/* Home page — hero, slider, focus stack, Orbit, offer, platform */

/* ---------- Hero ---------- */
.hero{position:relative;min-height:100svh;display:grid;grid-template-rows:1fr auto;align-items:center;padding-top:calc(var(--nav-h) + 24px);padding-bottom:clamp(28px,4vw,52px);overflow:clip}
.hero__bg{position:absolute;inset:0;z-index:0;pointer-events:none}
.hero__bg .wash{position:absolute;inset:0;background:radial-gradient(60% 55% at 78% 40%,rgba(80,189,255,.28),transparent 70%),radial-gradient(40% 40% at 10% 90%,rgba(198,200,209,.35),transparent 70%),linear-gradient(180deg,#F9FBFE 0%,var(--paper) 100%)}
.hero__bg .grid-bg{opacity:.5}
.hero__grid{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:clamp(24px,4vw,56px);align-items:center}
.hero__copy h1{font-size:var(--fs-hero);line-height:.98;margin-bottom:1.2rem;max-width:12ch}
.hero__copy h1 .h1-sub{display:block;font-size:.34em;font-weight:600;letter-spacing:-.01em;color:var(--ink-2);margin-top:.9rem;max-width:36ch;font-variation-settings:"wdth" 100,"wght" 600;line-height:1.25}
.hero__slidecopy{position:relative;min-height:150px}
.hero__slide-text{position:absolute;inset:0;opacity:0;transform:translateY(14px);transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);pointer-events:none}
.hero__slide-text.is-active{opacity:1;transform:none;pointer-events:auto;position:relative}
.hero__slide-text .lead{margin:0 0 1.4rem;max-width:46ch}
.hero__slide-text .actions{display:flex;flex-wrap:wrap;gap:.8rem;align-items:center}
/* Slider controls: a standalone bar under the hero, separated by a rule so it reads
   as a control strip rather than another element of the hero composition. */
.hero__controls{position:relative;z-index:2;margin-top:clamp(24px,3.4vw,44px);border-top:1px solid var(--rule)}
.hero__tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(10px,1.4vw,18px);margin:0;padding-top:clamp(14px,1.8vw,20px)}
.hero__tab{--p:0;position:relative;overflow:hidden;display:flex;align-items:center;gap:.55rem;text-align:left;border:1px solid var(--silver-2);background:rgba(255,255,255,.72);border-radius:14px;padding:.85rem 1.05rem .95rem;font-family:var(--font-display);font-weight:700;font-size:clamp(.82rem,1.05vw,.95rem);letter-spacing:-.01em;color:var(--ink-2);cursor:pointer;transition:color .3s,border-color .3s,background .3s,box-shadow .3s,transform .3s var(--ease-out)}
.hero__tab:hover{transform:translateY(-2px);background:#fff;color:var(--ink)}
.hero__tab::after{content:"";position:absolute;left:0;bottom:0;height:3px;width:100%;background:var(--sky);transform:scaleX(var(--p));transform-origin:left;transition:none}
.hero__tab[aria-selected="true"]{color:var(--ink);border-color:var(--sky);background:#fff;box-shadow:0 12px 28px -20px rgba(20,33,58,.55)}
.hero__tab-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hero__tab .dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--silver);transition:background .3s,box-shadow .3s}
.hero__tab[aria-selected="true"] .dot{background:var(--sky-deep);box-shadow:0 0 0 4px rgba(80,189,255,.25)}
.hero__proof{display:flex;gap:1.6rem;flex-wrap:wrap;margin-top:2rem;color:var(--muted);font-family:var(--font-display);font-size:.9rem}
.hero__proof b{color:var(--ink);font-weight:800}
/* Stage */
.hero__stage{position:relative;aspect-ratio:1/1;max-height:78vh;width:100%;margin-inline:auto}
/* The rings used to bleed 10% past the stage on all four sides. Above sits the copy once
   the layout stacks, below sits the tab row at every width, and to the left sits the copy
   column on desktop, so every direction ran into something. The canvas is now exactly the
   stage: three.js renders to whatever size it is given, so the rings simply draw smaller
   rather than being cut off. */
.hero__3d{position:absolute;inset:0;z-index:0;pointer-events:none}
.hero__3d canvas{width:100%!important;height:100%!important;display:block}
.hero__slide{position:absolute;inset:0;display:grid;place-items:center;opacity:0;transform:scale(.92) translateY(10px);transition:opacity .8s var(--ease-out),transform .9s var(--ease-out);pointer-events:none;z-index:1}
.hero__slide.is-active{opacity:1;transform:none;pointer-events:auto}
/* Slide A: laptop + floating chips */
/* Fill the stage and cap the laptop to it. Sized by width alone the laptop kept its
   width driven height while the stage shrank on short screens, so it hung past the
   bottom of its own box and took the Automations chip with it, over the tab row. */
