/* ============================================================
   AEGENT — HARDWARE: the line in 3D
   Six chapters. Each pins the product's real 3D feature tour
   (tours/<id>/index.html?embed=1) for a scroll well: the scroll
   brings the product from a waiting pose to its overview, then
   the markers arm and the reader explores. The page names the
   product and steps aside; the tour owns the stage.
   ============================================================ */

/* ---------- opener ---------- */
.hw-hero{min-height:100svh;}

/* ---------- the line (index) ---------- */
.lineup{max-width:1240px;margin:0 auto;padding:clamp(64px,10vh,120px) 6vw 0;}
.lineup-head{display:grid;grid-template-columns:1.05fr .95fr;gap:24px 48px;align-items:end;}
.lineup h2{font-size:clamp(2rem,4.4vw,3.4rem);font-weight:700;letter-spacing:-.02em;line-height:1.04;max-width:14ch;text-wrap:balance;}
.lineup-head p{color:var(--muted);max-width:46ch;font-size:clamp(1rem,1.4vw,1.15rem);line-height:1.6;padding-bottom:.35em;}
.rail{list-style:none;margin:clamp(28px,4vh,44px) 0 0;padding:0;display:grid;grid-template-columns:repeat(8,1fr);gap:0 16px;}
.rail a{display:block;text-decoration:none;color:var(--ink);padding:14px 0 16px;border-top:1px solid var(--line);transition:border-color .3s cubic-bezier(.16,1,.3,1);}
.rail a:hover{border-top-color:var(--teal);}
.rail-name{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:15px;letter-spacing:.02em;transition:color .2s;}
.rail a:hover .rail-name{color:var(--teal);}
.rail-role{display:block;margin-top:4px;font-size:12.5px;color:var(--muted);}

/* ---------- interludes ---------- */
/* a thin band: one fling from a product's bench should land near the next product, not in copy */
.inter{max-width:1240px;margin:0 auto;padding:clamp(28px,5vh,56px) 6vw clamp(10px,2vh,20px);}
.inter h2{font-size:clamp(1.6rem,3.2vw,2.6rem);font-weight:700;letter-spacing:-.02em;line-height:1.05;max-width:22ch;text-wrap:balance;}
.inter p{margin-top:10px;color:var(--muted);max-width:58ch;font-size:1rem;line-height:1.55;}
.inter small{display:block;margin-top:14px;font-size:11.5px;letter-spacing:.32em;text-transform:uppercase;color:var(--teal);font-weight:600;}
.inter small::before{content:"";display:inline-block;width:22px;height:1px;background:var(--teal);margin-right:12px;vertical-align:3px;}

/* ---------- chapters ---------- */
.ch{
  position:relative;
  --in:30vh;      /* scroll that brings the product in (it moves from the first pixel, lands by p .35) */
  --hold:25vh;    /* scroll the stage stays pinned, armed */
  --in-share:.5455;   /* --in / (--in + --hold): hardware.js reads it */
  --shift:14vw;   /* where the product starts: right of the copy */
  --lift:0svh;
  --p:0;--k:0;
  height:calc(100svh + var(--in) + var(--hold));
}
.ch-stage{position:sticky;top:0;height:100svh;overflow:hidden;background:var(--bg);}
.ch-view{
  position:absolute;inset:0;
  /* translate only: the tour canvas is never raster-scaled (its edges would show; the product waits smaller through the tour's own camera) */
  transform:translate(calc(var(--shift) * (1 - var(--k))),calc(var(--lift) * (1 - var(--k))));will-change:transform;
}
.ch-frame{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:transparent;color-scheme:dark;visibility:hidden;}
.ch.is-alive .ch-frame{visibility:visible;}   /* only a frame whose tour has spoken is shown: a failed navigation (Chrome's white error page) stays behind the dark stage */
.ch-frame:not([src]){pointer-events:none;}