.slide-launch{width:100%;height:100%;min-height:0;position:relative;perspective:1400px;display:grid;place-items:center}
.slide-launch .laptop{position:relative;z-index:1;width:min(100%,560px);max-height:100%;min-height:0;object-fit:contain;margin-inline:auto;border-radius:18px;box-shadow:0 40px 80px -30px rgba(20,33,58,.45),0 0 0 1px rgba(255,255,255,.7);transform:rotateX(var(--rx,0)) rotateY(var(--ry,0));transition:transform .5s var(--ease-out);will-change:transform;background:#fff}
.slide-launch .fchip{position:absolute;z-index:3;text-decoration:none;color:var(--ink);cursor:pointer;background:#fff;border:1px solid var(--silver-2);box-shadow:0 20px 40px -16px rgba(20,33,58,.5),0 2px 6px -2px rgba(20,33,58,.28);border-radius:15px;padding:.65rem 1rem;font-family:var(--font-display);font-weight:700;font-size:.98rem;letter-spacing:-.012em;color:var(--ink);display:flex;align-items:center;gap:.55rem;white-space:nowrap;animation:float 6s ease-in-out infinite;scale:1;transition:scale .3s var(--ease-out),box-shadow .3s var(--ease-out),border-color .3s var(--ease-out);will-change:transform,scale}
/* The float animation owns transform, so the hover growth uses the independent
   scale property, which composes with it instead of being overridden. */
@media (hover:hover) and (pointer:fine){
  .slide-launch .fchip:hover{scale:1.15;z-index:5;border-color:var(--sky);box-shadow:0 0 0 3px var(--sky-soft),0 26px 48px -14px rgba(22,145,222,.6);animation-play-state:paused}
  .slide-launch .fchip:hover i{background:var(--sky-deep);box-shadow:0 0 0 5px rgba(80,189,255,.35)}
}
@media (prefers-reduced-motion:reduce){.slide-launch .fchip{transition-duration:.01ms}}
.slide-launch .fchip i{width:11px;height:11px;flex:none;border-radius:50%;background:var(--sky);box-shadow:0 0 0 4px var(--sky-tint)}
.slide-launch .fchip:nth-child(2){left:-6%;top:13%;animation-delay:-1s}
.slide-launch .fchip:nth-child(3){right:-7%;top:4%;animation-delay:-2.5s}
.slide-launch .fchip:nth-child(4){left:-5%;bottom:15%;animation-delay:-4s}
.slide-launch .fchip:nth-child(5){right:-6%;bottom:25%;animation-delay:-3s}
.slide-launch .fchip:nth-child(6){left:32%;bottom:0;animation-delay:-5s}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
/* Slide B: Orbit */
/* Same cap as the laptop: a square sized by width alone outgrows a short stage.
   max-height lets aspect-ratio shrink the width to suit. */
.slide-orbit{position:relative;width:min(88%,520px);max-height:100%;min-height:0;aspect-ratio:1;display:grid;place-items:center}
.slide-orbit img{width:78%;height:auto;max-height:100%;min-height:0;object-fit:contain;filter:drop-shadow(0 40px 50px rgba(20,33,58,.35));animation:hover 5.5s ease-in-out infinite;will-change:transform}
.slide-orbit .glow{position:absolute;left:50%;bottom:6%;width:46%;height:10%;transform:translateX(-50%);border-radius:50%;background:radial-gradient(ellipse,rgba(80,189,255,.75),rgba(80,189,255,0) 70%);filter:blur(8px);animation:glowpulse 5.5s ease-in-out infinite}
.slide-orbit .bubble{position:absolute;background:#fff;border:1px solid var(--silver-2);border-radius:18px;padding:.6rem .9rem;font-family:var(--font-display);font-weight:600;font-size:.86rem;color:var(--ink);box-shadow:0 18px 40px -20px rgba(20,33,58,.45);max-width:220px;line-height:1.3;opacity:0;transform:translateY(8px);animation:bubble 9s var(--ease-out) infinite}
.slide-orbit .bubble--you{left:-6%;top:6%;border-bottom-left-radius:4px;background:var(--ink);color:#fff;border-color:var(--ink);animation-delay:.6s}
.slide-orbit .bubble--orbit{right:-8%;top:24%;border-bottom-right-radius:4px;animation-delay:2.6s}
.slide-orbit .bubble--done{right:2%;bottom:10%;border-bottom-right-radius:4px;background:var(--sky-tint);border-color:var(--sky-soft);animation-delay:5s}
/* The Orbit page opens on this art, and a conversation that starts from an empty frame
   reads as nothing happening. Negative delays start each bubble partway through its own
   9s cycle, so the question and the reply are already up when the page paints and the
   confirmation lands a beat later. The home page keeps the build from empty, because
   there the slide arrives with the slider and the viewer watches it come in. */
.art.slide-orbit .bubble--you{animation-delay:-3.8s}
.art.slide-orbit .bubble--orbit{animation-delay:-1.8s}
.art.slide-orbit .bubble--done{animation-delay:.6s}
.slide-orbit .bubble b{color:var(--sky-deep)}
.slide-orbit .bubble--you b{color:var(--sky)}
@keyframes hover{0%,100%{transform:translateY(0) rotate(-2deg)}50%{transform:translateY(-16px) rotate(2deg)}}
@keyframes glowpulse{0%,100%{opacity:.8;transform:translateX(-50%) scaleX(1)}50%{opacity:.45;transform:translateX(-50%) scaleX(.8)}}
@keyframes bubble{0%,8%{opacity:0;transform:translateY(8px)}14%,78%{opacity:1;transform:none}86%,100%{opacity:0;transform:translateY(-6px)}}
/* The middle word of the headline tracks the slider. During a swap both words are in the
   box, the outgoing one pulled out of flow so the incoming one sets the height, and the
   box's own width is animated between them so the rest of the line does not jump. */
.swapword{position:relative;display:inline-block;color:var(--sky-deep);transition:width .45s var(--ease-out);will-change:width}
.swapword i{font-style:normal;white-space:nowrap;display:block}
.swapword i.is-out{position:absolute;left:0;top:0;animation:swapout .38s var(--ease-out) forwards}
.swapword i.is-in{animation:swapin .46s .04s var(--ease-out) both}
@keyframes swapout{to{transform:translateY(-.45em);opacity:0}}
@keyframes swapin{0%{transform:translateY(.5em);opacity:0}60%{opacity:1}100%{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){
  .swapword{transition:none}
  .swapword i.is-in{animation:none}
  .swapword i.is-out{display:none}
}

/* Slide C: beams from AI engines to your business */
.slide-leads{width:min(100%,560px);position:relative;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:clamp(24px,6vw,72px);padding:1rem 0}
.slide-leads .col{display:grid;gap:clamp(34px,4.4vw,46px);justify-items:center}
.slide-leads .col--r{justify-items:center}
.slide-leads .beam-node{width:58px;height:58px}
.slide-leads .beam-node span{font-family:var(--font-display);font-weight:800;font-size:.7rem;letter-spacing:-.02em;color:var(--ink)}
.slide-leads .beam-node .n-name{position:absolute;top:calc(100% + 7px);left:50%;transform:translateX(-50%);font-family:var(--font-display);font-weight:600;font-size:.76rem;letter-spacing:-.006em;line-height:1;color:var(--ink-2);white-space:nowrap;pointer-events:none;transition:color .35s var(--ease-out)}
.slide-leads .beam-node.is-hot .n-name{color:var(--sky-ink)}
.slide-leads .beam-node.biz{width:150px;height:150px;flex-direction:column;gap:.2rem;text-align:center}
.slide-leads .biz svg{width:40%;height:auto}
.slide-leads .biz span{font-family:var(--font-display);font-weight:800;font-size:.8rem;color:var(--ink);line-height:1.1}
.slide-leads .lead-tag{position:absolute;left:50%;transform:translateX(-50%);bottom:-30px;background:var(--ink);color:#fff;border-radius:var(--r-pill);padding:.55rem 1.15rem;font-family:var(--font-display);font-weight:700;font-size:.98rem;letter-spacing:-.012em;white-space:nowrap;box-shadow:0 16px 32px -14px rgba(20,33,58,.75)}
.slide-leads .lead-note{position:absolute;left:0;right:0;margin-inline:auto;width:max-content;bottom:-72px;background:#fff;border:1px solid var(--silver-2);color:var(--ink-2);border-radius:var(--r-pill);padding:.42rem 1rem;font-family:var(--font-display);font-weight:600;font-size:.86rem;letter-spacing:-.008em;white-space:normal;max-width:100%;line-height:1.3;text-align:center;box-shadow:0 8px 18px -10px rgba(20,33,58,.32)}
/* The lead generation hero clips its overflow and the diagram sits at its bottom
   edge, so pills hanging below the diagram get cut off at any width. Reserve the
   room inside the diagram and sit both pills in it. */
#lead-beams{padding-bottom:132px}
#lead-beams .lead-tag{bottom:60px}
#lead-beams .lead-note{bottom:14px}
.slide-leads .lead-tag b{color:var(--sky)}

/* ---------- Clients ---------- */

/* ---------- Case study ---------- */
.case{background:linear-gradient(180deg,var(--paper),var(--sky-tint) 60%,var(--paper))}
.page-home .case{padding-top:clamp(18px,2.4vw,30px)}
.case__grid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:clamp(32px,5vw,80px);align-items:start}
.case__cta{display:flex;flex-wrap:wrap;align-items:center;gap:.9rem 1.5rem}
.case__stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(20px,3vw,40px) clamp(20px,3vw,48px)}
.case__stats .stat{padding:1.4rem 0 0;border-top:2px solid var(--silver-2)}
.case__stats .stat:first-child{grid-column:1/-1;border-top-color:var(--sky)}
.case__stats .stat:first-child .stat__num{font-size:clamp(3.4rem,7vw,6.2rem);color:var(--sky-ink)}
.case__note{font-size:.95rem;color:var(--muted);margin-top:1rem}
.case h2{max-width:14ch}
.case__pill{display:inline-flex;align-items:center;gap:.5rem;background:#fff;border:1px solid var(--sky-soft);border-radius:var(--r-pill);padding:.4rem .9rem;font-family:var(--font-display);font-weight:700;font-size:.85rem;color:var(--sky-ink);margin-bottom:1.2rem}
.case__pill i{width:8px;height:8px;border-radius:50%;background:var(--sky-deep);box-shadow:0 0 0 4px rgba(80,189,255,.3);animation:blink 2s ease-in-out infinite}
@keyframes blink{50%{opacity:.4}}

/* ---------- Focus stack ---------- */
.focus{padding-top:clamp(20px,2.6vw,34px);padding-bottom:0}
.focus .section-head{margin-bottom:clamp(24px,4vw,48px)}
.stack{position:relative;display:grid;gap:clamp(24px,3vw,40px);padding-bottom:clamp(32px,4vw,56px)}
/* While cards are pinned the gap is pure scroll distance, not visible space: it is the
   pause that lets a card be read before the next one slides over it. Applied by JS only
   when the stack is actually pinning, so unpinned layouts keep the normal tight gap. */
.stack.is-stacking{gap:clamp(570px,99vh,988px)}
/* On a phone the cards themselves are taller than the screen, so they need far less
   added gap to give the next one room to travel over the one before. */
.stack.is-stacking--tall{gap:clamp(228px,38vh,418px)}
.stack-card{position:relative;background:#fff;border:1px solid var(--rule);border-radius:calc(var(--r-card) + 8px);box-shadow:var(--shadow-card);display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(24px,4vw,64px);align-items:center;padding:clamp(28px,4vw,64px);min-height:min(70vh,640px);transform-origin:center top;will-change:transform,opacity;overflow:clip}
.stack-card--sky{background:linear-gradient(150deg,#FFFFFF,var(--sky-tint))}
.stack-card--silver{background:linear-gradient(150deg,#FFFFFF,var(--silver-3))}
.stack-card--ink{background:var(--ink);border-color:var(--ink);color:#DCE6F3}
.stack-card--ink h3,.stack-card--ink h2{color:#fff}
.stack-card--ink .muted{color:#AEBBD0}
.stack-card .idx{font-family:var(--font-display);font-weight:800;font-size:clamp(3rem,7vw,6rem);letter-spacing:-.05em;line-height:.8;color:var(--sky);font-variation-settings:"wdth" 130;margin-bottom:1rem;opacity:.9}
.stack-card--ink .idx{color:var(--sky)}
.stack-card h3{font-size:clamp(1.7rem,2.8vw,2.4rem);margin-bottom:.7rem;max-width:16ch}
.stack-card p{max-width:52ch;font-size:1.1rem}
.stack-card .visual{position:relative;min-height:320px;display:grid;place-items:center}
/* Focus 1: icon cloud */
.focus-cloud .cloud{width:min(100%,440px)}
/* Focus 2: journey */
.journey{width:100%;max-width:520px;position:relative}
.journey svg{width:100%;height:auto;overflow:visible}
.journey .node{fill:#fff;stroke:var(--silver);stroke-width:2}
.journey .node.lit{stroke:var(--sky-deep);filter:drop-shadow(0 6px 14px rgba(80,189,255,.55))}
.journey text{font-family:var(--font-display);font-weight:700;font-size:12px;fill:var(--ink)}
.journey .path{fill:none;stroke:var(--silver-2);stroke-width:3;stroke-linecap:round}
.journey .path-lit{fill:none;stroke:var(--sky-deep);stroke-width:3;stroke-linecap:round;stroke-dasharray:1200;stroke-dashoffset:1200;animation:dash 7s linear infinite}
@keyframes dash{0%{stroke-dashoffset:1200}70%{stroke-dashoffset:0}100%{stroke-dashoffset:0}}
/* Sits above the diagram in normal flow. Absolutely positioned it landed on the
   Referral node, and any corner collides at some width as the SVG scales. */
.journey .tag{display:inline-block;margin-bottom:.7rem;background:var(--ink);color:#fff;border-radius:var(--r-pill);padding:.4rem .8rem;font-family:var(--font-display);font-weight:700;font-size:.8rem}
/* Focus 3: enrichment */
.enrich{width:100%;max-width:520px;display:grid;grid-template-columns:minmax(0,1fr) 34px minmax(0,1.4fr);gap:.6rem;align-items:center}
.enrich .in,.enrich .out{background:#fff;border:1px solid var(--rule);border-radius:16px;padding:1rem;font-family:var(--font-display);box-shadow:var(--shadow-card);color:var(--ink)}
.stack-card--ink .enrich .in,.stack-card--ink .enrich .out{background:#1E2D4A;border-color:#33456A;color:#EAF1FA;box-shadow:none}
.enrich .in{font-size:.9rem;line-height:1.5}
/* The address is one unbreakable string and the column is 162px of content, so it ran
   past the edge of its own box. Cut it the way the enriched rows opposite are cut. */
.enrich .in span{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.enrich .in small{display:block;font-family:var(--font-mono);font-size:.62rem;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin-bottom:.5rem}
.stack-card--ink .enrich .in small,.stack-card--ink .enrich .out small{color:#8FA3C2}
.enrich .arrow-anim{width:34px;height:2px;background:var(--silver);position:relative;overflow:visible}
.enrich .arrow-anim::after{content:"";position:absolute;left:-10px;top:-3px;width:8px;height:8px;border-radius:50%;background:var(--sky);box-shadow:0 0 12px var(--sky);animation:travel 2.4s var(--ease-in-out) infinite}
@keyframes travel{0%{left:-10px;opacity:0}20%{opacity:1}80%{opacity:1}100%{left:36px;opacity:0}}
.enrich .out{font-size:.86rem;display:grid;gap:.35rem}
.enrich .out small{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);margin-bottom:.2rem}
.enrich .out .row{display:grid;grid-template-columns:78px minmax(0,1fr);gap:.4rem;border-bottom:1px solid rgba(255,255,255,.12);padding-bottom:.3rem}
.enrich .out .row span:first-child{color:#8FA3C2}
.enrich .out .row span:last-child{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.enrich .out .row.typing span:last-child{border-right:2px solid var(--sky)}

/* Orbit integrations beams */
.integ{padding-top:clamp(26px,3.4vw,44px)}
.integ__stage{position:relative;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:clamp(28px,7vw,120px);max-width:980px;margin-inline:auto;padding:1rem 0}
.integ__col{display:grid;gap:clamp(12px,2vw,22px);justify-items:center}
.integ__col--l{justify-items:end}
.integ__col--r{justify-items:start}
.integ .beam-node{width:64px;height:64px}
.integ .beam-node span{font-family:var(--font-display);font-weight:800;font-size:.66rem;letter-spacing:-.02em;color:var(--ink);text-align:center;line-height:1.05}
.integ .beam-node--hub{width:170px;height:170px;border-radius:50%}
.integ .beam-node--hub img{width:80%;height:80%}
/* A mark far taller than it is wide only fills its box vertically, so give it a
   larger box to reach the visual weight of the square logos around it. */
.integ .beam-node--tall img{width:76%;height:76%}
/* Hovering any node, or the hub itself, lifts it and drives a surge along its beams.
   Shared by the Orbit integrations and the step two channels so the two diagrams
   cannot drift apart. The hub is already large, so it takes a gentler lift. */
.integ .beam-node,.channels .beam-node{cursor:pointer;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out),border-color .3s var(--ease-out)}
.integ .beam-node::after,.channels .beam-node::after{content:"";position:absolute;inset:-8px;border-radius:50%;border:3px solid var(--sky);opacity:0;pointer-events:none}
.integ .beam-node.is-hot,.channels .beam-node.is-hot{transform:scale(1.22);border-color:var(--sky);z-index:3;box-shadow:0 0 0 3px var(--sky-soft),0 18px 34px -12px rgba(22,145,222,.7)}
.integ .beam-node--hub.is-hot,.channels .beam-node--hub.is-hot{transform:scale(1.08);box-shadow:0 0 0 5px var(--sky-soft),0 22px 44px -14px rgba(22,145,222,.6)}
.integ .beam-node.is-receiving,.channels .beam-node.is-receiving{box-shadow:0 0 0 5px rgba(80,189,255,.26),var(--shadow-sky)}
.integ .beam-node.is-receiving::after,.channels .beam-node.is-receiving::after{animation:hubpulse 3s var(--ease-out) infinite}
@media (prefers-reduced-motion:reduce){.integ .beam-node.is-receiving::after,.channels .beam-node.is-receiving::after{animation:none}}
.integ__labels{display:flex;justify-content:center;gap:.5rem;flex-wrap:wrap;margin-top:1.5rem}

/* ---------- Offer ---------- */
.offer{position:relative;padding-bottom:clamp(18px,2.4vw,30px)}
.offer__head{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:clamp(24px,4vw,64px);align-items:end;margin-bottom:clamp(40px,5vw,72px)}
.offer__guarantee{background:var(--ink);color:#EAF1FA;border-radius:var(--r-card);padding:clamp(22px,3vw,34px);position:relative;overflow:clip}
.offer__guarantee::before{content:"";position:absolute;width:260px;height:260px;right:-90px;top:-120px;border-radius:50%;background:radial-gradient(circle,rgba(80,189,255,.45),transparent 65%)}
.offer__guarantee h3{color:#fff;font-size:1.45rem;margin-bottom:.5rem}
.offer__guarantee p{color:#C5D2E4;margin-bottom:.8rem;font-size:1.05rem}
.offer__guarantee .price{color:#fff}
.offer__guarantee .price .amt{font-size:clamp(2.4rem,4vw,3.2rem)}
.offer__guarantee .price .per{color:#AEBBD0}
.offer__guarantee small{display:block;color:#AEBBD0;font-size:.9rem;margin-top:.8rem}
.offer__steps{display:grid;gap:clamp(24px,3vw,40px)}
.ostep{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(24px,4vw,64px);align-items:center;background:#fff;border:1px solid var(--rule);border-radius:calc(var(--r-card) + 8px);padding:clamp(22px,3vw,44px);box-shadow:var(--shadow-card)}
.ostep:nth-child(even){grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
.ostep:nth-child(even) .ostep__visual{order:-1}
.ostep__num{font-family:var(--font-mono);font-size:.75rem;letter-spacing:.2em;text-transform:uppercase;color:var(--sky-ink);margin-bottom:.8rem;display:flex;align-items:center;gap:.6rem}
.ostep__num::before{content:"";width:28px;height:2px;background:var(--sky)}
.ostep h3{font-size:clamp(1.5rem,2.4vw,2rem)}
.ostep p{max-width:50ch;color:var(--ink-2)}
.ostep__visual{position:relative;min-height:260px;display:grid;place-items:center;border-radius:var(--r-card);background:var(--paper-2);overflow:clip}
.ostep__visual img{width:100%;height:100%;object-fit:cover}
.jumble{position:relative;width:100%;height:auto;min-height:0;align-self:center}
.jumble img{height:auto;object-fit:contain;border-radius:var(--r-card)}
/* Step 2: channels */
.channels{position:relative;width:100%;max-width:420px;aspect-ratio:1;display:grid;place-items:center}
.channels .beam-node{position:absolute;width:62px;height:62px;flex-direction:column;gap:.15rem}
.channels .beam-node span{font-family:var(--font-display);font-weight:700;font-size:.62rem;color:var(--ink);text-align:center;line-height:1.05}
.channels .beam-node--hub{position:relative;width:128px;height:128px;flex-direction:column}
.channels .beam-node--hub span{font-size:.78rem}
.channels .beam-node--hub img{width:52%;height:52%}
.channels .c1{left:8%;top:6%}.channels .c2{right:8%;top:6%}.channels .c3{left:-2%;top:44%}.channels .c4{right:-2%;top:44%}.channels .c5{left:12%;bottom:4%}.channels .c6{right:12%;bottom:4%}
/* Step 3: cycle */
.cycle{position:relative;width:min(100%,380px);aspect-ratio:1;display:grid;place-items:center;padding:34px}
.cycle svg{width:100%;height:100%;overflow:visible}
.cycle .ring{fill:none;stroke:var(--silver-2);stroke-width:2}
.cycle .ring-dash{fill:none;stroke:var(--sky-deep);stroke-width:3;stroke-dasharray:14 18;stroke-linecap:round;transform-origin:center;animation:spin 18s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.cycle .cnode{position:absolute;background:#fff;border:1px solid var(--sky-soft);border-radius:var(--r-pill);padding:.6rem 1.05rem;font-family:var(--font-display);font-weight:800;font-size:.92rem;color:var(--ink);white-space:nowrap;transform:translateY(-50%);box-shadow:0 10px 26px -12px rgba(22,145,222,.5),var(--shadow-card);animation:cpulse 3s ease-in-out infinite}
/* Each stage sits on the ring rather than beside it. The svg fills the 34px padded
   box, so the ring is centred on .cycle with radius 0.38 * (100% - 68px), and a
   45 degree point is that over root two: 0.38 / 1.41421 = 0.2687. Clockwise from
   the top left, one stage per vertical. */
.cycle .cnode:nth-child(2){left:0;top:calc(50% - 0.2687 * (100% - 68px))}
.cycle .cnode:nth-child(3){right:0;top:50%;animation-delay:1s}
.cycle .cnode:nth-child(4){left:0;top:calc(50% + 0.2687 * (100% - 68px));animation-delay:2s}
.cycle .cnode b{color:var(--sky-deep)}
@keyframes cpulse{0%,60%,100%{box-shadow:0 10px 26px -12px rgba(22,145,222,.5),var(--shadow-card)}15%{box-shadow:0 0 0 7px rgba(80,189,255,.45),0 10px 26px -12px rgba(22,145,222,.5),var(--shadow-card)}}
@media (hover:hover) and (pointer:fine){
  .cycle .cnode{transition:transform .28s var(--ease-out),box-shadow .28s var(--ease-out),border-color .28s var(--ease-out);will-change:transform}
  /* The pulse animates box-shadow, so it has to stop rather than pause or it keeps
     overriding the hover glow. All three stages are centred on the ring with a
     transform, so the growth goes inside that same transform: the scale property
     resolves first and would leave the percentage translate on the unscaled box. */
  .cycle .cnode:hover{transform:translateY(-50%) scale(1.14);z-index:3;animation:none;border-color:var(--sky);box-shadow:0 0 0 5px var(--sky-soft),0 22px 44px -14px rgba(22,145,222,.65)}
  .cycle .cnode:hover b{color:var(--sky-ink,var(--sky-deep))}
}
/* On a phone the cycle shrinks with the column and the ring is only 63 to 104px in
   radius, so the 45 degree points crowd together. Both left stages are wider than the
   distance from the cycle's edge to its centre, so the ring stays behind them right out
   to the radius: push them to 0.94 of it, 0.94 * 0.38 = 0.357, which keeps a visible
   crossing rather than a tangent and gains about a third more separation. Bounded at the
   widest common phone, above which the cycle nears its 380px cap and the crossing on the
   narrower top stage would slide out to its edge. The bound is 440 rather than 430
   because a fractional viewport under a non integer device pixel ratio can measure just
   over the round number and miss the rule. */
@media (max-width:440px){
  .cycle .cnode:nth-child(2){top:calc(50% - 0.357 * (100% - 68px))}
  .cycle .cnode:nth-child(4){top:calc(50% + 0.357 * (100% - 68px))}
}
.offer__close{margin-top:clamp(36px,5vw,64px);display:flex;flex-wrap:wrap;gap:1.2rem;align-items:center;justify-content:space-between;padding:clamp(22px,3vw,34px);border-radius:var(--r-card);background:linear-gradient(120deg,var(--sky-tint),#fff);border:1px solid var(--sky-soft)}
.offer__close h3{margin:0;font-size:clamp(1.3rem,2.2vw,1.8rem)}

/* ---------- Platform teaser ---------- */
.platform{background:linear-gradient(180deg,var(--paper),var(--paper-2))}
.platform__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(28px,5vw,80px);align-items:center}
.platform__img{position:relative}
.platform__img img{border-radius:var(--r-card);box-shadow:var(--shadow-sky);border:1px solid #fff}
/* A transparent lockup, not a screenshot: the card frame would draw a rounded box
   around empty space, so drop it and hold the mark to a sensible size. */
.platform__img--mark{width:min(100%,400px);margin-inline:auto}
.platform__img--mark img{border:0;border-radius:0;box-shadow:none;width:100%;display:block}
.platform__img .badge{position:absolute;left:-14px;top:22px;background:var(--ink);color:#fff;border-radius:var(--r-pill);padding:.5rem 1rem;font-family:var(--font-display);font-weight:800;font-size:.9rem;box-shadow:0 14px 30px -14px rgba(20,33,58,.8)}
.platform__img .badge b{color:var(--sky)}
.platform .chips{margin:1.4rem 0 1.8rem}
.platform .price-row{display:flex;gap:1.4rem;align-items:baseline;flex-wrap:wrap;margin-bottom:1.4rem}
.platform .price-row .or{color:var(--muted);font-family:var(--font-display)}

/* ---------- Insights ---------- */
.insights{padding-top:clamp(20px,2.6vw,34px);padding-bottom:clamp(20px,2.6vw,34px)}
.insights__grid{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,4vw,56px);align-items:start}
.insights__posts{display:grid;gap:1.6rem}
.insights__posts .post-card{grid-template-columns:200px minmax(0,1fr);align-items:center}
.insights__posts .post-card:first-child{grid-template-columns:minmax(0,1fr)}
.podcast-card{background:var(--ink);color:#EAF1FA;border-radius:calc(var(--r-card) + 4px);padding:clamp(20px,2.5vw,30px);position:relative;overflow:clip}
.podcast-card h3{color:#fff}
.podcast-card p{color:#C5D2E4}
.podcast-card .video-frame{margin:1rem 0 1.2rem;box-shadow:none}
.podcast-card .k{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--sky)}

/* ---------- Responsive ---------- */
/* Short desktop windows: tighten the hero so the slider controls stay above the fold.
   A control the visitor cannot see is a control they will not use. */
@media (min-width:981px) and (max-height:820px){
  .hero{padding-top:calc(var(--nav-h) + 10px);padding-bottom:18px}
  .hero__copy h1{font-size:clamp(2.4rem,4.4vw,3.6rem)}
  .hero__slidecopy{min-height:132px}
  .hero__controls{margin-top:clamp(16px,2vw,26px)}
  .hero__stage{max-height:min(64vh,470px)}
}
@media (max-width:1100px){
  .hero__copy h1{max-width:14ch}
}
@media (max-width:980px){
  /* The rings sit at inset:-10%, bleeding past the stage on every side. Beside the copy
     that is fine, but once the hero stacks the stage sits under the text and the top
     bleed climbed into it: 42px above the stage at 375, which is 18px into the copy.
     Keep the top edge on the stage here; the sides and bottom still bleed. */

  .hero{min-height:0;padding-top:calc(var(--nav-h) + 40px)}
  .hero__grid{grid-template-columns:minmax(0,1fr)}
  .hero__stage{max-height:none;aspect-ratio:1/1;max-width:560px}
  .hero__copy h1{max-width:none}
  .case__grid,.offer__head,.platform__grid,.insights__grid{grid-template-columns:minmax(0,1fr)}
  .stack-card,.ostep,.ostep:nth-child(even){grid-template-columns:minmax(0,1fr)}
  .ostep:nth-child(even) .ostep__visual{order:0}
  .stack-card{min-height:0}
  .stack-card .visual{min-height:280px}
  .insights__posts .post-card{grid-template-columns:minmax(0,1fr)}
  .integ__stage{gap:clamp(16px,5vw,60px)}
}
@media (max-width:640px){
  .hero__tabs{grid-template-columns:minmax(0,1fr);gap:.5rem}
  .hero__tab{padding:.75rem .95rem .85rem}
  .hero__stage{aspect-ratio:4/5}
  .slide-launch .fchip{font-size:.82rem;padding:.5rem .7rem}
  .slide-orbit .bubble{font-size:.75rem;max-width:160px}
  .case__stats{grid-template-columns:minmax(0,1fr)}
  .integ__stage{grid-template-columns:1fr auto 1fr;gap:12px}
  .integ .beam-node{width:48px;height:48px}
  .integ .beam-node--hub{width:110px;height:110px}
  .enrich{grid-template-columns:minmax(0,1fr);gap:.8rem}
  .enrich .arrow-anim{width:2px;height:28px;margin-inline:auto}
  .enrich .arrow-anim::after{animation:traveldown 2.4s var(--ease-in-out) infinite;left:-3px}
  @keyframes traveldown{0%{top:-10px;opacity:0}20%{opacity:1}80%{opacity:1}100%{top:30px;opacity:0}}
  .channels{max-width:320px}
  .channels .beam-node{width:52px;height:52px}
  .channels .beam-node--hub{width:104px;height:104px}
  .channels .c3{left:3%}
  .channels .c4{right:3%}
  .slide-leads{gap:10px}
  .slide-leads .beam-node.biz{width:118px;height:118px}
  .slide-leads .biz span{font-size:.72rem}
  .slide-leads .beam-node{width:46px;height:46px}
  .slide-leads .col{gap:30px}
  .slide-leads .beam-node .n-name{font-size:.68rem;top:calc(100% + 5px)}
  /* the bottom row now carries labels, so the pills clear them */
  /* Both captions hang below the diagram. At 320x640 the note needed 94px of room and
     had 84, so it crossed the tab row. Raised 14px each, which keeps the 14px gap
     between them and leaves the note clear of the controls at the narrowest size. */
  .slide-leads .lead-tag{bottom:-30px}
  .slide-leads .lead-note{bottom:-78px;font-size:.78rem;padding:.34rem .8rem}

}

/* The chips hang off the sides of the product shot on a wide hero. On a narrow one
   there is no room outside it, so bring them back inside rather than off screen. */
@media (max-width:900px){
  .slide-launch .fchip:nth-child(2){left:0;top:8%}
  .slide-launch .fchip:nth-child(3){right:0;top:0}
  .slide-launch .fchip:nth-child(4){left:0;bottom:18%}
  .slide-launch .fchip:nth-child(5){right:0;bottom:30%}
  .slide-launch .fchip:nth-child(6){left:50%;margin-left:-80px;bottom:0}
}