/* the copy: on as the chapter pins, gone (p .2 → .35) while the product slides to the centre (p 0 → .35) */
.ch-copy{
  position:absolute;left:6vw;top:50%;width:min(420px,32vw);
  transform:translateY(-50%) translateY(calc(var(--p) * -36px));
  opacity:clamp(0,(.35 - var(--p)) / .15,1);
  pointer-events:none;
}
.ch-copy>*{pointer-events:auto;}
.ch-name{font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:clamp(2.4rem,4.6vw,4.2rem);line-height:.96;letter-spacing:-.025em;}
.ch-sub{margin-top:12px;color:var(--muted);font-size:.9rem;letter-spacing:.14em;text-transform:uppercase;}
.ch-lead{margin-top:20px;color:#cfd9df;font-size:clamp(1rem,1.2vw,1.12rem);line-height:1.6;text-wrap:pretty;}
.ch-lead a{color:var(--teal);}
.ch-note{display:none;margin-top:10px;font-size:.78rem;line-height:1.45;color:var(--muted);}   /* phones only: the paragraph's must-keep line, shown where the paragraph is hidden */
.ch-note a{color:var(--teal);}
.ch-facts{list-style:none;margin:22px 0 0;padding:0;border-top:1px solid var(--line);}
.ch-facts li{padding:9px 0 8px;border-bottom:1px solid var(--line);font-size:.95rem;color:var(--ink);font-variant-numeric:tabular-nums;display:flex;justify-content:space-between;gap:16px;}
.ch-facts li span{color:var(--muted);flex:none;}

/* armed: a small name where the tour's own brand would sit; gone in a close-up (the panel names the part) */
.ch-tag{position:absolute;left:6vw;top:calc(96px + env(safe-area-inset-top,0px));margin:0;opacity:0;transform:translateY(6px);transition:opacity .5s cubic-bezier(.16,1,.3,1),transform .5s cubic-bezier(.16,1,.3,1);pointer-events:none;}
.ch.is-armed:not(.is-feature) .ch-tag{opacity:1;transform:none;}
.ch-tag b{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:22px;line-height:1;letter-spacing:-.01em;}
.ch-tag span{display:block;margin-top:7px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);}

/* the cue while the product comes in; the tour's own hint takes over once it lands */
.ch-cue{position:absolute;left:50%;bottom:calc(30px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);margin:0;display:flex;align-items:center;gap:12px;white-space:nowrap;
  font-size:10.5px;letter-spacing:.3em;text-transform:uppercase;color:rgba(238,243,245,.55);opacity:0;transition:opacity .4s;pointer-events:none;}
.ch.is-view:not(.is-armed) .ch-cue{opacity:1;}
.ch-cue i{display:block;width:1px;height:28px;background:currentColor;transform-origin:top;animation:cue 1.8s cubic-bezier(.45,0,.55,1) infinite;}
@keyframes cue{0%{transform:scaleY(0);opacity:0}30%{opacity:1}100%{transform:scaleY(1);opacity:0}}

/* load state: a hairline that fills while the model decodes (the tour reports it) */
.ch-load{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(280px,70vw);opacity:0;transition:opacity .25s;text-align:center;pointer-events:none;}
.ch.is-loading.is-view .ch-load{opacity:1;}
.mode-arrive .ch.is-loading.is-view .ch-load{opacity:0;}   /* arrival mode: the label only after a section has sat 400 ms unready (the dark stage reads as the intro's start) */
.mode-arrive .ch.is-loading.is-view.show-load .ch-load{opacity:1;}
.ch-load i{display:block;height:2px;border-radius:2px;background:rgba(238,243,245,.16);overflow:hidden;}
.ch-load b{display:block;height:100%;background:var(--teal);transform:scaleX(0);transform-origin:left center;transition:transform .25s cubic-bezier(.2,.7,.2,1);box-shadow:0 0 12px rgba(52,198,212,.6);}
.ch-load span{display:block;margin-top:14px;font-family:"IBM Plex Mono",monospace;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);}
.ch-load em{font-style:normal;color:var(--teal);font-variant-numeric:tabular-nums;}
@media (max-width:720px){.ch-load{top:62%;}}

/* ---------- a still chapter (IDIS fixed & PTZ: no 3D model, so a product photo) ----------
   Same footprint as a 3D chapter: one screen, the copy where a chapter's copy sits, the product where the tour's product
   lands, on the tour stage's own dark field. The photo is the booklet's (~711 px wide), so it is never shown wider. */
.ch-still{position:relative;height:100vh;height:100svh;}
.still-stage{position:relative;height:100%;overflow:hidden;
  background:radial-gradient(ellipse 46% 58% at 64% 50%,#0f171e 0%,#0b1218 46%,var(--bg) 100%);}
.still-copy{position:absolute;left:6vw;top:50%;width:min(420px,32vw);transform:translateY(-50%);}
.still-view{position:absolute;margin:0;top:0;bottom:0;left:calc(6vw + min(420px,32vw) + 5vw);right:5vw;
  display:flex;flex-direction:column;align-items:center;justify-content:center;}
.still-media{width:min(660px,100%);}
/* the booklet image is cropped at the PTZ's top: the top edge falls off into the stage */
.still-media img{display:block;width:100%;height:auto;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 14%);mask-image:linear-gradient(180deg,transparent 0,#000 14%);}
.still-view figcaption{margin-top:18px;font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--muted);text-align:center;}
.mode-arrive .ch-still{scroll-snap-align:start;}
.mode-arrive .ch-still .ch-next{opacity:1;pointer-events:auto;}   /* nothing to arm: the way on is there from the start */

/* ---------- the end ---------- */
.hw-cta{padding-top:clamp(110px,18vh,220px);}

/* ---------- narrow ---------- */
@media (max-width:1180px){
  .ch{--shift:16vw;}
  .ch-copy{width:min(380px,30vw);}
  .still-copy{width:min(380px,30vw);}
  .still-view{left:calc(6vw + min(380px,30vw) + 4vw);right:4vw;}
}
@media (max-width:1000px){
  .rail{grid-template-columns:repeat(4,1fr);}   /* eight stops: two rows of four before the names would wrap */
}
@media (max-width:880px){
  .lineup-head{grid-template-columns:1fr;align-items:start;}
  .rail{grid-template-columns:1fr 1fr;gap:0 16px;}
}
@media (max-width:720px){
  .ch{--in:25vh;--hold:20vh;--in-share:.5556;--shift:0vw;--lift:16svh;}
  .ch-copy{left:16px;right:16px;top:calc(74px + env(safe-area-inset-top,0px));width:auto;transform:translateY(calc(var(--p) * -24px));}
  .ch-name{font-size:2.2rem;}
  .ch-sub{margin-top:8px;font-size:.78rem;}
  .ch-lead{margin-top:12px;font-size:.98rem;line-height:1.5;}
  .ch-facts{margin-top:14px;}
  .ch-facts li{font-size:.88rem;padding:7px 0 6px;}
  .ch-facts li:nth-child(n+3){display:none;}
  .ch-tag{left:16px;top:calc(72px + env(safe-area-inset-top,0px));}
  .ch-tag b{font-size:19px;}
  /* the still stacks like a 3D chapter on a phone: copy at the top, the product in the band below it, the chevron under that */
  .still-stage{display:flex;flex-direction:column;padding:calc(74px + env(safe-area-inset-top,0px)) 16px calc(70px + env(safe-area-inset-bottom,0px));
    background:radial-gradient(ellipse 90% 34% at 50% 70%,#0f171e 0%,#0b1218 50%,var(--bg) 100%);}
  .still-copy{position:static;width:auto;transform:none;}
  .still-view{position:static;flex:1;min-height:0;}
  .still-media{width:100%;}
  .still-view figcaption{margin-top:14px;font-size:10.5px;}
  .ch-still .ch-facts li:nth-child(n+3){display:flex;}   /* no 3D view to make room for: all four facts stay */
}
@media (max-height:640px) and (max-width:720px){
  .ch-lead{display:none;}
  .ch .ch-note{display:block;}
}

/* reduced motion: the scroll still sets the pose (the reader drives it); only the loops stop */
@media (prefers-reduced-motion:reduce){
  .ch-cue i{animation:none;transform:none;opacity:.7;}
}

/* ---------- ARRIVAL MODE (?mode=arrive): full-viewport sections that snap; the product arrives on its own timing ---------- */
html.mode-arrive{scroll-snap-type:y proximity;}   /* wheel steps are programmatic (one notch = one section); the snap serves touch and the scrollbar */
html.mode-arrive.snap-mandatory{scroll-snap-type:y mandatory;}
.mode-arrive .hw-hero,.mode-arrive .lineup{scroll-snap-align:start;}
.mode-arrive .inter{display:none;}                          /* product to product, nothing between */
.mode-arrive .ch{height:100svh;scroll-snap-align:start;--p:0;--k:0;}
.mode-arrive .ch-view{transition:transform .6s cubic-bezier(.16,1,.3,1);}
.mode-arrive .ch.is-feature{--k:1;}   /* a close-up owns the whole stage: the shifted view would push the tour's panel off the right edge (Marc, 1 Oct: the front-camera close-up showed no text) */   /* the view keeps its resting place beside the copy; the tour's own intro brings the product in */
.mode-arrive .ch-stage{position:relative;}
.mode-arrive .ch-copy{opacity:1;transform:translateY(-50%);transition:opacity .25s;}  /* the title and the spec rows stay with the product */
.mode-arrive .ch.is-feature .ch-copy{opacity:0;}   /* a close-up's panel owns the side */
.ch.is-feature .ch-copy,.ch.is-feature .ch-copy>*{pointer-events:none;}   /* and the faded copy must not catch the clicks meant for that panel: its spec rows sat invisible above the tour's Next and Close (Marc, 1 Oct: 'why cant i scroll to the right? why doesnt the close button work') */
.mode-arrive .ch-cue{display:none;}
.mode-arrive .ch.is-armed:not(.is-feature) .ch-tag{opacity:0;}  /* the copy already names it */
@media (max-width:720px){
  .mode-arrive .ch-copy{transform:none;}
  /* a phone stacks copy over product: the view gets only the band under the copy and above the chevron, and the tour frames
     its product into that band (the P3000 family filled the whole height and ran under the spec rows: QA, 1 Oct). hardware.js
     measures the copy into --copy-h. A close-up takes the whole stage again (its panel needs the room; the copy is faded). */
  .mode-arrive .ch{--lift:0svh;}
  .mode-arrive .ch .ch-lead{display:none;}   /* 5 Oct (Marc: the products "look really small on the mobile view"): the name, the line and two facts stay; the paragraph's room goes to the product */
  .mode-arrive .ch .ch-note{display:block;}   /* what a hidden paragraph must still say: MOHOC's FCC line, Silvus's link to the mesh */
  .mode-arrive .ch-view{top:var(--copy-h,44svh);bottom:calc(64px + env(safe-area-inset-bottom,0px));transition:transform .6s cubic-bezier(.16,1,.3,1),top .6s cubic-bezier(.16,1,.3,1),bottom .6s cubic-bezier(.16,1,.3,1);}
  .mode-arrive .ch.is-feature .ch-view{top:0;bottom:0;}
}
/* the "next" chevron: a visible way off a revealed product for any mouse (keys and a wheel notch step too) */
.ch-next{display:none;}
.mode-arrive .ch-next{position:absolute;left:50%;bottom:calc(22px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:10px 14px;border:0;background:transparent;color:rgba(238,243,245,.6);font:600 10.5px/1 "IBM Plex Mono",monospace;letter-spacing:.3em;text-transform:uppercase;cursor:pointer;opacity:0;pointer-events:none;transition:opacity .4s,color .2s;z-index:3;}   /* invisible = not clickable */
.mode-arrive .ch.is-armed:not(.is-feature) .ch-next{opacity:1;pointer-events:auto;}
.mode-arrive .ch-next:hover,.mode-arrive .ch-next:focus-visible{color:var(--ink);outline:none;}
.mode-arrive .ch-next i{display:block;width:10px;height:10px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);animation:cue-chev 1.8s cubic-bezier(.45,0,.55,1) infinite;}
.mode-arrive .ch:last-of-type .ch-next{display:none;}
@keyframes cue-chev{0%,100%{transform:translateY(0) rotate(45deg);}50%{transform:translateY(5px) rotate(45deg);}}

/* The photo band is gone from this page (4 Oct, Marc; see hardware.html), and with it S12's band rules (no snap, the taller
   .pb-tall band). The closing call is the stop after the last product (hardware.js closeStop()). */

/* S13 (4 Oct, follow-up to S12; HQ measured Marc's usual 3440x1352 window): when the window is taller than the closing call
   plus the footer, the page end could not scroll the photo band out of view, so the last screen still showed a strip of
   the photo above the heading. The closing section is now at least one screen tall under the nav (62 px once scrolled).
   The spare height is split above the heading and above the footer (two flexible gaps), so the page end shows the closing
   call and the footer, and none of the band. Where the section is already taller (most laptops) both gaps are zero and
   nothing moves. With the band gone, the same layout keeps the end of the last product out of the last screen. */
@media (min-width:881px){
  .mode-arrive .hw-cta{display:flex;flex-direction:column;min-height:calc(100vh - 62px);}
  .mode-arrive .hw-cta::before{content:"";flex:1 0 0;}
  .mode-arrive .hw-cta .cta-gap{flex:1 0 0;}
  .mode-arrive .hw-cta .site-foot{width:100%;}
}
