/* ============================================================= TOKENS */
:root{
  --cloud:#FAFAFA; --canvas:#FFFFFF; --paper:#FFFFFF;
  --ink:#0E1116; --ink-elev:#161B22; --ink-2:#1B212B;
  --slate:#54606C; --steel:#8A93A0; --haze:#E7EAEE;
  --line:rgba(14,17,22,.09); --line-2:rgba(14,17,22,.055);
  --line-dark:rgba(14,17,22,.10); --line-dark-2:rgba(14,17,22,.06);
  --hair:rgba(14,17,22,.06);
  --cyan:#14B3D6; --cyan-deep:#0E93B2; --sky:#7AE2FF; --lavender:#C8DCFB;
  --pai:#2E5BFF; --pai-soft:#889CFF;
  --signal:linear-gradient(90deg,#14B3D6,#7AE2FF);
  /* inverted for the white canvas: surfaces are a light tint, not white-on-white */
  --glass:rgba(240,244,251,.75); --glass-2:rgba(240,244,251,.9); --glass-brd:rgba(255,255,255,.85);
  --font-display:"Geist",system-ui,-apple-system,sans-serif;
  --font-body:"Inter",system-ui,-apple-system,sans-serif;
  --font-label:"Inter",system-ui,-apple-system,sans-serif;
  --ease:cubic-bezier(.22,1,.36,1); --spring:cubic-bezier(.16,1,.3,1);
  --glass-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px var(--hair),0 28px 56px -30px rgba(14,17,22,.22),0 0 50px -30px rgba(20,179,214,.22);
  --tile-shadow:inset 0 1px 0 rgba(255,255,255,.85),0 8px 18px -12px rgba(14,17,22,.28);
  --shadow-sm:0 1px 2px rgba(14,17,22,.04);
  --shadow:0 1px 2px rgba(14,17,22,.04),0 14px 40px -16px rgba(14,17,22,.16);
  --shadow-lg:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px var(--hair),0 40px 90px -40px rgba(14,17,22,.32),0 0 60px -34px rgba(20,179,214,.24);
  --r-lg:22px; --r-md:14px; --r-sm:10px; --pill:999px;
  --wrap:1240px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
[id]{scroll-margin-top:92px}
body{
  margin:0;color:var(--ink);background:var(--canvas);
  font-family:var(--font-body);font-size:1rem;line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
/* ambient aurora removed — the canvas is pure white; depth now comes from the tinted surfaces */
/* grain */
body::before{
  content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.02;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer;border:0;background:none}
h1,h2,h3,h4{font-family:var(--font-display);font-weight:500;letter-spacing:-.02em;line-height:1.05;margin:0}
p{margin:0}
::selection{background:var(--cyan);color:#fff}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:4px}

/* ============================================================= LAYOUT */
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 clamp(1.25rem,4vw,2.5rem)}
.section{padding:clamp(4rem,9vw,8rem) 0}
.eyebrow{font-family:var(--font-label);font-size:.75rem;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--slate);display:inline-flex;align-items:center;gap:.6rem}
.eyebrow::before{display:none}
.eyebrow.on-dark{color:var(--steel)}
.lead{font-size:clamp(.98rem,1.35vw,1.12rem);color:var(--slate);max-width:64ch;line-height:1.62}

/* ---- on-page navigator: a vertical rail, so the header stays uncluttered.
     Labels stay hidden until you reach for the rail; only the current one shows. ---- */
.onpage{position:fixed;left:clamp(12px,1.9vw,26px);top:50%;transform:translateY(-50%);
  z-index:60;opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}
.onpage.on{opacity:1;pointer-events:auto}
/* collapsed: a quiet stack of dashes, no container. on hover each item becomes
   its own separate glass pill. */
.onpage-pill{position:relative;display:flex;flex-direction:column;gap:.28rem;padding:0;
  background:transparent;border:0}
.op-link{position:relative;display:flex;align-items:center;gap:.62rem;padding:.4rem .55rem;
  border-radius:999px;text-decoration:none;color:var(--steel);white-space:nowrap;
  background:transparent;border:1px solid transparent;
  transition:background .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease),color .25s var(--ease)}
.onpage:hover .op-link{background:var(--glass-2);border-color:var(--glass-brd);
  backdrop-filter:blur(18px) saturate(160%);-webkit-backdrop-filter:blur(18px) saturate(160%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px var(--hair),0 14px 30px -18px rgba(14,17,22,.28)}
.op-link i{flex:none;width:7px;height:7px;border-radius:50%;background:currentColor;opacity:.45;
  transition:transform .4s var(--spring),opacity .25s var(--ease),background .25s var(--ease)}
.op-link span{max-width:0;overflow:hidden;font-size:.78rem;line-height:1;opacity:0;
  transform:translateX(-4px);transition:max-width .4s var(--spring),opacity .3s var(--ease),transform .3s var(--ease)}
.onpage:hover .op-link span{max-width:190px;opacity:1;transform:none}
.op-link:hover{color:var(--ink)}
.op-link:hover i{opacity:.9}
.op-link.is-here{color:var(--cyan-deep)}
.op-link.is-here i{transform:scale(1.4);opacity:1;background:var(--cyan);box-shadow:0 0 0 3px rgba(20,179,214,.2)}
.op-link.is-here span{font-weight:600;color:var(--ink)}
.onpage:hover .op-link.is-here{background:rgba(20,179,214,.12);border-color:rgba(20,179,214,.3)}
@media(max-width:1180px){.onpage{display:none}}
.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}

/* ============================================================= BUTTONS */
.btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--font-body);
  font-weight:600;font-size:.95rem;padding:.85rem 1.5rem;border-radius:var(--pill);
  transition:transform .15s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease),color .2s var(--ease);white-space:nowrap}
.btn svg{width:17px;height:17px;transition:transform .25s var(--ease)}
.btn-primary{background:var(--cyan);color:#04141a;box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 10px 28px -12px rgba(20,179,214,.75)}
.btn-primary:hover{background:#2bc0e0;transform:translateY(-1px)}
.btn-primary:active{transform:translateY(1px)}
.btn-primary:hover svg{transform:translateX(3px)}
.btn-ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.btn-ghost:hover{border-color:var(--ink);transform:translateY(-1px)}
.btn-ghost{background:var(--glass)}
.hero .btn-ghost:hover,.final .btn-ghost:hover{border-color:var(--ink);background:var(--glass-2)}
.btn-lg{padding:1.05rem 1.75rem;font-size:1rem}
.textlink{display:inline-flex;align-items:center;gap:.45rem;font-weight:600;font-size:.95rem;color:var(--ink)}
.textlink .ar{transition:transform .25s var(--ease)}
.textlink:hover .ar{transform:translateX(4px)}
.textlink.cy{color:var(--cyan)}
.textlink:hover{color:var(--cyan-deep)}

/* ============================================================= HEADER */
/* a full-width translucent bar; on scroll it tightens — logo, type and height shrink */
/* Scoped to `body>header`, not a bare `header`. The site nav is the only
   <header> that is a direct child of <body>; page content also uses
   <header class="section-header"> (five of them on subtitles.html), and an
   unqualified `header` selector made those sticky at z-index 1000 too, so
   section headings stuck to the top of the viewport and painted over the
   cookie bar. The `header.scrolled` rules below stay unqualified on purpose:
   .scrolled is only ever set on the nav, by site.js. */
body>header{position:sticky;top:0;z-index:1000;padding:0;
  background:rgba(255,255,255,.72);
  backdrop-filter:blur(22px) saturate(180%);-webkit-backdrop-filter:blur(22px) saturate(180%);
  border-bottom:1px solid rgba(14,17,22,.07);
  transition:background .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease)}
header.scrolled{background:rgba(255,255,255,.82);border-bottom-color:rgba(14,17,22,.09);
  box-shadow:0 14px 34px -24px rgba(14,17,22,.3)}
.nav{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  height:80px;max-width:var(--wrap);margin:0 auto;padding:0 clamp(16px,3vw,32px);
  transition:height .35s var(--ease)}
header.scrolled .nav{height:60px}
.brand{display:flex;align-items:center;gap:.6rem;font-family:var(--font-display);font-weight:500;
  font-size:1.12rem;letter-spacing:-.02em;color:var(--ink);padding:5px 8px}
/* extra breathing room inside the logo pill, on the right (no external margin) */
header .brand{margin-right:0;padding-right:18px}
.brand .mark{width:30px;height:30px;flex:none}
.brand b{font-weight:500}.brand span{color:var(--steel);font-weight:400}
.brand-logo{height:54px;width:auto;display:block;transition:height .35s var(--ease)}
header.scrolled .brand-logo{height:40px}
footer .brand-logo{height:34px}
.mn-head .brand-logo{height:25px}
/* menu sits inline in the bar — no pill */
.nav-main{display:flex;align-items:center;gap:.15rem}
.nav-item{position:relative}
.nav-trigger{display:inline-flex;align-items:center;gap:.35rem;padding:.5rem .8rem;border-radius:var(--pill);
  font-size:.925rem;font-weight:400;color:var(--ink);white-space:nowrap;
  transition:color .2s,background .2s,font-size .35s var(--ease),padding .35s var(--ease)}
.nav-trigger:hover,.nav-item:hover .nav-trigger,.nav-item.open .nav-trigger{color:var(--ink);background:rgba(20,179,214,.10)}
.nav-trigger .chev{width:11px;height:11px;opacity:.6;transition:transform .25s var(--ease)}
.nav-item:hover .nav-trigger .chev,.nav-item.open .nav-trigger .chev{transform:rotate(180deg)}
header.scrolled .nav-trigger{font-size:.85rem;padding:.42rem .7rem}
.nav-right{display:flex;align-items:center;gap:.75rem}
.nav-right .btn{padding:.6rem 1.15rem;font-size:.9rem;gap:.4rem;transition:padding .35s var(--ease),font-size .35s var(--ease)}
.nav-right .btn svg{width:15px;height:15px}
header.scrolled .nav-right .btn{padding:.48rem .95rem;font-size:.83rem}

/* dropdown */
.dd{position:absolute;top:calc(100% + 14px);left:0;min-width:300px;background:rgba(255,255,255,.96);
  backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);
  border:1px solid var(--glass-brd);border-radius:18px;box-shadow:var(--shadow-lg);padding:.6rem;
  opacity:0;visibility:hidden;transform:translateY(10px);transition:.28s var(--spring);z-index:60}
/* JS owns opening now (hover, click-pin, focus), so the panel does not flash
   open again while the controller is swapping between triggers */
.nav-item.open .dd{opacity:1;visibility:visible;transform:translateY(0)}
.dd.mega{min-width:640px;padding:1.1rem;display:grid;grid-template-columns:1fr 1fr;gap:.4rem 1.4rem}
/* promo panel inside a dropdown: soft brand-blue gradient + product illustration */
.dd.has-promo{display:flex;align-items:stretch}
.dd-promo{flex:none;width:212px;margin-left:.55rem;border-radius:14px;overflow:hidden;
  display:grid;place-items:center;padding:1.1rem;
  background:linear-gradient(rgba(255,255,255,.62),rgba(255,255,255,.62)),url("sov-mesh.webp") center/cover no-repeat}  /* homepage mesh, washed lighter */
.dd-promo img{width:100%;max-height:200px;object-fit:contain;display:block}
/* narrow desktops: keep the promo, just make it slimmer (site.js nudges the menu into view) */
@media(max-width:1240px){.dd-promo{width:168px}.dd-promo img{max-height:168px}}
@media(max-width:1040px){.dd-promo{width:140px}.dd-promo img{max-height:140px}}
.dd-h{grid-column:1/-1;font-family:var(--font-label);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--steel);padding:.3rem .7rem .55rem}
.dd-link{display:flex;gap:.85rem;padding:.7rem;border-radius:var(--r-sm);transition:background .18s;
  /* the menu's own cyan, until a family below claims the row */
  --dd-wash:rgba(20,179,214,.09); --dd-ring:rgba(20,179,214,.34);
  --dd-cur:rgba(20,179,214,.07);  --dd-ink:var(--cyan-deep)}
/* Hover reads by product family: green down the streaming line, violet down the
   PAI line, slate for the corporate pages. Keyed on where the row goes rather
   than on a class, so no markup carries the colour and every page's menu picks
   it up. The washes sit at a tenth of an alpha — enough to name the family,
   not enough to shout.

   Each property holds a whole colour rather than the three channels: a bare
   triple has to be spliced back together inside rgba(), and that is the form
   older CSS minifiers mishandle — on a build pipeline that rewrites the sheet,
   every row would come out the same colour.

   And the match is on CONTAINS, not starts-with. Netlify's Pretty URLs
   post-processing rewrites href="video-streaming.html" to href="/video-streaming"
   in the served HTML; a leading slash defeats every ^= selector at once, which
   is exactly how the whole menu ends up one colour on the deployed site.
   Contains survives that, and the bare .html, and a relative ./ prefix. The
   names are distinct enough that no row can match two families. */
.dd-link[href*="video-streaming"],
.dd-link[href*="perception-stream"],
.dd-link[href*="player-plus"]        { --dd-wash:rgba(31,185,140,.10); --dd-ring:rgba(31,185,140,.34);
                                       --dd-cur:rgba(31,185,140,.09);  --dd-ink:#0C8A65 }
.dd-link[href*="perception-ai"],
.dd-link[href*="chat"],
.dd-link[href*="subtitles"],
.dd-link[href*="wallet"],
.dd-link[href*="legal"]              { --dd-wash:rgba(124,92,242,.09); --dd-ring:rgba(124,92,242,.32);
                                       --dd-cur:rgba(124,92,242,.08);  --dd-ink:#5B3FD1 }
.dd-link[href*="user-applications"],
.dd-link[href*="private-cdn"],
.dd-link[href*="why-cloudworks"]     { --dd-wash:rgba(84,96,108,.09);  --dd-ring:rgba(84,96,108,.30);
                                       --dd-cur:rgba(84,96,108,.08);   --dd-ink:#3E4A57 }
.dd-link:hover{background:var(--dd-wash)}
/* dropdown icons: solid glyphs, black, in a grey circle */
.dd-ic{width:38px;height:38px;flex:none;border-radius:12px;background:#fff;border:0;
  box-shadow:inset 0 0 0 1px rgba(14,56,69,.13);display:grid;place-items:center;
  color:var(--ink);
  transition:box-shadow .25s var(--ease),background .25s var(--ease)}
.dd-link:hover .dd-ic{background:#FBFDFE;
  box-shadow:inset 0 0 0 1px var(--dd-ring)}
.dd-ic svg{width:19px;height:19px}
.dd-tt{font-weight:600;font-size:.92rem;color:var(--ink);display:flex;align-items:center;gap:.5rem}
.dd-tag{font-family:var(--font-label);font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cyan);border:1px solid rgba(20,179,214,.35);border-radius:4px;padding:.05rem .3rem}
.dd-dd{font-size:.82rem;color:var(--slate);line-height:1.45;margin-top:.1rem}
.dd-foot{grid-column:1/-1;margin-top:.5rem;border-top:1px solid var(--line);padding:.85rem .7rem .2rem;
  display:flex;justify-content:space-between;align-items:center}
.dd-foot small{color:var(--steel);font-size:.8rem}

.burger{display:none;width:42px;height:42px;border-radius:var(--r-sm);border:1px solid var(--line);
  place-items:center;color:var(--ink)}
.burger svg{width:20px;height:20px}

/* ============================================================= HERO */
.hero{position:relative;background:transparent;color:var(--ink);overflow:hidden;isolation:isolate;padding-bottom:clamp(4rem,8vh,7rem)}
/* .hero::after aurora removed — hero sits on the white canvas, the 64px grid carries the texture */
/* ambient hero backdrop — the signal ribbon, behind everything incl. the grid.
   Masked so it only lives under the video card and never fights the headline. */
/* natural 16:9 so the ribbon isn't blown up ~1.6x by covering the tall hero.
   The clip's own backdrop is #ecf0f6–#f8fcfe, not white, so every edge must be
   feathered or the video's rectangle shows against the page. */
/* Capped, not fluid: with width:100% the clip grew with the viewport (1.19x at 1920px)
   and its top climbed into the copy. A fixed cap keeps both the scale and the top edge
   stable at any width. The clip's own backdrop is #ecf0f6–#f8fcfe, not white, so every
   edge is feathered or its rectangle shows against the page. */
.hero-bg-video{position:absolute;left:0;right:0;bottom:0;
  width:100%;height:min(900px,72%);
  object-fit:cover;object-position:center;z-index:-2;pointer-events:none;display:block;opacity:.5;
  /* longer top feather so the ribbon's upper edge dissolves — no hard line */
  --feather:linear-gradient(180deg,transparent 0,#000 52%,#000 88%,transparent 100%),
            linear-gradient(90deg,transparent 0,#000 4%,#000 96%,transparent 100%);
  -webkit-mask-image:var(--feather);-webkit-mask-composite:source-in;
  mask-image:var(--feather);mask-composite:intersect}
/* translucent white veil over the top of the hero — melts the video's top edge into the page */
.hero::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,#fff 0%,#fff 18%,rgba(255,255,255,0) 58%)}
.hero-grid-bg{position:absolute;inset:0;z-index:-1;opacity:.8;
  background-image:linear-gradient(rgba(14,17,22,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(14,17,22,.045) 1px,transparent 1px);
  background-size:64px 64px;mask-image:radial-gradient(78% 78% at 62% 32%,#000,transparent 88%)}
/* halftone globe: covers the hero, sphere geometry computed in hero-globe.js
   (apex behind the headline, centre far below — only the top cap shows).
   Bottom feather melts the dots into the trust bar. */
.hero-net{position:absolute;inset:0;z-index:-1;pointer-events:none;
  --gfade:linear-gradient(180deg,#000 0,#000 86%,transparent 99%);
  -webkit-mask-image:var(--gfade);mask-image:var(--gfade)}
.hero-globe{display:block;width:100%;height:100%}
/* same 1240 rail as .wrap, so the hero copy shares the page's left edge */
.hero-lead-wrap{min-height:66vh;max-width:var(--wrap);margin-inline:auto;display:flex;align-items:center;justify-content:flex-start;padding:clamp(86px,10vh,118px) clamp(1.25rem,4vw,2.5rem) clamp(1rem,2.5vh,1.6rem)}
.hero-copy{max-width:var(--wrap);margin:0;text-align:left;display:flex;flex-direction:column;align-items:flex-start;gap:1.15rem}
.hero h1{font-size:clamp(2.8rem,6.6vw,5.4rem);font-weight:600;letter-spacing:-.04em;line-height:1.01;margin:0}
.hero .sig{color:var(--cyan-deep);font-weight:600}
.hero-sub{font-family:var(--font-display);font-weight:500;font-size:clamp(1.08rem,2.05vw,1.5rem);letter-spacing:-.02em;line-height:1.24;color:var(--ink);max-width:26ch;margin:0}
.hero .lead{max-width:58ch;margin:0;font-size:clamp(.98rem,1.3vw,1.08rem)}
.hero-cta{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:.5rem;justify-content:flex-start}
.proof-strip{display:flex;gap:2.2rem;flex-wrap:wrap;justify-content:flex-start;margin:1rem 0 0;padding-top:1.7rem;border-top:1px solid var(--line)}
/* hero video — peeking company overview */
/* glass shell around the video — same recipe as .sov-fact-shell / .tree-shell.
   Outer radius = inner + the 8px padding, so the two curves stay concentric. */
/* player spans the content rail (same 1240 wrap as the copy) and sits lower under the CTAs */
.hero-video-shell{--vr:clamp(16px,2vw,26px);width:min(1160px,calc(100% - clamp(2.5rem,8vw,5rem)));
  margin:clamp(1.6rem,3.4vw,3rem) auto 0;padding:8px;
  border-radius:calc(var(--vr) + 8px);background:rgba(255,255,255,.2);
  box-shadow:inset 0 0 0 1px #fff,0 60px 120px -60px rgba(14,17,22,.26),0 0 110px -52px rgba(20,179,214,.38);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.hero-video{position:relative;width:100%;margin:0;aspect-ratio:16/9;border-radius:var(--vr);overflow:hidden;
  border:1px solid var(--line);background:#EEF2F6;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 0 0 1px var(--hair)}
.hero-video-el{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:var(--ink)}
.video-poster{position:absolute;inset:0;display:grid;place-items:center;cursor:pointer;transition:opacity .5s var(--ease);
  background:url("perception-overview-poster.jpg") center/cover no-repeat}
.video-poster.hidden{opacity:0;pointer-events:none}
/* branded Media Player Plus mark instead of the generic disc button.
   The old circular ring shadows would draw a rectangle around the wide lockup —
   drop-shadow follows the cloud's alpha instead. */
.video-play{position:relative;z-index:1;width:clamp(130px,15vw,180px);height:auto;border-radius:0;background:transparent;
  display:block;box-shadow:none;filter:drop-shadow(0 20px 44px rgba(20,179,214,.45));
  transition:transform .3s var(--spring),filter .3s}
.video-poster:hover .video-play{transform:scale(1.06);filter:drop-shadow(0 26px 56px rgba(20,179,214,.6))}
.video-play img{width:100%;height:auto;display:block}
.video-cap{position:absolute;left:clamp(1rem,2.5vw,1.9rem);bottom:clamp(1rem,2.5vw,1.7rem);z-index:1;font-family:var(--font-label);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.82)}
.proof-strip div{display:flex;flex-direction:column;gap:.15rem}
.proof-strip .n{font-family:var(--font-display);font-size:1.45rem;color:var(--ink);font-weight:500;letter-spacing:-.02em}
.proof-strip .n b{color:var(--cyan-deep);font-weight:600}
.proof-strip .l{font-size:.78rem;color:var(--steel);letter-spacing:.02em}

/* signal motif */
.motif{position:relative;aspect-ratio:1/1;width:100%}
.motif svg{width:100%;height:100%;overflow:visible}
.dash{stroke-dasharray:6 10;animation:flow 3s linear infinite}
@keyframes flow{to{stroke-dashoffset:-160}}
.pulse-node{transform-box:fill-box;transform-origin:center;animation:pnode 2.6s var(--ease) infinite}
.pulse-node.d1{animation-delay:.4s}.pulse-node.d2{animation-delay:.9s}.pulse-node.d3{animation-delay:1.4s}.pulse-node.d4{animation-delay:1.9s}
@keyframes pnode{0%,100%{opacity:.35}50%{opacity:1}}
.trace{stroke-dasharray:520;stroke-dashoffset:520;animation:trace 4.2s var(--ease) infinite}
@keyframes trace{0%{stroke-dashoffset:520}55%,100%{stroke-dashoffset:0}}
.spark{transform-box:fill-box;transform-origin:center;animation:spark 4.2s var(--ease) infinite}
@keyframes spark{0%{opacity:0;transform:scale(.4)}8%{opacity:1;transform:scale(1)}55%,100%{opacity:0;transform:scale(.4)}}
.orbit{transform-box:view-box;transform-origin:50% 50%;animation:orb 26s linear infinite}
@keyframes orb{to{transform:rotate(360deg)}}

/* ============================================================= LOGO MARQUEE */
.trust{border:0;background:transparent}
.trust-inner{padding:2.1rem 0;display:flex;align-items:center;gap:2.5rem}
.trust-lbl{font-family:var(--font-label);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--steel);flex:none;max-width:150px;line-height:1.5}
.marquee{overflow:hidden;flex:1;min-width:0;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
/* fixed rem gap (not vw): the marquee is capped at the 1240 wrap, so one half must
   stay wider than that at every desktop width for the -50% loop to be seamless */
.marquee-track{display:flex;align-items:center;width:max-content;animation:scroll 36s linear infinite}
.trust:hover .marquee-track{animation-play-state:paused}
@keyframes scroll{to{transform:translateX(-50%)}}
/* client logos — slightly dimmed, full colour on hover */
.logo-img{height:30px;width:auto;display:block;flex:none;opacity:.72;transition:opacity .25s var(--ease);
  /* The gap is measured between the LETTERING, not between the files. Several
     of these logos carry a wide band of empty artwork on each side — afri▶ has
     36px of it, X Wallet 31 — so an even margin between boxes produced gaps of
     47px in one part of the strip and 105px in another. Each logo declares the
     empty space it brings and gives it back, which leaves one true gap for the
     whole run. Insets are in rendered pixels and the heights are fixed, so they
     do not move with the viewport; only the gap itself does. */
  --gap:clamp(1.7rem,3.2vw,2.7rem); --ink-l:0px; --ink-r:0px;
  margin-left:calc(var(--ink-l) * -1);
  margin-right:calc(var(--gap) - var(--ink-r))}
.logo-img:hover{opacity:1}
.logo-img[src$="truthfull.png"] { --ink-l:9.3px;  --ink-r:9.3px }
.logo-img[src$="t2.png"]        { --ink-l:20.8px; --ink-r:20.8px }
.logo-img[src$="tmtg.png"]      { --ink-l:19.9px; --ink-r:19.6px }
.logo-img[src$="tvcabo.avif"]   { --ink-l:12.8px; --ink-r:12.8px }
.logo-img[src$="visabeira.png"] { --ink-l:10.1px; --ink-r:7.8px }
.logo-img[src$="africell.avif"] { --ink-l:13.5px; --ink-r:13.2px }
.logo-img[src$="softnet.avif"]  { --ink-l:19.6px; --ink-r:19.2px }
.logo-img[src$="truth.avif"]    { --ink-l:4.2px;  --ink-r:4.2px }
.logo-img[src$="avo.png"]       { --ink-l:24.9px; --ink-r:24.6px }
.logo-img[src$="afritv.png"]    { --ink-l:36.2px; --ink-r:36.2px }
.logo-img[src$="hbbtv.png"]     { --ink-l:26px;   --ink-r:26px }
.logo-img[src$="xwallet.png"]   { --ink-l:31.5px; --ink-r:31.2px }
.logo-img[src$="entyen.png"]    { --ink-l:17.8px; --ink-r:18.1px }
/* Optically levelled, not mathematically. One height for every file made the
   lettering come out at a dozen different sizes: each logo carries its own
   padding, its own proportion of emblem to wordmark, and the box the artwork
   sits in is not the thing the eye measures. So each is set from what the eye
   does measure — for a wordmark its cap height, for a mark its overall mass —
   which puts every name on the strip at the same apparent size. The heights
   below were read off each asset's inked pixels, then adjusted by eye.
   Keyed on the filename so every page that shows the strip gets them. */
.logo-img[src$="truth.avif"]{height:28.5px}
.logo-img[src$="truthfull.png"]{height:30px}
.logo-img[src$="t2.png"]{height:22px}
.logo-img[src$="tmtg.png"]{height:28px}
.logo-img[src$="tvcabo.avif"]{height:31.5px}
.logo-img[src$="rotana.png"]{height:26px}
.logo-img[src$="visabeira.png"]{height:35px}
.logo-img[src$="africell.avif"]{height:32.5px}
.logo-img[src$="softnet.avif"]{height:36px}
.logo-img[src$="gbnews.png"]{height:20px}
.logo-img[src$="fintech.png"]{height:26.5px}
.logo-img[src$="avo.png"]{height:28px}
.logo-img[src$="afritv.png"]{height:37px}
.logo-img[src$="hbbtv.png"]{height:33px}
.logo-img[src$="xwallet.png"]{height:27px}
.logo-img[src$="entyen.png"]{height:34px}

/* ============================================================= SOVEREIGNTY */
.sov{background:transparent}
.sov-quote{font-family:var(--font-display);font-weight:500;font-size:clamp(1.9rem,4.2vw,3.1rem);
  letter-spacing:-.03em;line-height:1.12;max-width:20ch}
.sov-quote em{font-style:normal;position:relative;white-space:nowrap}
.sov-quote em::after{content:"";position:absolute;left:0;right:0;bottom:.06em;height:.14em;background:var(--signal);border-radius:2px}
/* quote + lead stack on the left, facts ride a blurred mesh panel on the right */
.sov-two{display:grid;grid-template-columns:589fr 541fr;gap:30px;align-items:center}
.sov-left{min-width:0}
.sov-left .lead{margin-top:40px;max-width:none}
.sov-facts{position:relative;display:flex;align-items:center;justify-content:center;
  padding:60px clamp(1.5rem,3vw,2.5rem);border-radius:30px;overflow:hidden;
  /* the mesh, quietened. A white wash layered over the image rather than a
     filter on the panel: filter would take the three glass cards down with it,
     and they are the thing the panel exists to hold. .model-ill uses the same
     mesh and is deliberately left at full strength — there it is the subject,
     not a backdrop. */
  background:linear-gradient(rgba(255,255,255,.44),rgba(255,255,255,.44)),
    url("sov-mesh.webp") center/cover no-repeat}
.sov-facts-list{display:flex;flex-direction:column;gap:18px;width:369px;max-width:100%}
/* double glass: a bright 8px shell around each card.
   Rules are inset box-shadows, not borders — Figma's INSIDE stroke doesn't affect
   layout, so real borders would shift every size by 1–2px and compound down the stack. */
.sov-fact-shell{padding:8px;border-radius:30px;background:rgba(255,255,255,.2);
  box-shadow:inset 0 0 0 1px #fff;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.sov-fact{display:flex;gap:16px;padding:16px;border-radius:22px;
  background:rgba(255,255,255,.8);box-shadow:inset 0 0 0 1px rgba(255,255,255,.5);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.sov-fact svg{width:22px;height:22px;color:var(--cyan);flex:none;margin-top:2px}
.sov-fact b{font-weight:600;font-size:.98rem}
.sov-fact p{font-size:.9rem;color:var(--slate);margin-top:.2rem}

/* ============================================================= STACK */
.stream{background:transparent}
.head-2{max-width:60ch}
.head-2 h2{font-size:clamp(2rem,4vw,2.9rem);margin:1.1rem 0 1rem}

/* ============================================================= ARCHITECTURE */
/* FOUNDATION — the one dark anchor, echoing the diagram's base bar */
.foundation{margin-top:clamp(1.6rem,3vw,2.4rem);border-radius:24px;overflow:hidden;
  padding:clamp(1.5rem,3vw,2.1rem) clamp(1.6rem,3.4vw,2.6rem);
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem 2rem;flex-wrap:wrap;
  background:var(--ink);position:relative;isolation:isolate}
.foundation::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(52% 140% at 12% 0%,rgba(20,179,214,.28),transparent 60%),
             radial-gradient(48% 130% at 92% 100%,rgba(122,226,255,.14),transparent 62%)}
.foundation>*{position:relative;z-index:1}
.fnd-brand{display:flex;flex-direction:column;gap:.5rem}
.fnd-logo{height:clamp(30px,3.4vw,40px);width:auto;display:block}
.fnd-role{font-family:var(--font-label);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--sky)}
.fnd-attrs{display:flex;gap:.5rem;flex-wrap:wrap}
.fnd-attr{display:inline-flex;align-items:center;gap:.45rem;font-size:.76rem;color:rgba(255,255,255,.86);
  padding:.5rem .85rem;border-radius:999px;background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.fnd-attr svg{width:15px;height:15px;color:var(--sky);flex:none}

/* ---- the capability stack: four layers on sticky glass ---- */
.stack{background:transparent}
.layers{margin-top:3.5rem}
/* Breathing room between the Perception Stream heading block and the solution cards. */
.stream .solutions{margin-top:clamp(2.5rem,4vw,3.5rem)}
/* Perception Stream head illustration, parked to the right of the copy. */
.stream .head-2{position:relative}
.stream .plat-ill{position:absolute;right:0;top:50%;transform:translateY(-50%);
  width:clamp(240px,26vw,340px);height:auto;pointer-events:none;opacity:.68;
  filter:saturate(.85) drop-shadow(0 30px 54px rgba(14,17,22,.10))}
@media(max-width:1040px){.stream .plat-ill{position:static;transform:none;display:block;margin:1.75rem auto 0;width:min(300px,60%)}}
.layer{display:grid;grid-template-columns:1.15fr 1fr;gap:clamp(1.5rem,4vw,3rem);
  padding:clamp(1.9rem,3vw,2.5rem) clamp(1.7rem,3vw,2.4rem) clamp(1.9rem,3vw,2.5rem) clamp(46px,6vw,62px);align-items:start;
  position:sticky;overflow:hidden;background:rgba(240,244,251,.8);
  backdrop-filter:blur(44px) saturate(170%);-webkit-backdrop-filter:blur(44px) saturate(170%);
  border:0;border-radius:22px;box-shadow:none;margin-bottom:26px}
/* The sov mesh bleeds in from the right, fading out toward the left. Pinned to the
   image's own 541x529 so it renders at 1.00x here exactly as it does in .sov-facts;
   a %-of-height size ties the blob scale to card height, and the cards differ. The
   mask ramp is anchored to the mesh's own left edge (100% - 541px) rather than a
   percentage, so no seam appears where the artwork starts, at any card width. */
.layer::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:url("sov-mesh.webp") right center/541px 529px no-repeat;opacity:.5;
  -webkit-mask-image:linear-gradient(90deg,transparent calc(100% - 541px),rgba(0,0,0,.72) calc(100% - 300px),rgba(0,0,0,.72) 100%);
  mask-image:linear-gradient(90deg,transparent calc(100% - 541px),rgba(0,0,0,.72) calc(100% - 300px),rgba(0,0,0,.72) 100%)}
.layer-main,.layer-feats{position:relative;z-index:1}
.layer:nth-child(1){top:96px}.layer:nth-child(2){top:120px}.layer:nth-child(3){top:144px}.layer:nth-child(4){top:168px}
.layer-ix{position:absolute;left:clamp(20px,2.6vw,26px);top:0;bottom:0;z-index:1;display:flex;align-items:center}
.lay{display:block;font-family:var(--font-label);color:var(--cyan);letter-spacing:.12em;text-transform:uppercase;font-size:.72rem;font-weight:500;margin-bottom:.75rem}
.layer-ix .depth{display:flex;flex-direction:column;gap:7px}
.layer-ix .depth i{width:7px;height:7px;border-radius:50%;background:var(--haze);transition:.3s}
.layer-ix .depth i.on{background:var(--cyan)}
.layer-main .ttl{display:flex;align-items:center;gap:.8rem;margin-bottom:.7rem}
.layer-main .ttl h3{font-size:1.6rem}
.layer-ic{width:60px;height:60px;border-radius:100px;border:1px solid var(--glass-brd);background:var(--paper);box-shadow:none;
  display:grid;place-items:center;color:var(--cyan);flex:none}
.layer-ic svg{width:24px;height:24px}
.layer-main p{color:var(--slate);font-size:.98rem;max-width:44ch}
.layer-main .textlink{margin-top:1.1rem}
/* chips centred vertically, white glass over the mesh.
   gap leaves room for each chip's 5px outer shell. */
.layer-feats{display:flex;flex-wrap:wrap;gap:.95rem;align-content:center;align-self:center}
/* a real double-glass shell like .sov-fact-shell, drawn as a ::before so each bare
   chip keeps its own translucent-white ring (with blur) without an extra wrapper */
.chip{position:relative;isolation:isolate;display:inline-flex;align-items:center;gap:.42rem;
  font-size:.8rem;color:var(--slate);border-radius:var(--pill);padding:.42rem .8rem;
  background:rgba(255,255,255,.82);box-shadow:inset 0 0 0 1px rgba(255,255,255,.55);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);transition:color .2s}
.chip::before{content:"";position:absolute;inset:-5px;z-index:-1;border-radius:inherit;
  background:rgba(255,255,255,.2);box-shadow:inset 0 0 0 1px #fff;
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);transition:box-shadow .2s}
.chip-ic{width:13px;height:13px;color:var(--cyan);flex:none}
.chip:hover{color:var(--ink)}
.chip:hover::before{box-shadow:inset 0 0 0 1px rgba(20,179,214,.5)}
.layer:hover .layer-ix .depth i.on{box-shadow:0 0 8px -1px rgba(20,179,214,.6)}
/* ---- the layer card on a phone --------------------------------------------
   It never left the two-column grid. Measured at 375px: 193px of copy beside a
   120px column, with chips 100-120px wide in it — every one of them ran about
   48px past the card's right edge, which is what made the section look broken.
   The chips come down under the copy, and they shrink so that costs the card as
   little height as possible: at .72rem they sit two and three to a row instead
   of one, and the whole block is shorter than the column it replaces. The
   heading, badge and rail come down a step with them, since the padding they
   were sized against is smaller too. ------------------------------------- */
@media(max-width:760px){
  .layer{grid-template-columns:1fr;gap:clamp(.9rem,3vw,1.25rem);
    padding:1.5rem 1.25rem 1.5rem 34px}
  .stream .layer{min-height:0}
  .layer-feats{gap:.6rem;align-self:start;align-content:start}
  /* the gap has to clear each chip's outer shell, so the shell tightens too */
  .chip{font-size:.72rem;padding:.3rem .6rem;gap:.34rem}
  .chip::before{inset:-3px}
  .chip-ic{width:11px;height:11px}
  .layer-main .ttl{gap:.6rem;margin-bottom:.55rem}
  .layer-main .ttl h3{font-size:1.3rem}
  .layer-main p{font-size:.92rem}
  .layer-main .textlink{margin-top:.9rem}
  .layer-ic{width:44px;height:44px}
  .layer-ic svg{width:20px;height:20px}
  .layer-ix{left:13px}
  .layer-ix .depth{gap:6px}
  .layer-ix .depth i{width:6px;height:6px}
}
/* ---- Perception Stream: an escalating ladder, not three equal cards.
   Column widths and visual weight both climb with the tier, so the layout
   itself states the hierarchy before a word is read. ---- */
.tiers{margin-top:clamp(2rem,4vw,3rem);display:grid;grid-template-columns:1fr 1.07fr 1.28fr;
  gap:16px;align-items:stretch}
.tier{--acc:var(--cyan);--wash:rgba(20,179,214,.13);
  position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:.66rem;
  padding:clamp(1.5rem,2.7vw,2.1rem);border-radius:26px;text-decoration:none;overflow:hidden;
  background:var(--glass-2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.6);
  backdrop-filter:blur(18px) saturate(150%);-webkit-backdrop-filter:blur(18px) saturate(150%);
  transition:transform .35s var(--spring),box-shadow .35s var(--ease)}
/* the accent arrives as a wash off the top edge instead of a hairline rule */
.tier::before{content:"";position:absolute;left:0;right:0;top:0;height:62%;pointer-events:none;
  background:linear-gradient(180deg,var(--wash),transparent)}
.tier>*{position:relative;z-index:1}
.t-core{--acc:var(--cyan-deep);--wash:rgba(20,179,214,.15)}
.t-ent{--acc:#144ED6;--wash:rgba(20,78,214,.13)}
.t-ult{--acc:#E0A93F;--wash:rgba(224,169,63,.18)}
.tier:hover{transform:translateY(-6px)}
.t-core:hover,.t-ent:hover{box-shadow:inset 0 0 0 1px var(--acc),0 26px 54px -30px rgba(14,17,22,.45)}
/* the flagship inverts — one dark object in a light section owns the eye */
.t-ult{background:var(--ink);box-shadow:inset 0 0 0 1px rgba(255,255,255,.11)}
.t-ult::before{height:100%;background:radial-gradient(86% 62% at 82% -6%,rgba(224,169,63,.36),transparent 64%)}
.t-ult:hover{box-shadow:inset 0 0 0 1px rgba(224,169,63,.55),0 32px 64px -28px rgba(224,169,63,.4)}
.tier-flag{align-self:flex-end;font-family:var(--font-label);font-size:.6rem;letter-spacing:.16em;
  text-transform:uppercase;color:#E0A93F;padding:.28rem .6rem;border-radius:999px;
  background:rgba(224,169,63,.14);box-shadow:inset 0 0 0 1px rgba(224,169,63,.34);margin-bottom:-.3rem}
.tier-logo{height:30px;width:auto;display:block}
.tier-line{font-family:var(--font-display);font-weight:600;line-height:1.12;letter-spacing:-.025em;
  font-size:clamp(1.2rem,1.8vw,1.55rem);color:var(--ink)}
.t-ult .tier-line{color:#fff}
.tier-d{font-size:.87rem;line-height:1.55;color:var(--slate)}
.t-ult .tier-d{color:rgba(255,255,255,.66)}
.tier-chips{display:flex;flex-wrap:wrap;gap:.38rem;margin-top:auto;padding-top:.7rem}
.tchip{font-size:.69rem;color:var(--slate);padding:.3rem .62rem;border-radius:999px;
  background:rgba(255,255,255,.72);box-shadow:inset 0 0 0 1px rgba(255,255,255,.7)}
.t-ult .tchip{color:rgba(255,255,255,.78);background:rgba(255,255,255,.07);box-shadow:inset 0 0 0 1px rgba(255,255,255,.15)}
.tier-cta{display:inline-flex;align-items:center;gap:.4rem;font-size:.83rem;font-weight:600;color:var(--acc)}
.tier .ar{transition:transform .28s var(--ease)}
.tier:hover .ar{transform:translateX(5px)}
.tier-foot{margin-top:1.5rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.tier-foot p{font-size:.9rem;color:var(--slate)}

/* ---- adjacent platforms ---- */
.pfm{background:transparent;position:relative}
.pfm-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1.2rem 2rem;flex-wrap:wrap}
/* headline gets the room to land on one line; the lead stays at reading width */
.pfm-copy{max-width:min(100%,760px);flex:1 1 460px}
.pfm-copy h2{font-size:clamp(2rem,4vw,2.9rem);margin:1rem 0 .85rem}
.pfm-copy .lead{margin-bottom:0;max-width:56ch}
.pfm-link{flex:none}

/* Perception AI: the page drops into darkness — the sister brand is a different
   world on the same body, and each product finally carries its OWN colour. */
.pfm-ai{background:var(--ink);color:#fff;overflow:clip;isolation:isolate;border-radius:60px}
.pfm-ai::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(46% 58% at 94% 108%,rgba(122,226,255,.16),transparent 60%)}
.pfm-ai>.wrap{position:relative;z-index:1}
/* large semi-transparent PAI mark; its lower half tucks behind the cards */
.pfm-mark{position:absolute;z-index:0;pointer-events:none;top:clamp(20px,3vw,58px);
  /* anchor to the content column (.wrap), not the section edge, so it doesn't drift out on wide screens */
  right:max(clamp(4px,1.6vw,34px),calc((100% - var(--wrap))/2 - 30px));
  width:clamp(240px,29vw,420px);height:auto;mix-blend-mode:screen;opacity:.96;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 13%,#000 87%,transparent 100%),linear-gradient(to bottom,transparent 0,#000 12%,#000 84%,transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(to right,transparent 0,#000 13%,#000 87%,transparent 100%),linear-gradient(to bottom,transparent 0,#000 12%,#000 84%,transparent 100%);
  mask-composite:intersect}
.pfm-fill{opacity:.2}
.pfm-mark .mk-glint{opacity:1;filter:blur(.8px)}
.pfm-mark .mk-glint path{stroke-width:1.6;stroke-dasharray:.14 .86;animation-duration:7s}
/* animated glint travelling a mark's outline (reusable across marks); non-scaling => crisp px-width line */
.mk-glint path{fill:none;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke;stroke-dasharray:.16 .84;animation:mkGlint 4.6s linear infinite}
.mk-glint path:nth-child(2){animation-delay:-1.5s}
.mk-glint path:nth-child(3){animation-delay:-3s}
@keyframes mkGlint{to{stroke-dashoffset:-1}}
@media(prefers-reduced-motion:reduce){.mk-glint path{animation:none}}
@media(max-width:760px){.pfm-mark{width:min(58vw,300px);right:-6%}}
.pfm-ai .eyebrow{color:var(--pai-soft)}
.pfm-ai .eyebrow::before{background:linear-gradient(90deg,var(--pai),var(--pai-soft))}
.pfm-ai h2{color:#fff}
.pfm-ai .lead{color:rgba(255,255,255,.64)}
.pfm-ai .pfm-link{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.34);box-shadow:none}
.pfm-ai .pfm-link:hover{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.65);transform:translateY(-1px)}
/* Perception AI CTA parked at the foot of the section, centred and prominent */
.pfm-foot{display:flex;justify-content:center;margin-top:clamp(2.6rem,5vw,4rem)}
.pfm-foot .pfm-link{font-size:1.05rem;padding:1.05rem 2.1rem}
/* Perception AI head illustration, parked right of the copy (same as Stream) */
.pfm-ai .pfm-head{position:relative}
.pfm-ai .pfm-head .plat-ill{position:absolute;right:0;top:50%;transform:translateY(-50%);
  width:clamp(240px,26vw,340px);height:auto;pointer-events:none;
  filter:drop-shadow(0 30px 54px rgba(0,0,0,.35))}
@media(max-width:1040px){.pfm-ai .pfm-head .plat-ill{position:static;transform:none;margin:1.75rem auto 0;width:min(300px,60%)}}

.prods{margin-top:clamp(1.8rem,3.2vw,2.7rem);display:grid;gap:14px}
/* bento: alternating 4/2 then 2/4 spans — deliberately unequal, sized to content */
.prods-ai{grid-template-columns:repeat(6,1fr)}
.prods-ai .prod{grid-column:span 2}
.prods-ai .prod.wide{grid-column:span 4}
/* two equal ventures — consumer destinations, not list rows. They get the largest
   cards on the page: half-width each, tall, with the brand colour washing up from
   the floor of the card. */
/* The venture house: one Perception Media shell that visibly PARENTS the two
   ventures, so Entyen and Voyage read as its children rather than two loose
   brands sharing a row. Outer glass + hairline tree = the same language as the
   architecture diagram. --vgap drives both the grid and the connector maths. */
.house{margin-top:clamp(1.6rem,2.8vw,2.3rem);padding:10px;border-radius:36px;
  /* the section sits on pure white, so the page's white-on-white glass shell would
     vanish. The parent's own cyan is what the bezel is machined from — it holds
     the whole object together and reads as Perception Media's own material. */
  background:linear-gradient(180deg,rgba(20,179,214,.13),rgba(20,179,214,.045));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.6),0 30px 60px -34px rgba(14,17,22,.22)}
/* Concentric double bezel: the inner core's radius is the outer radius minus the
   bezel (36 - 10 = 26), so the curves nest instead of fighting. */
.house-in{position:relative;border-radius:26px;overflow:hidden;background:rgba(255,255,255,.86);
  box-shadow:inset 0 0 0 1px var(--line)}
/* The masthead runs on the SAME two columns as the ventures below, and the padding
   lives in the cells rather than the band — so the parent mark sits on exactly the
   same left edge as Entyen's, and its copy on exactly the same edge as Voyage's. */
/* column-gap MUST stay 0: .house-split has none, and any gap here would shrink the
   band's columns and knock the copy off the venture's left edge. Separation comes
   from the cell padding instead. */
.house-brand{display:grid;grid-template-columns:1fr 1fr;align-items:start;
  column-gap:0;row-gap:1.6rem;
  padding-block:clamp(2.2rem,3.6vw,3.1rem);box-shadow:inset 0 -1px 0 var(--line)}
.house-brand>*{padding-inline:clamp(1.7rem,2.6vw,2.3rem)}
/* the mark IS the section's eyebrow now, so the text one was dropped. It centres
   against the copy block rather than pinning to the top, which would leave a tall
   void under it — the left edge still lines up with Entyen's mark below. */
.house-mark{height:52px;width:auto;display:block;align-self:center}
.house-copy h2{font-size:clamp(1.8rem,2.7vw,2.45rem);letter-spacing:-.03em;margin:0 0 .85rem;
  text-wrap:balance}
.house-copy .lead{max-width:none;margin:0}
.house-copy .btn{margin-top:1.5rem}
/* Two halves of ONE panel, parted by a single hairline — not two cards in a tray.
   The halves carry no radius of their own; the core's overflow clips their outer
   corners, which is what makes the whole thing read as a single machined object. */
.house-split{display:grid;grid-template-columns:1fr 1fr}
/* Top-aligned, not bottom-aligned: in one shared panel the eye expects the two
   halves to rhyme, and the descriptions are different lengths. Mark, title and
   copy now line up across the divider; the link is pushed to a common floor. */
.vent{position:relative;isolation:isolate;overflow:hidden;text-decoration:none;
  display:flex;flex-direction:column;align-items:flex-start;gap:.62rem;min-height:322px;
  padding:clamp(1.7rem,2.6vw,2.3rem)}
.vent+.vent{box-shadow:inset 1px 0 0 var(--line)}
.vent::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(78% 62% at 50% 118%,var(--pc),transparent 68%);opacity:.34;
  transition:opacity .7s cubic-bezier(.32,.72,0,1)}
a.vent:hover::before{opacity:.66}
.vent img{--mark-gap:clamp(1.5rem,2.6vw,2.2rem);width:auto;height:38px;display:block;
  margin-bottom:var(--mark-gap);transition:transform .7s cubic-bezier(.32,.72,0,1)}
a.vent:hover img{transform:translateY(-2px)}
.vent .prod-go{margin-top:auto;padding-top:.9rem}
/* optical, not mechanical: Voyage carries a plane above and a 'g' descender below,
   so an equal box height renders its letters ~35% smaller than Entyen's. Sized to
   match x-heights (140/200 vs 91/200 of the box) instead. The -7px lifts its letter
   bodies onto Entyen's line; the matching 7px taken off the bottom keeps the mark
   SLOT equal in both halves, so the titles below start on exactly the same line. */
.vent.v-voyage img{height:52px;margin-top:-7px;margin-bottom:calc(var(--mark-gap) - 7px)}
.vent .prod-t{font-family:var(--font-display);font-weight:600;font-size:1.32rem;
  letter-spacing:-.025em;color:var(--ink)}
.vent .prod-d{font-size:.92rem;line-height:1.5;color:var(--slate);max-width:42ch}
a.vent:hover .prod-go .ar{transform:translateX(5px)}
.prod-go{display:inline-flex;align-items:center;gap:.4rem;margin-top:.35rem;
  font-size:.85rem;font-weight:600;color:var(--pc)}
.prod-go .ar{transition:transform .28s var(--ease)}
a.prod:hover .prod-go .ar{transform:translateX(5px)}

.prod{--pc:var(--pai);position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:.5rem;
  padding:1.3rem 1.4rem;border-radius:20px;text-decoration:none;overflow:hidden;
  background:var(--glass-2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.55);
  backdrop-filter:blur(14px) saturate(150%);-webkit-backdrop-filter:blur(14px) saturate(150%);
  transition:transform .32s var(--spring),box-shadow .32s var(--ease)}
/* each product's own accent, glowing from its lower-right corner */
.prod::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(72% 88% at 88% 108%,var(--pc),transparent 62%);opacity:.5;
  transition:opacity .32s var(--ease)}
.prod>*{position:relative;z-index:1}
a.prod:hover{transform:translateY(-5px)}
a.prod:hover::before{opacity:.85}
.prod img:not(.prod-ill){height:36px;width:auto;display:block;margin-bottom:.15rem}
.prod-t{font-family:var(--font-display);font-weight:600;font-size:1rem;letter-spacing:-.02em;color:var(--ink)}
.prod-d{font-size:.82rem;line-height:1.5;color:var(--slate)}
/* dark-section product cards */
.pfm-ai .prod{background:rgba(255,255,255,.055);box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.pfm-ai .prod-t{color:#fff}
.pfm-ai .prod-d{color:rgba(255,255,255,.6)}
.pfm-ai a.prod:hover{box-shadow:inset 0 0 0 1px var(--pc)}
/* the real brand accent of every product, at last */
.p-chat{--pc:#1EB29C}.p-subs{--pc:#91409D}.p-wallet{--pc:#725ED4}.p-legal{--pc:#C89237}
/* each venture's wash follows its own wordmark, not the Cloudworks cyan */
.v-entyen{--pc:#0205FE}.v-voyage{--pc:#A354FE}
.pfm-media a.prod:hover{box-shadow:inset 0 0 0 1px var(--pc)}
.prod.future{background:transparent;box-shadow:inset 0 0 0 1px var(--line);justify-content:center}
.prod.future::before{display:none}
.prod-future{font-family:var(--font-display);font-weight:500;font-size:1rem;color:var(--ink)}

@media(max-width:1000px){.tiers{grid-template-columns:1fr}
  .prods-ai .prod,.prods-ai .prod.wide{grid-column:span 3}}
@media(max-width:860px){.foundation{flex-direction:column;align-items:flex-start}}
@media(max-width:620px){.prods-ai .prod,.prods-ai .prod.wide{grid-column:1/-1}
  /* one column: the parting hairline turns from vertical to horizontal */
  .house-split{grid-template-columns:1fr}
  .house-brand{grid-template-columns:1fr}
  .vent{min-height:270px}
  .vent+.vent{box-shadow:inset 0 1px 0 var(--line)}}
.pai h3 .pai-x{color:var(--pai)}
.plogo-slot{width:104px;flex:none;display:flex;align-items:center}
.plogo{max-height:21px;max-width:100%;width:auto;display:block}
/* brand-promise marquee — huge bold light-grey uppercase; full-bleed edge to edge.
   Sits outside .wrap (in the section) so it spans the full screen with no 100vw
   scrollbar hack; only vertical rhythm is set here. */
.arch-marquee{margin-top:clamp(2.5rem,5vw,3.8rem);overflow:hidden;width:100%}
.arch-track{display:flex;align-items:center;gap:clamp(4.8rem,10vw,8rem);width:max-content;
  animation:scroll 130s linear infinite}
.arch-marquee:hover .arch-track{animation-play-state:paused}
/* Inter, not Geist: Geist's ink-trap notches read as stray "flags" inside T/F/L when
   glyphs render outline-only. Inter's caps have clean contours.
   2px stroke, not 1px: a 1px hairline at ~280px glyphs shimmers unevenly while the
   track animates on subpixel positions. */
.arch-item{font-family:var(--font-body);font-weight:600;font-size:clamp(11.2rem,22.4vw,17.6rem);
  letter-spacing:-.02em;text-transform:uppercase;white-space:nowrap;
  color:transparent;-webkit-text-stroke:2px rgba(14,17,22,.18);text-stroke:2px rgba(14,17,22,.18)}
.arch-item b{font-weight:600;color:inherit}   /* outline only, no fill */
.arch-dot{font-size:clamp(9.6rem,19.2vw,14.4rem);line-height:1;
  color:transparent;-webkit-text-stroke:2px rgba(14,17,22,.18);text-stroke:2px rgba(14,17,22,.18)}

/* ============================================================= RESULTS */
.results{background:transparent}
.res-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1.2rem;margin-top:3rem}
.res{padding:1.8rem 0;border-top:2px solid var(--haze)}
.res .rn{font-family:var(--font-display);font-weight:500;font-size:clamp(2.6rem,5vw,3.6rem);letter-spacing:-.03em;line-height:1}
.res .rn .u{color:var(--cyan)}
.res .rl{margin-top:.6rem;font-size:.92rem;color:var(--slate);max-width:22ch}
.res-note{margin-top:1.8rem;font-family:var(--font-label);font-size:.72rem;color:var(--steel);letter-spacing:.02em;max-width:800px}

/* ============================================================= INDUSTRIES */
.ind{background:transparent;border-top:1px solid var(--hair)}
.ind-grid{margin-top:3rem;display:grid;grid-template-columns:1fr 1fr;gap:1.2rem}
.ind-card{position:relative;padding:clamp(1.6rem,3vw,2.2rem);border:0;border-radius:var(--r-lg);
  background:var(--glass-2);backdrop-filter:blur(18px) saturate(150%);-webkit-backdrop-filter:blur(18px) saturate(150%);box-shadow:none;
  overflow:hidden;transition:transform .3s var(--spring),box-shadow .3s var(--ease)}
.ind-card:hover{transform:translateY(-5px);box-shadow:inset 0 0 0 1px rgba(20,179,214,.4)}
.ind-card .ico{width:auto;height:auto;background:none;border:0;box-shadow:none;
  display:block;color:var(--cyan);margin-bottom:.85rem}
.ind-card .ico svg{width:122px;height:auto;display:block}

/* glossy PNG illustrations — crisp, no grain, brightness eased so they don't glare */
/* the frame is cropped to the drawing, so there is no dead space left to pull
   in with negative margins — the card simply grows to fit the larger mark */
.ind-card .ico svg.ind-ill{width:149px;height:auto;display:block;margin:0 0 2px -6px;filter:none}
.ind-card h3{font-size:1.3rem;margin-bottom:.5rem}
.ind-card p{font-size:.92rem;color:var(--slate);max-width:38ch}
.ind-card .mix{margin-top:1.3rem;display:flex;gap:.4rem;flex-wrap:wrap}
.ind-card .mix span{font-family:var(--font-label);font-size:.64rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--slate);background:var(--paper);border:1px solid var(--line);border-radius:5px;padding:.2rem .45rem}
.ind-card .go{position:absolute;top:1.6rem;right:1.6rem;color:var(--steel);transition:.25s}
.ind-card:hover .go{color:var(--cyan);transform:translate(3px,-3px)}

/* ============================================================= DEPLOY */
.deploy-strip{margin-top:clamp(3rem,6vw,4.5rem);padding-top:clamp(2rem,4vw,3rem);border-top:1px solid var(--line)}
.deploy-strip-h{font-family:var(--font-display);font-weight:500;font-size:clamp(1.1rem,1.8vw,1.4rem);letter-spacing:-.02em;color:var(--ink);margin-bottom:1.5rem;max-width:none}
.deploy-strip .dep-grid{margin-top:0}
.cobrand{font-size:.82rem}
/* no outer frame any more — only the hairlines between cells */
.dep-grid{margin-top:3rem;display:grid;grid-template-columns:repeat(5,1fr);gap:0;
  border-radius:var(--r-lg);background:transparent}
.dep{padding:35.2px;display:flex;flex-direction:column;align-items:flex-start;gap:24px;
  border-right:1px solid var(--line);transition:background .25s;isolation:isolate}
.dep:last-child{border-right:0}
.dep:hover{background:rgba(20,179,214,.06)}
/* the exported illustrations are opaque white, not cut out — multiply drops the white
   so no white box shows over the hover tint. White x backdrop = backdrop. */
.dep-ill{height:125px;width:auto;display:block;mix-blend-mode:multiply}
.dep-copy{display:flex;flex-direction:column;gap:8px;align-self:stretch}
.dep h4{font-size:1.08rem;margin:0}
.dep p{font-size:.86rem;color:var(--slate);margin:0}

/* ============================================================= CASE */
.case{background:transparent}

/* ============================================================= PAI HANDOFF */

/* ============================================================= FINAL CTA */
/* final CTA is a dark card that floats down over the footer.
   z-index:2 lifts the whole section (and its overhanging card) above the footer (z:1),
   which otherwise painted its white bg over the card's lower half. */
.final{background:transparent;position:relative;z-index:2;text-align:center;
  padding:clamp(4rem,9vw,7rem) 0 0}
.final-card{position:relative;overflow:hidden;isolation:isolate;text-align:center;
  border-radius:clamp(26px,3vw,38px);background:var(--ink);color:#fff;
  padding:clamp(3.4rem,6vw,5.5rem) clamp(1.5rem,5vw,4rem);
  margin-bottom:clamp(-210px,-15vw,-150px);   /* overhang ~half the card into the footer */
  box-shadow:0 50px 110px -50px rgba(14,17,22,.6),0 0 0 1px rgba(255,255,255,.06);z-index:2}
/* soft cyan aurora inside the dark card */
.final-card::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(58% 90% at 50% -12%,rgba(20,179,214,.30),transparent 60%),
            radial-gradient(70% 80% at 50% 120%,rgba(122,226,255,.14),transparent 62%)}
.final-card>*{position:relative;z-index:1}
.final-card .final-grid-bg{position:absolute;inset:0;z-index:0;opacity:.6;
  background-image:linear-gradient(rgba(255,255,255,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 1px);
  background-size:56px 56px;mask-image:radial-gradient(62% 72% at 50% 36%,#000,transparent 80%)}
.final-card .eyebrow{justify-content:center}
.final-card h2{font-size:clamp(2.2rem,5vw,3.6rem);letter-spacing:-.03em;margin:1.3rem auto 1.2rem;max-width:16ch;color:#fff}
.final-card p{color:rgba(255,255,255,.72);max-width:52ch;margin:0 auto 2.2rem}
.final-cta{display:flex;gap:.8rem;justify-content:center;flex-wrap:wrap}
/* ghost button reads on the dark card */
.final-card .btn-ghost{background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.22);color:#fff}
.final-card .btn-ghost:hover{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.4)}

/* ============================================================= FOOTER */
/* footer sits under the dark card: white stays solid past the card's overhang (so the
   whole card floats over white), then fades to grey below it. Absolute px stops keep
   the white zone matched to the ~210px overhang regardless of footer height. */
footer{background:transparent;   /* day gradient lives in ::before so the night fade can dissolve it */
  color:var(--ink);border-top:0;position:relative;z-index:1;
  padding:clamp(240px,26vw,300px) 0 2.5rem}
footer::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,#fff 0px,#fff 270px,#E5E8EC 100%);
  opacity:calc(1 - var(--nightp,0));
  /* ramp the day wash in over the footer's top padding — a hard start shows as a
     visible seam against the darkening page while --nightp is mid-way */
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 clamp(200px,24vw,300px));
          mask-image:linear-gradient(180deg,transparent 0,#000 clamp(200px,24vw,300px))}
.foot-top{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 1.1fr;gap:2rem}
.foot-brand .brand{color:var(--ink);margin-bottom:1.1rem}
.foot-brand p{color:var(--steel);font-size:.88rem;max-width:30ch;margin-bottom:1.4rem}
.foot-contact{display:grid;gap:.4rem;font-size:.88rem}
.foot-contact a{color:var(--slate)}.foot-contact a:hover{color:var(--cyan-deep)}
.foot-col h5{font-family:var(--font-label);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--steel);margin:0 0 1.1rem;font-weight:500}
.foot-col a{display:block;color:var(--slate);font-size:.9rem;padding:.32rem 0;transition:color .2s}
.foot-col a:hover{color:var(--ink)}
.foot-bottom{margin-top:3.5rem;padding-top:1.8rem;border-top:1px solid var(--line-dark);
  display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap}
.foot-bottom p{color:var(--steel);font-size:.82rem}
/* the legal stack: copyright, the trademark notice, then the two documents.
   It takes the left of the bar and the social icons keep the right; the links
   inherit the bar's colour so they follow it into night without a second rule. */
.foot-legal{display:flex;flex-direction:column;gap:.4rem;max-width:66ch}
.foot-tm{font-size:.76rem;line-height:1.5}
.foot-terms{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-top:.15rem}
.foot-terms a{color:inherit;text-decoration:none;border-bottom:1px solid transparent;
  padding-bottom:1px;transition:.2s var(--ease)}
.foot-terms a:hover{color:color-mix(in oklab,#fff calc(var(--nightp,0)*100%),var(--ink));
  border-bottom-color:currentColor}
.foot-terms span{opacity:.4}
/* footer homepage-version toggle (V1 <-> V2 preview switch) */
.foot-ver{display:inline-flex;align-items:center;gap:.35rem;font-family:var(--font-body);font-weight:600;
  font-size:.8rem;letter-spacing:.01em;color:var(--cyan-deep);text-decoration:none;
  padding:.4rem .85rem;border-radius:999px;border:1px solid rgba(20,179,214,.35);transition:.2s var(--ease)}
.foot-ver:hover{border-color:var(--cyan-deep);background:rgba(20,179,214,.08);transform:translateY(-1px)}
html.night .foot-ver{color:var(--sky);border-color:rgba(122,226,255,.4)}
html.night .foot-ver:hover{border-color:var(--sky);background:rgba(122,226,255,.1)}
.foot-social{display:flex;gap:.5rem}
.foot-social a{width:36px;height:36px;border:1px solid var(--line);border-radius:8px;display:grid;place-items:center;
  color:var(--slate);background:var(--glass);transition:.2s}
.foot-social a:hover{color:var(--ink);border-color:var(--ink)}
.foot-social svg{width:16px;height:16px}

/* ============================================================= REVEAL */
[data-rise]{opacity:0;transform:translateY(24px);transition:opacity .7s var(--spring),transform .7s var(--spring)}
[data-rise].in{opacity:1;transform:none}
[data-rise].d1{transition-delay:.07s}[data-rise].d2{transition-delay:.14s}[data-rise].d3{transition-delay:.21s}
/* Perception AI product cards: richer, properly-staggered rise-in on scroll
   (their .d1/.d2 stagger lived on a duplicate class attribute the browser ignores,
    so drive the entrance from an animation + nth-child delays instead) */
.prods-ai .prod[data-rise].in{animation:aiCardRise .72s var(--spring) backwards}
@keyframes aiCardRise{from{opacity:0;transform:translateY(44px) scale(.972)}to{opacity:1;transform:none}}
.prods-ai .prod:nth-child(2)[data-rise].in{animation-delay:.13s}
.prods-ai .prod:nth-child(3)[data-rise].in{animation-delay:.26s}
@media(prefers-reduced-motion:reduce){.prods-ai .prod[data-rise].in{animation:none}}
[data-rise].d4{transition-delay:.28s}[data-rise].d5{transition-delay:.35s}

/* motion — GSAP-style mask-rise headings, cursor glow, magnetic buttons */
.hmasked{overflow:hidden;padding-bottom:.1em}
.hmask{display:block;transform:translateY(115%);transition:transform 1.05s var(--spring)}
.hmasked.in .hmask{transform:none}
.hmasked[data-rise]{opacity:1!important;transform:none!important;filter:none!important}
.magnetic{will-change:transform;transition:transform .35s var(--spring)}

/* ============================================================= MOBILE NAV */
.mobile-nav{position:fixed;inset:0;z-index:1200;background:rgba(244,247,252,.92);backdrop-filter:blur(24px) saturate(160%);-webkit-backdrop-filter:blur(24px) saturate(160%);
  opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility .3s var(--ease);
  display:flex;flex-direction:column;overflow-y:auto}
.mobile-nav.open{opacity:1;visibility:visible}
.mobile-nav .mn-body{opacity:0;transform:translateY(12px);transition:opacity .4s var(--ease) .06s,transform .4s var(--ease) .06s}
.mobile-nav.open .mn-body{opacity:1;transform:none}
.mn-head{display:flex;align-items:center;justify-content:space-between;height:72px;padding:0 clamp(1.25rem,4vw,2.5rem);
  border-bottom:1px solid var(--line)}
.mn-body{padding:1.5rem clamp(1.25rem,4vw,2.5rem) 3rem}
.mn-group{border-bottom:1px solid var(--line);padding:.4rem 0}
.mn-g-h{font-family:var(--font-label);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--steel);
  padding:1rem 0 .4rem}
.mn-link{display:flex;align-items:center;gap:.7rem;padding:.7rem 0;font-size:1.05rem;font-weight:500;color:var(--ink)}
.mn-link .t{font-family:var(--font-label);font-size:.6rem;color:var(--cyan);border:1px solid rgba(20,179,214,.35);
  border-radius:4px;padding:.05rem .3rem;letter-spacing:.08em}
.mn-cta{margin-top:1.8rem}
.mn-cta .btn{width:100%;justify-content:center}

/* ============================================================= RESPONSIVE */
@media(max-width:1080px){
  .dd.mega{min-width:520px}
}
@media(max-width:920px){
  .nav-main,.nav-right .btn{display:none}
  .burger{display:grid}
  .hero-lead-wrap{min-height:auto;padding:clamp(70px,9vh,96px) clamp(1.25rem,4vw,2.5rem) clamp(1rem,2.5vh,1.5rem)}
  .sov-two{grid-template-columns:1fr}
  .res-grid,.dep-grid{grid-template-columns:1fr 1fr}
  .dep:nth-child(2){border-right:0}.dep:nth-child(1),.dep:nth-child(2){border-bottom:1px solid var(--line)}
  .foot-top{grid-template-columns:1fr 1fr}
  .foot-brand{grid-column:1/-1}
}
@media(max-width:560px){
  body{font-size:1rem}
  .res-grid{grid-template-columns:1fr 1fr;gap:0 1.2rem}
  .trust-inner{flex-direction:column;align-items:stretch;gap:1.2rem}
  .marquee{width:100%}
  .proof-strip{gap:1.4rem}
  .hero-copy{gap:.9rem;max-width:540px}
  .hero h1{font-size:clamp(2.25rem,8.4vw,2.9rem)}
  .hero-sub{font-size:1.12rem;max-width:26ch}
  .hero .lead{font-size:.97rem;line-height:1.5}
  .hero-cta{margin-top:.2rem}
  .proof-strip{margin-top:.4rem;padding-top:1.3rem}
  .dep-grid{grid-template-columns:1fr}.dep{border-right:0;border-bottom:1px solid var(--line)}
  .foot-top{grid-template-columns:1fr}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
  [data-rise]{opacity:1;transform:none}
}
/* static capture mode (?nomotion=1) — everything rendered revealed, for Figma/screenshot capture */
html.no-motion *,html.no-motion *::before,html.no-motion *::after{animation:none!important;transition:none!important}
html.no-motion [data-rise]{opacity:1!important;transform:none!important;filter:none!important}
html.no-motion .hmask{transform:none!important}

/* ---- stub pages: says plainly that the content is not written yet ---- */
.page-flag{display:inline-block;margin-bottom:1rem;padding:.34rem .8rem;border-radius:var(--pill);
  background:rgba(224,169,63,.14);box-shadow:inset 0 0 0 1px rgba(224,169,63,.34);
  font-family:var(--font-body);font-weight:600;font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;color:#9A6B15}

/* ---- platform openers: the name is the headline, the kicker names the role.
     No numbering — Stream and AI are siblings, not a sequence. ---- */
.plat-kicker{display:block;font-family:var(--font-body);font-weight:500;font-size:.95rem;
  color:var(--cyan-deep);margin-bottom:.55rem}
.pfm-ai .plat-kicker{color:var(--pai-soft)}
.stream .head-2 h2,.pfm-ai .pfm-head h2{font-size:clamp(3rem,6vw,5rem);line-height:.98;letter-spacing:-.04em;
  text-wrap:balance}
.plat-lead{margin-top:1.15rem;max-width:62ch;font-size:clamp(1.05rem,1.5vw,1.22rem);line-height:1.62;
  color:var(--slate);text-wrap:pretty}
.plat-lead b{font-weight:600;color:var(--ink)}
.pfm-ai .plat-lead{color:rgba(255,255,255,.74)}
.pfm-ai .plat-lead b{color:#fff}
.stream .head-2,.pfm-ai .pfm-copy{max-width:none}
/* the longer service copy needs room to breathe */
.prods-ai .prod{min-height:0}
.prods-ai .prod-d{font-size:.88rem;line-height:1.6;max-width:52ch;text-wrap:pretty}
.prods-ai .prod-d em{font-style:normal;color:rgba(255,255,255,.92)}
@media(prefers-reduced-motion:reduce){.plat-lead,.plat-kicker{transition:none}}

/* ---- Perception AI products adopt the Stream solution card: full width, and the same
     sticky stack, so both platforms read with one rhythm ---- */
/* 2x2 grid — all four products visible together, no scroll-stack */
.prods-ai{grid-template-columns:1fr 1fr;gap:clamp(14px,1.7vw,20px)}
.prods-ai .prod,.prods-ai .prod.wide{grid-column:auto;position:relative;top:auto;
  min-height:clamp(244px,28vw,310px);padding:clamp(1.5rem,2.2vw,2rem);border-radius:20px;
  justify-content:flex-start;gap:.5rem}
.prods-ai .prod img:not(.prod-ill){height:45px}
.prods-ai .prod-t{font-family:var(--font-display);font-weight:600;font-size:1.28rem;letter-spacing:-.02em}
.prods-ai .prod-d{font-size:.88rem;line-height:1.56;max-width:none}
.prods-ai .prod{background:rgba(19,24,32,.9);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),inset 0 0 0 1px rgba(255,255,255,.09);
  backdrop-filter:blur(20px) saturate(150%);-webkit-backdrop-filter:blur(20px) saturate(150%)}
.prods-ai .prod::before{background:radial-gradient(64% 150% at 88% 120%,var(--pc),transparent 66%);opacity:.42}
.prods-ai a.prod:hover::before{opacity:.68}
@media(max-width:760px){.prods-ai{grid-template-columns:1fr}}

/* ---- no pill, no border, no shadow: just a soft white ellipse that blurs whatever
     scrolls under the mark. The mask fades the blur out, so there is no edge at all. ---- */
.brand .brand-logo{display:block}

/* ---- one line drawing per Perception AI product, in that product's own accent ---- */
.prod-ill{position:absolute;right:clamp(1rem,2vw,1.9rem);bottom:clamp(1rem,1.8vw,1.5rem);top:auto;transform:none;
  width:clamp(150px,18vw,214px);height:auto;color:var(--pc);opacity:1;pointer-events:none;
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.prods-ai .prod-ill{filter:url(#ai-grain)}
.prods-ai a.prod:hover .prod-ill{opacity:1;transform:scale(1.03)}
.prods-ai .prod-d{max-width:min(40ch,calc(100% - clamp(120px,15vw,180px)))}
@media(max-width:600px){.prod-ill{opacity:.85;width:clamp(120px,26vw,150px)}}
@media(prefers-reduced-motion:reduce){.prods-ai a.prod:hover .prod-ill{transform:none}}


/* ========================= Core vs Enterprise — one comparison, done once =========================
   Reference: the flagship column is a single floating gradient panel; every mark is a white
   circular badge; the losing column and the feature list stay quiet. Palette is ours. */
.cmpx{margin-top:clamp(2rem,3.2vw,2.8rem)}
.cmpx-wrap{position:relative;--xc-spine-w:250px}
.xc-spine{display:none;position:absolute;top:0;bottom:0;right:0;width:var(--xc-spine-w);z-index:0;pointer-events:none;
  background:linear-gradient(to right,rgba(20,78,214,.10),#fff);
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 13%,#000 87%,transparent 100%);
          mask-image:linear-gradient(180deg,transparent 0,#000 13%,#000 87%,transparent 100%)}
.cmpx table{position:relative;z-index:1;width:100%;border-collapse:collapse;table-layout:fixed}
.cmpx col.col-core{width:200px}
.cmpx col.col-ent{width:250px}

/* head — quiet labels; the panel carries the emphasis */
.cmpx thead th{padding:0 0 1.15rem;vertical-align:bottom;text-align:center;background:#fff;border:0;
  position:sticky;top:72px;z-index:4;box-shadow:0 12px 18px -16px rgba(14,17,22,.22)}
.cmpx thead .xc-feat{text-align:left}
.cmpx thead img{height:34px;width:auto;display:block;margin:0 auto}
.cmpx thead .xc-lbl{font-family:var(--font-display);font-weight:600;font-size:1.08rem;
  letter-spacing:-.01em;color:var(--ink)}
.cmpx thead .xc-ent{padding-top:1.35rem}
.cmpx thead .xc-ent .xc-lbl{color:#123FA8}

/* rows — hairlines, tall, calm */
.cmpx tbody th[scope="row"]{padding:.72rem 1.6rem .72rem 16px;text-align:left;font-weight:400;
  font-size:.95rem;color:var(--slate);border-top:1px solid var(--line-2);transition:color .18s var(--ease)}
.cmpx tbody td{padding:.72rem 1rem;text-align:center;border-top:1px solid var(--line-2)}
.cmpx tbody td.xc-e{border-top-color:rgba(20,78,214,.14)}
.cmpx tbody tr:hover th[scope="row"]{color:var(--ink)}

/* category bands span the reading columns only, so the panel is never cut */
.cmpx .xc-band th{padding:0;border:0;border-top:12px solid transparent;border-bottom:12px solid transparent;
  background:#F4F6F9;background-clip:padding-box}
.xc-band-btn{width:100%;display:flex;align-items:center;justify-content:space-between;gap:.55rem;
  padding:.86rem .5rem .86rem 16px;background:none;border:0;cursor:pointer;
  font-family:var(--font-body);color:var(--ink);text-align:left;line-height:1}
.xc-band-static{cursor:default}
.xc-band-t{font-weight:600;font-size:.74rem;letter-spacing:.14em;text-transform:uppercase}
.xc-band-ic{position:relative;width:22px;height:22px;flex:none;border-radius:50%;
  border:1px solid rgba(14,17,22,.2);color:var(--slate);
  transition:border-color .22s var(--ease),color .22s var(--ease)}
.xc-band-ic::before,.xc-band-ic::after{content:"";position:absolute;background:currentColor;
  transition:opacity .22s var(--ease)}
.xc-band-ic::before{top:50%;left:6px;right:6px;height:1px;transform:translateY(-50%)}   /* thin horizontal */
.xc-band-ic::after{left:50%;top:6px;bottom:6px;width:1px;transform:translateX(-50%)}     /* thin vertical (hidden when open -> minus) */
.xc-band-btn:hover .xc-band-ic,.xc-band-btn[aria-expanded="true"] .xc-band-ic{border-color:var(--cyan-deep);color:var(--cyan-deep)}
.xc-band-btn[aria-expanded="true"] .xc-band-ic::after{opacity:0}
/* no separator hairline directly under a band heading — it groups the rows beneath it */
.cmpx tbody .xc-band + tr th[scope="row"],
.cmpx tbody .xc-band + tr td{border-top:0}

/* marks — one shape everywhere */
.xc-mk{display:inline-flex;align-items:center;justify-content:center}
.xc-mk svg{width:18px;height:18px}
.xc-yes{color:var(--cyan-deep)}
.xc-e .xc-yes{color:#123FA8}
.xc-no{color:rgba(14,17,22,.32)}
.xc-no svg{width:18px;height:18px}
.xc-txt{display:inline-block;padding:.34rem .74rem;border-radius:999px;font-size:.8rem;color:var(--slate)}
.xc-e .xc-txt{background:#fff;color:var(--ink);box-shadow:0 5px 13px -6px rgba(14,17,22,.28)}
.cmpx td sup{font-size:.62rem;color:var(--steel);margin-left:.1rem;vertical-align:super}

/* foot */
.xc-foot{display:flex;flex-wrap:wrap;align-items:center;gap:.7rem 2rem;margin-top:1.4rem;
  padding-top:1.2rem;border-top:1px solid var(--line);font-size:.75rem;color:var(--steel)}
.xc-foot span{flex:1 1 320px}
.xc-key{list-style:none;display:flex;gap:1.3rem;margin:0;padding:0}
.xc-key li{display:flex;align-items:center;gap:.5rem;color:var(--slate);white-space:nowrap}
.xc-key .xc-mk{width:22px;height:22px}.xc-key .xc-mk svg{width:12px;height:12px}
@media(max-width:900px){
  .cmpx-wrap{--xc-spine-w:100px}.cmpx col.col-core{width:80px}.cmpx col.col-ent{width:100px}
  .cmpx thead .xc-lbl{font-size:.9rem}.cmpx tbody th[scope="row"]{font-size:.85rem}
}

/* ---- comparison: collapsed to key rows, expandable ---- */
.cmpx-more{display:flex;justify-content:center;margin-top:1.6rem}
.cmpx-toggle{display:inline-flex;align-items:center;gap:.55rem;padding:.72rem 1.5rem;border-radius:999px;
  border:1px solid var(--line);background:#fff;font-family:var(--font-body);font-weight:600;font-size:.86rem;
  color:var(--ink);cursor:pointer;box-shadow:none;
  transition:border-color .25s var(--ease),background .25s var(--ease),transform .25s var(--ease)}
.cmpx-toggle:hover{border-color:var(--steel);background:var(--cloud);transform:translateY(-1px)}
.cmpx-toggle:active{transform:translateY(0)}
.cmpx-toggle svg{width:16px;height:16px;transition:transform .3s var(--ease)}
.cmpx:not(.is-collapsed) .cmpx-toggle svg{transform:rotate(180deg)}
.cmpx.is-collapsed tbody tr:not([data-key]):not(.xc-band){display:none}
@media(prefers-reduced-motion:reduce){.cmpx-toggle,.cmpx-toggle svg{transition:none}}

/* the Managed Service art is a square export with wide margins, so its object reads
   smaller than the landscape ones — scale it up visually without changing its box,
   so the card heights and copy baselines stay aligned across the row. */
.dep-ill[src*="managed"]{transform:scale(1.32);transform-origin:center}

/* the marquee now scrolls a designed vector-stroke phrase instead of CSS-outlined text */
.arch-svg{height:clamp(96px,15vw,180px);width:auto;display:block;flex:none}

/* ===================== Case studies: a horizontal strip of portrait cards ===================== */
.case-head{display:flex;justify-content:space-between;align-items:flex-end;gap:1.5rem;
  margin-bottom:clamp(1.6rem,3vw,2.4rem)}
.case-head-t .eyebrow{margin-bottom:.6rem}
.case-head-t h2{font-family:var(--font-display);font-weight:500;font-size:clamp(2rem,3.6vw,2.9rem);
  letter-spacing:-.03em;color:var(--ink);text-wrap:balance}
.case-nav{display:flex;gap:.5rem;flex:none}
.case-arrow{width:44px;height:44px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;
  background:#fff;border:1px solid var(--line);color:var(--ink);cursor:pointer;
  transition:background .2s var(--ease),border-color .2s var(--ease),transform .2s var(--ease),opacity .2s var(--ease)}
.case-arrow svg{width:18px;height:18px}
.case-arrow[data-dir="-1"] svg{transform:scaleX(-1)}
.case-arrow:hover{border-color:var(--steel);background:var(--cloud)}
.case-arrow:active{transform:scale(.94)}
.case-arrow[disabled]{opacity:.35;cursor:default}
.case-arrow[disabled]:hover{border-color:var(--line);background:#fff}

/* full-bleed strip: direct child of the section, so its right edge is the screen edge
   and its left aligns with the wrap content. Uses % (scrollbar-safe), never vw. */
.case .cases-scroll,.ind .cases-scroll{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  padding:4px clamp(1.25rem,4vw,2.5rem) 14px
    max(clamp(1.25rem,4vw,2.5rem), calc((100% - var(--wrap)) / 2 + clamp(1.25rem,4vw,2.5rem)));
  scroll-padding-left:max(clamp(1.25rem,4vw,2.5rem), calc((100% - var(--wrap)) / 2 + clamp(1.25rem,4vw,2.5rem)));
  scroll-padding-right:clamp(1.25rem,4vw,2.5rem);
  scrollbar-width:none;-ms-overflow-style:none}
.case .cases-scroll::-webkit-scrollbar,.ind .cases-scroll::-webkit-scrollbar{display:none}
/* Mouse-draggable strips. The grab cursor is the only affordance the strip has
   once the scrollbar is hidden, so it is offered wherever there is a real
   pointer. While the hand is down, snapping and smooth scrolling are off — both
   fight a per-frame scrollLeft — and text selection is suppressed. */
@media(hover:hover) and (pointer:fine){
  .case .cases-scroll,.ind .cases-scroll{cursor:grab}
  .case .cases-scroll.is-drag,.ind .cases-scroll.is-drag{cursor:grabbing}
}
.case .cases-scroll.is-drag,.ind .cases-scroll.is-drag{
  scroll-snap-type:none;scroll-behavior:auto;user-select:none;-webkit-user-select:none}
.cases-scroll.is-drag a{pointer-events:none}
/* Industries presented as a horizontal card strip (same machinery as case studies) */
.ind .case-head{align-items:flex-start}
.ind .case-head-t .lead{margin-top:.85rem;max-width:64ch}
.ind .cases-scroll .ind-card{flex:0 0 clamp(300px,26vw,344px);scroll-snap-align:start;margin:0;
  display:flex;flex-direction:column;min-height:clamp(300px,30vw,360px)}
.ind .cases-scroll .ind-card .mix{margin-top:auto}
@media(max-width:620px){.ind .cases-scroll .ind-card{flex-basis:82vw}}
.case-tile{flex:0 0 clamp(272px,25vw,320px);scroll-snap-align:start;
  display:flex;flex-direction:column;min-height:clamp(370px,42vw,430px);
  padding:clamp(1.5rem,2.2vw,1.9rem);border-radius:24px;
  background:var(--glass-2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.6);
  transition:box-shadow .3s var(--ease),transform .3s var(--ease)}
.case-tile:hover{transform:translateY(-3px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.7),0 26px 50px -30px rgba(14,17,22,.28)}
.ct-badge{display:inline-flex;align-items:center;gap:.5rem;align-self:flex-start;
  font-family:var(--font-label);font-size:.66rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--cyan-deep)}
.ct-badge i{width:6px;height:6px;border-radius:50%;background:var(--cyan)}
.ct-q{margin:1.1rem 0 0;font-family:var(--font-display);font-weight:500;font-size:1.16rem;line-height:1.35;
  letter-spacing:-.015em;color:var(--ink);text-wrap:pretty}
.ct-bottom{margin-top:auto;padding-top:1.4rem}
.ct-stat b{display:block;font-family:var(--font-display);font-weight:600;font-size:1.7rem;
  letter-spacing:-.02em;color:var(--ink)}
.ct-stat span{display:block;margin-top:.2rem;font-size:.8rem;line-height:1.4;color:var(--steel)}
.ct-who{display:flex;align-items:center;gap:.6rem;margin-top:1.1rem;padding-top:1.1rem;
  border-top:1px solid var(--line)}
.ct-who img{height:22px;width:auto;max-width:90px;object-fit:contain;flex:none}
.ct-who span{font-size:.78rem;color:var(--slate)}
.ct-more{display:inline-flex;align-items:center;gap:.4rem;margin-top:1.1rem;
  font-family:var(--font-body);font-weight:600;font-size:.84rem;color:var(--cyan-deep);text-decoration:none}
.ct-more svg{width:16px;height:16px;transition:transform .28s var(--ease)}
.ct-more:hover svg{transform:translateX(4px)}
@media(max-width:620px){.case-nav{display:none}
  .case-tile{flex-basis:82vw}}
@media(prefers-reduced-motion:reduce){.cases-scroll{scroll-behavior:auto}.case-tile,.ct-more svg{transition:none}}

/* Core & Enterprise: constrained to the site body width (var(--wrap)), like every
   other section — head and table share the same centred wrap. */
#tiers .head-2{max-width:720px}
#tiers .xc-feat{width:auto}
/* ===== #tiers — comfortable, considered comparison (breathing room over cram) ===== */
#tiers{padding:clamp(3rem,6vw,5rem) 0}
#tiers .head-2{max-width:860px}
#tiers .xc-foot{margin-top:1.4rem}
#tiers .head-2 h2{font-size:clamp(1.7rem,3vw,2.4rem);line-height:1.14;margin:.6rem 0 .55rem}
#tiers .head-2 .lead{font-size:clamp(.95rem,1.1vw,1.05rem);line-height:1.5}
#tiers .cmpx{margin-top:clamp(1.6rem,3vw,2.6rem)}
#tiers .cmpx thead th{padding:0 0 .95rem}
#tiers .cmpx thead img{height:44px}
#tiers .cmpx thead .xc-ent{padding-top:.9rem}
#tiers .cmpx tbody th[scope="row"]{padding:.5rem 1.6rem .5rem 16px;line-height:1.32;font-size:.95rem}
#tiers .cmpx tbody td{padding:.5rem 1rem}
#tiers .cmpx .xc-band th{padding:0}
#tiers .xc-mk{width:22px;height:22px}
#tiers .xc-mk svg{width:18px;height:18px}
#tiers .cmpx-more{margin-top:1.4rem}
#tiers .cmpx-toggle{padding:.62rem 1.45rem;font-size:.86rem}

/* dropdowns: icon + title + desc rows, with grouped columns for Products */
.dd-txt{display:flex;flex-direction:column;min-width:0}
.dd-link{align-items:center}
.dd.cols{display:flex;gap:0;min-width:600px;padding:.5rem}
.dd-col{flex:1;min-width:262px;padding:.4rem .5rem}
.dd-col+.dd-col{border-left:1px solid var(--line);margin-left:.2rem;padding-left:.7rem}
.dd-h{margin:0}
.dd-h+.dd-link{margin-top:.1rem}
/* a second group in the same column: the heading takes a hairline and some
   air above it, so it reads as a new group rather than as a caption on the
   link it follows */
.dd-col .dd-link+.dd-h{margin-top:.55rem;padding-top:.7rem;border-top:1px solid var(--line-2)}

/* ============================================================= NIGHT FADE
   Scroll-driven: --nightp goes 0->1 as the footer arrives (site.js). The page
   canvas sinks to ink and the footer chrome goes light. color-mix scrubs with
   the scroll; the html.night hooks carry transitions for the logo + fallback. */
body{background:color-mix(in oklab,var(--ink) calc(var(--nightp,0)*100%),var(--canvas))}
.foot-brand p,.foot-bottom p{color:color-mix(in oklab,#9FB0C0 calc(var(--nightp,0)*100%),var(--steel))}
.foot-col h5{color:color-mix(in oklab,#8FA3B5 calc(var(--nightp,0)*100%),var(--steel))}
.foot-col a,.foot-contact a{color:color-mix(in oklab,#D9E4EE calc(var(--nightp,0)*100%),var(--slate))}
.foot-col a:hover,.foot-contact a:hover{color:color-mix(in oklab,#fff calc(var(--nightp,0)*100%),var(--ink))}
.foot-bottom{border-top-color:color-mix(in oklab,rgba(255,255,255,.16) calc(var(--nightp,0)*100%),var(--line-dark))}
.foot-social a{border-color:color-mix(in oklab,rgba(255,255,255,.22) calc(var(--nightp,0)*100%),var(--line));
  color:color-mix(in oklab,#D9E4EE calc(var(--nightp,0)*100%),var(--slate));
  background:color-mix(in oklab,rgba(255,255,255,.06) calc(var(--nightp,0)*100%),var(--glass))}
.foot-social a:hover{color:color-mix(in oklab,#fff calc(var(--nightp,0)*100%),var(--ink));
  border-color:color-mix(in oklab,#fff calc(var(--nightp,0)*100%),var(--ink))}
footer .brand-logo{transition:filter .5s ease}
html.night footer .brand-logo{filter:brightness(0) invert(1)}
/* Dark (PAI) pages: footer is dark from the first paint — pin the night end-state so
   the day gradient (footer::before, opacity:1-nightp) is off and foot chrome is light.
   No transition to animate since nightp never changes here (site.js skips the fade). */
body.pai{--nightp:1}
body.pai footer .brand-logo{filter:brightness(0) invert(1)}
/* coarse fallback if color-mix is unavailable: snap on the class instead */
@supports not (color:color-mix(in oklab,#000 50%,#fff)){
  body,footer .foot-col a,.foot-contact a,.foot-brand p,.foot-bottom p{transition:background-color .6s,color .6s}
  html.night body{background:var(--ink)}
  html.night .foot-col a,html.night .foot-contact a{color:#D9E4EE}
  html.night .foot-brand p,html.night .foot-bottom p{color:#9FB0C0}
  html.night .foot-col h5{color:#8FA3B5}
}

/* ============================================================= HERO V2 — deep-blue mosaic variant (v2.html only, scoped to .hero-v2) */
.hero-v2{position:relative;min-height:min(880px,94vh);overflow:hidden;isolation:isolate;
  padding:clamp(96px,13vh,150px) 0 clamp(3rem,6vh,5rem);color:#fff;
  background:radial-gradient(115% 90% at 82% 6%,rgba(20,179,214,.13),transparent 52%),
    radial-gradient(90% 80% at 6% 104%,rgba(8,40,74,.5),transparent 60%),
    linear-gradient(162deg,#02080f 0%,#04121f 48%,#061c30 100%)}
.hero-v2::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.55;
  background-image:linear-gradient(rgba(122,226,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(122,226,255,.05) 1px,transparent 1px);
  background-size:60px 60px;-webkit-mask-image:radial-gradient(82% 82% at 72% 22%,#000,transparent 90%);mask-image:radial-gradient(82% 82% at 72% 22%,#000,transparent 90%)}
.hero-v2 .hero-copy{position:relative;z-index:3;max-width:min(700px,58%);padding-right:1.4rem;
  margin-left:max(clamp(1.25rem,4vw,2.5rem),calc((100% - var(--wrap))/2 + clamp(1.25rem,4vw,2.5rem)))}
.hero-v2 .hero-copy h1{color:#fff;text-shadow:0 2px 34px rgba(4,16,28,.35)}
.hero-v2 .hero-sub{color:#dff0f7}
.hero-v2 .hero-sub .sig{color:var(--sky)}
.hero-v2 .lead{color:rgba(255,255,255,.66)}
.hero-v2 .hero-mosaic{position:absolute;top:0;right:0;bottom:0;width:clamp(500px,54%,900px);z-index:1;
  display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr);gap:14px;grid-auto-flow:dense;
  padding:clamp(1.5rem,3.4vh,3rem) clamp(1.4rem,3vw,2.6rem) clamp(1.5rem,3.4vh,3rem) 0;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 20%);mask-image:linear-gradient(90deg,transparent 0,#000 20%)}
.hero-v2 .hm-tile{border-radius:16px;position:relative;overflow:hidden;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);transition:transform .35s var(--ease)}
.hero-v2 .hm-tile:hover{transform:translateY(-4px)}
.hero-v2 .hm-video{grid-row:span 2;background:linear-gradient(140deg,#0f5286,#1a86b8 55%,#22b6d8)}
.hero-v2 .hm-video.v-b{background:linear-gradient(140deg,#123f74,#2a6fb0 60%,#4bb7d6)}
.hero-v2 .hm-video.v-c{background:linear-gradient(140deg,#0c3b5f,#0f6fa0 55%,#17a9cf)}
.hero-v2 .hm-video::after{content:"";position:absolute;inset:0;background:radial-gradient(circle at 30% 24%,rgba(255,255,255,.18),transparent 46%)}
.hero-v2 .hm-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:2;width:46px;height:46px;border-radius:50%;
  background:rgba(255,255,255,.92);display:grid;place-items:center;color:#0a2c4c;box-shadow:0 10px 24px -8px rgba(0,0,0,.4)}
.hero-v2 .hm-play svg{width:16px;height:16px;margin-left:2px}
.hero-v2 .hm-tag{position:absolute;top:10px;left:10px;z-index:2;font-family:var(--font-label);font-size:.56rem;font-weight:700;
  letter-spacing:.12em;background:#ff4d5e;color:#fff;padding:.22rem .45rem;border-radius:5px}
.hero-v2 .hm-logo{display:grid;place-items:center;background:rgba(255,255,255,.95);padding:1rem;box-shadow:inset 0 0 0 1px rgba(255,255,255,.6)}
.hero-v2 .hm-logo img{max-height:26px;max-width:80%;width:auto;opacity:.82}
.hero-v2 .hm-feat{display:flex;flex-direction:column;justify-content:space-between;padding:.95rem 1rem;color:#fff;
  background:linear-gradient(150deg,rgba(20,179,214,.92),rgba(14,78,150,.92));box-shadow:inset 0 0 0 1px rgba(255,255,255,.16)}
.hero-v2 .hm-feat.alt{background:linear-gradient(150deg,rgba(122,226,255,.22),rgba(20,179,214,.12));color:#eaf9ff;box-shadow:inset 0 0 0 1px rgba(122,226,255,.28)}
.hero-v2 .hm-feat svg{width:26px;height:26px}
.hero-v2 .hm-feat span{font-family:var(--font-label);font-size:.64rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase}

.vmodal{position:fixed;inset:0;z-index:3000;display:grid;place-items:center;padding:6vh 5vw;background:rgba(4,14,24,.82);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);animation:vmfade .25s var(--ease)}
.vmodal[hidden]{display:none}
@keyframes vmfade{from{opacity:0}to{opacity:1}}
.vmodal-frame{width:100%;aspect-ratio:16/9;border-radius:18px;overflow:hidden;background:#000;box-shadow:0 50px 120px -30px rgba(0,0,0,.75)}
.vmodal-frame video{width:100%;height:100%;object-fit:cover;display:block}
.vmodal-box{position:relative;width:min(1040px,94vw)}
.vmodal-close{position:absolute;top:-14px;right:-14px;z-index:2;width:42px;height:42px;border-radius:50%;cursor:pointer;color:#fff;
  background:rgba(18,32,46,.92);border:1px solid rgba(255,255,255,.3);display:grid;place-items:center;
  box-shadow:0 10px 26px -8px rgba(0,0,0,.7);transition:background .2s,transform .2s,border-color .2s}
.vmodal-close:active{transform:scale(.94)}
@media(max-width:620px){.vmodal-close{top:-10px;right:-6px;width:38px;height:38px}}
.vmodal-close:hover{background:rgba(255,255,255,.2)}
@media(max-width:900px){
  .hero-v2 .hero-copy{max-width:none;margin-right:clamp(1.25rem,4vw,2.5rem)}
  .hero-v2 .hero-mosaic{position:relative;top:auto;right:auto;bottom:auto;width:auto;margin-top:2.2rem;
    grid-template-rows:repeat(3,88px);-webkit-mask-image:none;mask-image:none;padding:0 clamp(1.25rem,4vw,2.5rem)}
  .hero-v2 .hero-fab{position:fixed}
}
@media(prefers-reduced-motion:reduce){.hero-v2 .hm-tile,.hero-v2 .hero-fab{transition:none}.vmodal{animation:none}}

/* ===== HERO V2 — concave ring around the viewer.
   Each tile travels along the FAR half of a cylinder: rotateY(t) translateZ(-r).
   At t=0 it is at the centre => farthest (small + blurred); at t=±72° it is at the
   left/right edge with z=0 => nearest (large + sharp). The trailing rotateY(-t)
   counter-rotates the tile so it stays square-on to the camera — never skewed.
   Every tile sits on the visible arc, so nothing is wasted off-screen. */
.hero-v2 .hero-arc{position:absolute;inset:0;z-index:1;overflow:hidden;pointer-events:none;
  perspective:880px;perspective-origin:50% 46%}
.hero-v2 .ha-ring{position:absolute;left:50%;top:var(--y);width:0;height:0;transform-style:preserve-3d;
  transform:rotateX(var(--tilt,0deg))}
.hero-v2 .ha-t{position:absolute;left:0;top:0;width:86px;height:54px;margin:-27px 0 0 -43px;transition:box-shadow .55s ease-out;
  border-radius:7px;overflow:hidden;background:#0a2b46;
  box-shadow:0 12px 26px -12px rgba(0,0,0,.72),inset 0 0 0 1px rgba(255,255,255,.11);
  animation:haArc var(--d,28s) linear infinite,haDepth var(--d,28s) linear infinite;
  animation-direction:var(--dirn,normal)}
/* left edge (near) -> centre (far) -> right edge (near); tile always faces camera */
@keyframes haArc{
  from{transform:rotateY(84deg)  translateZ(calc(var(--r) * -1)) rotateY(-84deg) rotateX(calc(var(--tilt,0deg) * -1)) scale(.82)}
  to  {transform:rotateY(-84deg) translateZ(calc(var(--r) * -1)) rotateY(84deg)  rotateX(calc(var(--tilt,0deg) * -1)) scale(1.42)}}
/* depth cue: sharp + bright at the near edges, small-blurred-dim through the far centre */
@keyframes haDepth{
  0%  {filter:blur(0) brightness(1);   opacity:0}
  5%  {filter:blur(.3px) brightness(.99);opacity:1}
  50% {filter:blur(3.6px) brightness(.62);opacity:1}
  95% {filter:blur(.3px) brightness(.99);opacity:1}
  100%{filter:blur(0) brightness(1);   opacity:0}}
/* hover anywhere in the hero — the whole arc runs the other way */
.hero-v2 .ha-g{width:100%;height:100%;object-fit:cover;display:block;filter:saturate(1.05)}
.hero-v2 .ha-t::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(165deg,rgba(4,18,32,.22),transparent 62%)}
.hero-v2 .ha-veil{position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(100deg,rgba(6,26,45,.95) 0%,rgba(6,26,45,.85) 18%,rgba(6,26,45,.36) 35%,rgba(6,26,45,0) 54%),
    linear-gradient(180deg,rgba(6,26,45,.68) 0%,transparent 14%,transparent 86%,rgba(6,26,45,.8) 100%)}
.hero-v2 .hero-copy{z-index:3}
@media(max-width:900px){
  .hero-v2 .hero-arc{perspective:900px;perspective-origin:50% 50%}
  .hero-v2 .ha-ring{left:50%}
  .hero-v2 .ha-t{width:76px;height:48px;margin:-24px 0 0 -38px}
}
@media(prefers-reduced-motion:reduce){.hero-v2 .ha-t{animation:none;opacity:1;filter:none}}
/* ---- HERO V2: taller stage, arcs up top with wider vertical gaps, globe below ---- */
.hero-v2{min-height:calc(100svh - 81px);height:calc(100svh - 81px);padding-top:clamp(58px,8vh,104px);padding-bottom:0;display:flex;flex-direction:column;justify-content:center}
.hero-v2 .hero-arc{inset:0;height:100%}
/* the V1 dotted globe, sitting under the arcs */
.hero-v2 .hero-net{position:absolute;left:50%;top:auto !important;bottom:0;transform:translateX(-50%);overflow:hidden;
  width:min(1180px,104vw);height:clamp(380px,66%,580px);z-index:1;pointer-events:none;
  --gm:linear-gradient(90deg,transparent 0,#000 6%,#000 94%,transparent 100%),linear-gradient(180deg,transparent 0,#000 16%);
  -webkit-mask-image:var(--gm);-webkit-mask-composite:source-in;mask-image:var(--gm);mask-composite:intersect}
.hero-v2 .hero-net .hero-globe{position:absolute;left:0;top:0;filter:none}
/* photographic Earth as the globe body — circular soft mask melts the limb into the dark hero */
.hero-v2 .hero-net .globe-vid{position:absolute;object-fit:contain;pointer-events:none;
  filter:brightness(1.05) saturate(1.06) contrast(1.02)}
/* links drawn from the globe's city nodes up to the video thumbnails */
.hero-v2 .ha-links{position:absolute;inset:0;z-index:2;pointer-events:none;overflow:visible}

@media(max-width:900px){
  .hero-v2{min-height:auto;padding-bottom:clamp(3rem,7vh,5rem)}
  .hero-v2 .hero-arc{height:58%}
  .hero-v2 .hero-net{position:relative;left:auto;bottom:auto;transform:none;width:100%;height:340px;margin-top:1.5rem}
}
/* On a phone the globe was 340px of a hero the copy already fills — a third of
   the screen spent on a decoration whose city nodes are a few pixels across and
   whose point (a network reaching everywhere) does not survive the crop. It
   goes, and the links drawn from its nodes go with it: they anchor to it, so
   left alone they would run to nothing. */
@media(max-width:760px){
  .hero-v2 .hero-net,
  .hero-v2 .ha-links{display:none}
  /* THE SEAM ACROSS THE HERO. .ha-veil is inset:0 inside .hero-arc, and on a
     phone the arc is only 58% of the hero — so the veil's vertical gradient,
     which ends on rgba(3,12,22,.8) at 100%, laid a dark band that stopped dead
     at the arc's bottom edge: a hard line right across the hero, at the same y
     where overflow:hidden was cutting the tiles. Raising the arc to full height
     would fix the line but drop the tiles behind the copy and the CTA, which is
     what the 58% is there to prevent. So the arc dissolves instead of ending —
     one mask takes the veil's band and the tile clip out together. */
  .hero-v2 .hero-arc{
    -webkit-mask-image:linear-gradient(180deg,#000 0,#000 56%,transparent 100%);
            mask-image:linear-gradient(180deg,#000 0,#000 56%,transparent 100%)}
}
/* ---- V2 dark hero: header rides transparent over it until the user scrolls ---- */
body.dark-hero #header:not(.scrolled){background:transparent;border-bottom-color:transparent;
  -webkit-backdrop-filter:none;backdrop-filter:none}
body.dark-hero #header:not(.scrolled) .nav-trigger,
body.dark-hero #header:not(.scrolled) .nav-trigger .chev{color:#fff}
body.dark-hero #header:not(.scrolled) .nav-trigger:hover{color:var(--sky)}
body.dark-hero #header:not(.scrolled) .brand-logo{filter:brightness(0) invert(1)}
body.dark-hero #header:not(.scrolled) .burger{color:#fff}
/* the veil no longer needs to darken the top strip — the header sits clear now */
body.dark-hero .hero-v2 .ha-veil{
  background:linear-gradient(100deg,rgba(3,12,22,.95) 0%,rgba(3,12,22,.85) 18%,rgba(3,12,22,.36) 35%,rgba(3,12,22,0) 54%),
    linear-gradient(180deg,rgba(3,12,22,.55) 0%,transparent 12%,transparent 86%,rgba(3,12,22,.75) 100%)}
/* the dark hero slides up UNDER the sticky header, so the transparent bar shows
   the hero (not the white page) behind it while unscrolled */
body.dark-hero main{margin-top:-113px}
body.dark-hero .hero-v2{height:100svh;min-height:100svh;padding-top:clamp(118px,15vh,168px);padding-bottom:clamp(120px,16vh,210px)}
/* ...except on a phone, where the globe that filled the lower half is gone and
   a pinned full screen would just be a gap under the CTA. Content sets the
   height, and the 118/120px of padding it was holding comes down with it. This
   has to sit AFTER the rule above, not in the earlier mobile block: the two
   selectors weigh the same, so the later one is the one that applies. */
@media(max-width:760px){
  body.dark-hero .hero-v2{height:auto;min-height:0;
    padding-top:clamp(92px,13vh,118px);padding-bottom:clamp(2rem,5vh,3rem)}
}
body.dark-hero #header:not(.scrolled) .nav-trigger{text-shadow:0 1px 12px rgba(0,0,0,.45)}
/* impulse links: faint guide + bright travelling head */
.hero-v2 .ha-links .hl-base{stroke:rgba(122,226,255,.34);stroke-width:.8}
.hero-v2 .ha-links .hl-pulse{stroke:rgba(150,225,250,.8);stroke-width:1.3;stroke-linecap:round;
  filter:drop-shadow(0 0 4px rgba(122,226,255,.4))}
.hero-v2 .ha-links .hl-head{fill:#cdeeff;filter:drop-shadow(0 0 5px rgba(122,226,255,.55))}
/* arrival: the frame lights up and a glint sweeps across the gif */
.hero-v2 .ha-t::before{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;opacity:0;
  background:linear-gradient(100deg,transparent 26%,rgba(224,250,255,.72) 50%,transparent 74%)}
.hero-v2 .ha-t.is-hit::before{animation:haGlint .8s cubic-bezier(.3,.72,.28,1)}
@keyframes haGlint{from{opacity:1;transform:translateX(-125%)}to{opacity:1;transform:translateX(125%)}}
.hero-v2 .ha-t.is-hit{box-shadow:0 0 0 1.8px rgba(165,240,255,.92),0 0 24px -3px rgba(122,226,255,.55),
  0 12px 26px -12px rgba(0,0,0,.72)}
/* ---- V2 hero copy: smaller type, outline CTA ---- */
.hero-v2 .hero-copy h1{font-size:clamp(2.4rem,5vw,3.9rem);font-weight:600;letter-spacing:-.035em;line-height:1.02}
.hero-v2 .hero-sub{font-size:clamp(1.06rem,1.5vw,1.19rem);line-height:1.55;max-width:46ch}
.hero-v2 .lead{font-size:clamp(.84rem,1vw,.94rem);line-height:1.62;max-width:64ch}
.hero-v2 .hero-cta{margin-top:.9rem}
.hero-v2 .hero-cta .btn-primary{background:transparent;color:var(--sky);
  border:1px solid rgba(122,226,255,.55);box-shadow:none;
  padding:.78rem 1.5rem;font-size:.9rem}
.hero-v2 .hero-cta .btn-primary svg{width:15px;height:15px}
.hero-v2 .hero-cta .btn-primary:hover{background:rgba(122,226,255,.1);
  border-color:rgba(122,226,255,.95);color:#eafaff;box-shadow:0 0 22px -6px rgba(122,226,255,.45)}
/* ---- V2 hero: overview presented as a glass preview card (bottom-right) ---- */
.hero-v2 .hero-fab{position:absolute;right:clamp(1.1rem,3vw,2.4rem);bottom:clamp(1.1rem,3vh,2.2rem);z-index:6;
  width:clamp(255px,25vw,319px);display:flex;flex-direction:column;align-items:stretch;gap:.68rem;
  padding:11px 11px 14px;border-radius:22px;cursor:pointer;text-align:left;
  background:rgba(14,26,40,.62);border:1px solid rgba(255,255,255,.14);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);backdrop-filter:blur(16px) saturate(1.3);
  box-shadow:0 30px 60px -28px rgba(0,0,0,.8);
  transition:transform .3s var(--ease),border-color .3s var(--ease),box-shadow .3s var(--ease)}
.hero-v2 .hero-fab:hover{transform:translateY(-4px);border-color:rgba(122,226,255,.5);
  box-shadow:0 36px 70px -28px rgba(0,0,0,.85),0 0 30px -10px rgba(122,226,255,.35)}
.hff-shot{position:relative;display:block;border-radius:13px;overflow:hidden;aspect-ratio:16/9;
  background:#05121e;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
.hff-shot img{width:100%;height:100%;object-fit:cover;display:block;filter:brightness(.6) saturate(.9) contrast(1.05)}
.hff-shot::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(160deg,rgba(5,18,30,.55),rgba(5,18,30,.15) 55%,rgba(20,179,214,.18))}
.hff-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:42px;height:42px;border-radius:50%;display:grid;place-items:center;
  background:var(--cyan);color:#fff;box-shadow:0 8px 20px -6px rgba(0,0,0,.55);
  transition:transform .3s var(--ease)}
.hff-play svg{width:15px;height:15px;margin-left:2px}
.hero-v2 .hero-fab:hover .hff-play{transform:translate(-50%,-50%) scale(1.09)}
.hff-badge{align-self:flex-start;font-family:var(--font-label);font-size:.6rem;font-weight:700;
  letter-spacing:.13em;color:var(--sky);padding:.2rem .45rem;border-radius:5px;
  border:1px solid rgba(122,226,255,.45);background:rgba(122,226,255,.08)}
.hff-title{font-family:var(--font-body);font-weight:500;font-size:.88rem;line-height:1.38;
  color:rgba(255,255,255,.92);text-wrap:pretty}
@media(max-width:900px){.hero-v2 .hero-fab{position:relative;right:auto;bottom:auto;width:auto;margin:1.4rem auto 0}}

/* ===== DEPLOY (v2) — two models side by side + optional managed band ===== */
/* one big grey panel: infra cards on top, the managed-service note at the bottom */
.dep-panel{margin-top:clamp(2.2rem,4vw,3rem);padding:clamp(1.4rem,2.6vw,2.2rem);
  background:#F4F6F9;border-radius:var(--r-lg)}
.dep-panel .dep2-grid{margin-top:0}
.dep-panel .dep-managed{margin-top:clamp(1.2rem,2.2vw,1.8rem);background:none;border:0;
  border-top:1px solid var(--line);border-radius:0;padding:clamp(1.4rem,2.6vw,2rem) clamp(.4rem,1vw,.9rem) clamp(.4rem,1vw,.7rem)}
.dep2-grid{margin-top:clamp(2.2rem,4vw,3rem);display:grid;grid-template-columns:1fr 1fr;gap:clamp(1rem,1.8vw,1.4rem)}
.dep2{display:flex;flex-direction:column;align-items:flex-start;gap:1.4rem;padding:clamp(1.8rem,3vw,2.6rem);background:#fff;
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease)}
.dep2:hover{border-color:rgba(20,179,214,.45);box-shadow:0 30px 60px -34px rgba(14,17,22,.28);transform:translateY(-3px)}
.dep2-ill{height:clamp(120px,13vw,150px);width:auto;display:block;mix-blend-mode:multiply}
.dep2-copy{display:flex;flex-direction:column;gap:.7rem}
.dep2 h3{font-family:var(--font-display);font-weight:500;font-size:clamp(1.3rem,2vw,1.65rem);letter-spacing:-.02em;color:var(--ink);margin:0}
.dep2 p{font-size:.95rem;line-height:1.62;color:var(--slate);margin:0}
.dep-managed{margin-top:clamp(1rem,1.8vw,1.4rem);display:grid;grid-template-columns:auto 1fr;align-items:center;gap:clamp(1.6rem,4vw,3.2rem);
  padding:clamp(1.6rem,3vw,2.4rem) clamp(1.8rem,3.5vw,3rem);border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(118deg,rgba(20,179,214,.07),rgba(122,226,255,.035) 55%,rgba(255,255,255,0))}
.dep-managed-ill{height:clamp(96px,10vw,128px);width:auto;display:block;mix-blend-mode:multiply}
.dep-managed-copy{display:flex;flex-direction:column;gap:.55rem}
.dep-managed h3{font-family:var(--font-display);font-weight:500;font-size:clamp(1.25rem,1.9vw,1.55rem);letter-spacing:-.02em;color:var(--ink);margin:.15rem 0 0}
.dep-managed p{font-size:.95rem;line-height:1.62;color:var(--slate);margin:0;max-width:74ch}
@media(max-width:820px){
  .dep2-grid{grid-template-columns:1fr}
  .dep-managed{grid-template-columns:1fr;gap:1.1rem;text-align:left}
}
/* ===== SOLUTIONS (homepage, leads the IA) ===== */
.sol-grid{margin-top:clamp(2.2rem,4vw,3rem);display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,1.8vw,1.4rem)}
.sol-card{display:flex;flex-direction:column;align-items:flex-start;gap:1rem;padding:clamp(1.6rem,2.4vw,2.1rem);
  background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);text-decoration:none;color:inherit;
  transition:border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease)}
.sol-card:hover{border-color:rgba(20,179,214,.45);box-shadow:0 30px 60px -34px rgba(14,17,22,.28);transform:translateY(-3px)}
.sol-ic{width:46px;height:46px;display:grid;place-items:center;border-radius:12px;background:rgba(20,179,214,.1);color:var(--cyan-deep)}
.sol-ic svg{width:24px;height:24px}
.sol-card h3{font-family:var(--font-display);font-weight:500;font-size:1.3rem;letter-spacing:-.02em;color:var(--ink);margin:0}
.sol-card p{font-size:.92rem;line-height:1.58;color:var(--slate);margin:0;flex:1}
.sol-go{font-family:var(--font-label);font-size:.82rem;font-weight:600;color:var(--cyan-deep);display:inline-flex;align-items:center;gap:.4rem}
.sol-go .ar{transition:transform .25s var(--ease)}
.sol-card:hover .sol-go .ar{transform:translateX(3px)}
.sol-foundation{margin-top:clamp(1rem,1.8vw,1.4rem);display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:clamp(1.2rem,3vw,2.4rem);padding:clamp(1.4rem,2.6vw,2rem) clamp(1.6rem,3vw,2.4rem);
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(118deg,rgba(20,179,214,.07),rgba(122,226,255,.03) 60%,rgba(255,255,255,0))}
.sol-f-ic{width:52px;height:52px;flex:none;display:grid;place-items:center;border-radius:13px;background:rgba(20,179,214,.12);color:var(--cyan-deep)}
.sol-f-ic svg{width:28px;height:28px}
.sol-f-copy h3{font-family:var(--font-display);font-weight:500;font-size:clamp(1.15rem,1.7vw,1.4rem);letter-spacing:-.02em;color:var(--ink);margin:.15rem 0 .3rem}
.sol-f-copy p{font-size:.92rem;line-height:1.55;color:var(--slate);margin:0;max-width:66ch}
@media(max-width:860px){.sol-grid{grid-template-columns:1fr}.sol-foundation{grid-template-columns:1fr;gap:1rem;text-align:left}}

/* ===== PLAYER PLUS standalone advert (dark band) ===== */
.pp-band{display:grid;grid-template-columns:1.05fr .95fr;align-items:center;gap:clamp(1.6rem,4vw,3.4rem);
  padding:clamp(2rem,4vw,3.4rem);border-radius:var(--r-lg);overflow:hidden;
  background:linear-gradient(135deg,#061c31 0%,#0a2c4c 55%,#0c3a63 100%);box-shadow:0 40px 80px -46px rgba(6,26,45,.8)}
.pp-copy .eyebrow{color:var(--steel)}
.pp-copy h2{font-family:var(--font-display);font-weight:500;font-size:clamp(1.8rem,3.4vw,2.7rem);letter-spacing:-.03em;line-height:1.02;margin:.6rem 0 .7rem;color:#fff}
.pp-copy p{font-size:1rem;line-height:1.6;color:rgba(255,255,255,.82);margin:0 0 1.4rem;max-width:52ch}
.pp-visual svg{width:100%;height:auto;display:block;filter:drop-shadow(0 30px 50px rgba(0,0,0,.5))}
@media(max-width:860px){.pp-band{grid-template-columns:1fr}.pp-visual{order:-1;max-width:420px}}/* ===== EXPLAINER VIDEO (homepage) ===== */
.head-2.center{text-align:center;max-width:none;margin-inline:auto}
/* frameless, full-bleed overview video with Player Plus chrome on hover */
.explainer-frame{position:relative;margin:clamp(1.8rem,3.5vw,3rem) 0 0;width:100%;
  border:0;border-radius:0;box-shadow:none;overflow:hidden;background:#04121f}
.explainer-frame video{width:100%;height:auto;display:block;aspect-ratio:16/9;object-fit:cover}
.expl-chrome{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:clamp(.7rem,1.4vw,1.1rem);
  padding:clamp(1rem,2.4vw,2rem) clamp(1.1rem,3vw,2.6rem);opacity:0;pointer-events:none;
  background:linear-gradient(to top,rgba(4,18,31,.74),rgba(4,18,31,.28) 46%,transparent);
  transition:opacity .32s var(--ease)}
.explainer-frame:hover .expl-chrome,.explainer-frame:focus-within .expl-chrome{opacity:1;pointer-events:auto}
.expl-btn{flex:none;display:grid;place-items:center;width:clamp(42px,4vw,52px);height:clamp(42px,4vw,52px);border-radius:50%;
  border:1px solid rgba(255,255,255,.28);background:rgba(255,255,255,.13);color:#fff;cursor:pointer;
  -webkit-backdrop-filter:blur(8px) saturate(140%);backdrop-filter:blur(8px) saturate(140%);
  transition:background .2s var(--ease),transform .2s var(--ease),border-color .2s var(--ease)}
.expl-btn:hover{background:rgba(255,255,255,.24);border-color:rgba(255,255,255,.5);transform:translateY(-1px)}
.expl-btn svg{width:46%;height:46%}
.expl-logo{display:inline-flex;align-items:center;gap:.55rem;color:#fff}
.expl-logo img{height:clamp(22px,2.4vw,30px);width:auto;display:block}
.expl-logo b{font-family:var(--font-display);font-weight:500;font-size:clamp(.98rem,1.4vw,1.2rem);letter-spacing:-.01em}
.expl-mute{margin-left:auto}
.expl-pause .i-play{display:none}.expl-pause.is-paused .i-pause{display:none}.expl-pause.is-paused .i-play{display:block}
.expl-mute .i-sound{display:none}.expl-mute.is-on .i-muted{display:none}.expl-mute.is-on .i-sound{display:block}
@media(prefers-reduced-motion:reduce){.expl-chrome{transition:none}}

/* ===== SCALE & CAPABILITY (homepage) ===== */
.scale-grid{margin-top:clamp(2rem,3.5vw,2.8rem);display:grid;grid-template-columns:repeat(4,1fr);gap:0;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.scale-stat{display:flex;flex-direction:column;gap:.5rem;padding:clamp(1.5rem,2.6vw,2.2rem);border-right:1px solid var(--line)}
.scale-stat:last-child{border-right:0}
.scale-v{font-family:var(--font-display);font-weight:500;font-size:clamp(1.6rem,2.9vw,2.4rem);letter-spacing:-.03em;color:var(--ink);line-height:1}
.scale-l{font-size:.85rem;line-height:1.4;color:var(--slate)}
@media(max-width:820px){.scale-grid{grid-template-columns:1fr 1fr}.scale-stat:nth-child(2){border-right:0}.scale-stat:nth-child(1),.scale-stat:nth-child(2){border-bottom:1px solid var(--line)}}/* ===== INNER PAGES — content kit ===== */
.page-head{padding-top:20px}
.crumbs{display:flex;align-items:center;gap:.5rem;font-family:var(--font-label);font-size:.8rem;color:var(--steel);margin-bottom:1.1rem}
.crumbs a{color:var(--slate);text-decoration:none}.crumbs a:hover{color:var(--cyan-deep)}
.crumb-sep{opacity:.5}
.page-head h1{font-family:var(--font-display);font-weight:600;font-size:clamp(2.4rem,5vw,3.9rem);letter-spacing:-.035em;line-height:1.02;margin:0}
.page-head .lead{margin-top:1.1rem;max-width:56ch;font-size:clamp(1.06rem,1.5vw,1.19rem);line-height:1.55}
.page-cta{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.8rem}
.slab{margin-top:clamp(1.6rem,3vw,2.4rem);display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));gap:clamp(.9rem,1.6vw,1.3rem)}
.slab-card{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:clamp(1.4rem,2.2vw,1.9rem);transition:border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease)}
.slab-card:hover{border-color:rgba(20,179,214,.35);box-shadow:0 24px 50px -34px rgba(14,17,22,.25);transform:translateY(-2px)}
.slab-card h3{font-family:var(--font-display);font-weight:500;font-size:1.2rem;letter-spacing:-.02em;color:var(--ink);margin:0 0 .5rem}
.slab-card h3 .textlink{font-size:1.2rem}
.slab-card>p{font-size:.92rem;line-height:1.55;color:var(--slate);margin:0}
.slab-card ul{list-style:none;margin:.3rem 0 0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.slab-card li{position:relative;padding-left:1.35rem;font-size:.9rem;line-height:1.45;color:var(--slate)}
.slab-card li::before{content:"";position:absolute;left:0;top:.42em;width:8px;height:8px;border-radius:2px;background:var(--cyan);box-shadow:0 0 8px rgba(20,179,214,.5)}

/* ---------- feature cards with an icon chip in the top-left (user-applications "Advanced TV") ---------- */
.slab-ico .sc-ic{width:42px;height:42px;border-radius:12px;display:grid;place-items:center;
  margin:0 0 clamp(.9rem,1.6vw,1.2rem);
  background:linear-gradient(152deg,rgba(20,179,214,.17),rgba(122,226,255,.05));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.85),0 0 0 1px rgba(20,179,214,.2);
  transition:transform .4s var(--spring)}
.slab-ico .sc-ic svg{width:21px;height:21px;fill:none;stroke:var(--cyan-deep);stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.slab-ico .slab-card:hover .sc-ic{transform:translateY(-1px) scale(1.06)}


/* ---------- pop map as an in-page panel (private-cdn, under "Three POP types") ---------- */
/* Full bleed. The map is a world map: held to the text column it reads as a
   diagram of somewhere, and edge to edge it reads as everywhere. Same escape
   the platform marquee uses — 100vw with a negative margin either side, in %
   rather than vw so a visible scrollbar cannot push it off-centre. */
.popmap-panel{margin-top:clamp(1.6rem,3vw,2.4rem);border-radius:0;overflow:hidden;position:relative;
  background:transparent;
  width:100vw;max-width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw)}
.popmap-panel .popmap-wrap{width:100%;max-width:100%;margin:0;height:clamp(440px,46vw,640px);overflow:hidden}
.section:has(.popmap-panel){overflow-x:clip}
.popmap-panel .popmap-frame{width:100%;height:100%}   /* the map composes to its own frame now — nothing to clip */
@media(max-width:640px){.popmap-panel .popmap-wrap{height:min(60vw,290px)}}

/* ---------- solution cards with illustration + Explore button (perception-stream "Three layers") ---------- */
.slab-sol .slab-card{display:flex;flex-direction:column;align-items:flex-start;text-align:left}
.slab-sol .slab-ill{width:100%;aspect-ratio:4/3;border-radius:14px;overflow:hidden;
  background:linear-gradient(160deg,rgba(20,179,214,.09),rgba(122,226,255,.02));
  display:grid;place-items:center;padding:clamp(.7rem,1.6vw,1.15rem);
  margin-bottom:clamp(1rem,1.8vw,1.35rem)}
.slab-sol .slab-ill img{max-width:100%;max-height:100%;object-fit:contain;display:block}
.slab-sol .slab-card p{margin:0 0 clamp(1rem,1.7vw,1.3rem)}
.slab-sol .slab-explore{margin-top:auto;display:inline-flex;align-items:center;gap:.45rem;
  padding:.52rem 1.05rem;border-radius:999px;border:1px solid var(--line);
  font-family:var(--font-body);font-weight:600;font-size:.85rem;color:var(--ink);
  transition:border-color .25s var(--ease),color .25s var(--ease),background .25s var(--ease)}
.slab-sol .slab-explore:hover{border-color:var(--cyan);color:var(--cyan-deep);background:rgba(20,179,214,.06)}
.slab-sol .slab-explore svg{width:15px;height:15px;transition:transform .25s var(--ease)}
.slab-sol .slab-explore:hover svg{transform:translateX(2px)}

/* ---------- Our Core → value cards (why-cloudworks #core only; own component, leaves shared .slab-card untouched) ---------- */
#core .corevals{margin-top:clamp(1.8rem,3.4vw,2.8rem);display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));gap:clamp(1rem,1.5vw,1.35rem)}
.coreval{position:relative;overflow:hidden;padding:clamp(1.5rem,2.3vw,2rem);border-radius:var(--r-lg);
  background:var(--glass);box-shadow:var(--glass-shadow);transition:transform .4s var(--ease),box-shadow .4s var(--ease)}
.coreval::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;background:var(--signal);
  transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease)}
.coreval:hover{transform:translateY(-5px);box-shadow:var(--shadow-lg)}
.coreval:hover::before{transform:scaleX(1)}
.coreval .cv-ico{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;
  background:linear-gradient(152deg,rgba(20,179,214,.17),rgba(122,226,255,.05));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.85),0 0 0 1px rgba(20,179,214,.2),0 12px 22px -16px rgba(20,179,214,.6);
  transition:transform .45s var(--spring)}
.coreval .cv-ico svg{width:23px;height:23px;fill:none;stroke:var(--cyan-deep);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.coreval:hover .cv-ico{transform:translateY(-1px) scale(1.06)}
.coreval h3{font-family:var(--font-display);font-weight:500;font-size:1.24rem;letter-spacing:-.02em;color:var(--ink);margin:clamp(1.1rem,2vw,1.45rem) 0 .5rem}
.coreval p{font-size:.94rem;line-height:1.58;color:var(--slate);margin:0}
.coreval[data-rise].in{animation:cvRise .7s var(--spring) backwards}
.coreval:nth-child(2)[data-rise].in{animation-delay:.09s}
.coreval:nth-child(3)[data-rise].in{animation-delay:.18s}
.coreval:nth-child(4)[data-rise].in{animation-delay:.27s}
@keyframes cvRise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.coreval[data-rise].in{animation:none}}
@media (max-width:560px){.coreval{padding:1.45rem}}
.feat-cols{margin-top:clamp(1.4rem,2.6vw,2rem);list-style:none;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:.85rem 2rem}
.feat-cols li{position:relative;padding-left:1.9rem;font-size:.98rem;line-height:1.5;color:var(--ink-2)}
.feat-cols li::before{content:"";position:absolute;left:0;top:.02em;width:20px;height:20px;border-radius:50%;background:rgba(20,179,214,.12) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%230E93B2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 5 5 9-11"/></svg>') center/12px no-repeat}
.plat-pills{margin-top:clamp(1.2rem,2.4vw,1.8rem);display:flex;flex-direction:column;gap:1rem}
.plat-row{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
.plat-k{font-family:var(--font-label);font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--steel);min-width:118px}
.plat-pill{display:inline-flex;align-items:center;gap:.45rem;padding:.4rem .9rem .4rem .7rem;border-radius:var(--pill);border:1px solid var(--line);background:#fff;font-size:.85rem;color:var(--ink)}
.plat-pill .pp-ic{width:44px;height:44px;flex:none;display:block}

/* ---------- platform marquee: one subtitle line + two rows scrolling opposite ways ---------- */
.plat-sub{margin:.9rem 0 0;font-family:var(--font-label);font-size:.78rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--steel)}
.plat-marquee{margin-top:clamp(1.6rem,3vw,2.4rem);display:flex;flex-direction:column;gap:0;
  width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.section:has(.plat-marquee){overflow-x:clip}
.pm-row{overflow:hidden;padding:9px 0}
.pm-track{display:flex;gap:.7rem;width:max-content;will-change:transform;backface-visibility:hidden;
  animation-timing-function:linear;animation-iteration-count:infinite;
  animation-duration:var(--pm-dur,71s)}
/* the repeat unit: one full run of the row's pills. Its gap matches the
   track's, so the strip reads as one even sequence and the pitch from a set to
   its clone is a constant. */
.pm-set{display:flex;gap:.7rem;flex:none}
/* Three rows, three speeds. The rates are deliberately not multiples of one
   another: rows that share a factor keep re-aligning, and the eye reads that
   as the whole block lurching rather than three tracks drifting.

   The travel is --pm-shift, a whole number of set pitches, and the duration
   --pm-dur is that distance at the row's own rate — both written by site.js,
   which also clones the set until one travel's worth of them covers the row.
   That is what keeps the ribbon endless: at the far end of the loop the strip
   still reaches past the far edge, and the frame it lands on is the frame it
   started from. Without the script the rows simply hold still.

   translate3d rather than translateX puts each track on its own compositor
   layer, which is what takes the stutter out on a long strip of text. */
.pm-a .pm-track{animation-name:pmLeft}
.pm-b .pm-track{animation-name:pmRight}
.pm-c .pm-track{animation-name:pmLeft}
@keyframes pmLeft {from{transform:translate3d(0,0,0)}
                     to{transform:translate3d(calc(var(--pm-shift,0px) * -1),0,0)}}
@keyframes pmRight{from{transform:translate3d(calc(var(--pm-shift,0px) * -1),0,0)}
                     to{transform:translate3d(0,0,0)}}
.pm-row:hover .pm-track{animation-play-state:paused}
/* the pill under the cursor: cyan hairline, tile shadow, a 2px lift */
.plat-marquee .plat-pill{transition:transform .3s var(--ease),box-shadow .3s var(--ease),
  border-color .3s var(--ease),background .3s var(--ease)}
.plat-marquee .plat-pill:hover{transform:translateY(-2px);
  border-color:color-mix(in srgb,var(--cyan) 46%,transparent);
  box-shadow:var(--tile-shadow),0 14px 28px -18px rgba(20,179,214,.45)}
/* the rest of the row recedes a little so the one you are on is the one you see */
.pm-row:hover .plat-pill{opacity:.55}
.pm-row:hover .plat-pill:hover{opacity:1}
@media(prefers-reduced-motion:reduce){.plat-marquee .plat-pill:hover{transform:none}}
.plat-marquee .plat-pill{padding:.55rem 1.15rem .55rem .9rem;font-size:.92rem;white-space:nowrap;
  box-shadow:none}
@media(prefers-reduced-motion:reduce){.pm-track{animation:none}}
/* brand colours apply to the MARK only — the label stays ink black */
.plat-pill>span{color:var(--ink)}
.pp--apple   .pp-ic{color:#0B0B0D}
.pp--android .pp-ic{color:#3DDC84}
.pp--windows .pp-ic{color:#0078D4}
.pp--linux   .pp-ic{color:#E9A100}
.pp--google  .pp-ic{color:#4285F4}
.pp--amazon  .pp-ic{color:#FF9900}
.pp--samsung .pp-ic{color:#1428A0}
.pp--web     .pp-ic{color:#14B3D6}
.pp--roku    .pp-ic{color:#6F1AB1}
.pp--lg      .pp-ic{color:#A50034}
.pp--hisense .pp-ic{color:#00A0E9}
.pp--cast    .pp-ic{color:#4285F4}
.pp--hbb     .pp-ic{color:#1E7BB8}
.stat-hi{margin-top:1.5rem;display:inline-flex;align-items:baseline;gap:.7rem;padding:.9rem 1.3rem;border-radius:var(--r-md);background:rgba(20,179,214,.08);border:1px solid rgba(20,179,214,.25)}
.stat-hi b{font-family:var(--font-display);font-weight:500;font-size:1.9rem;letter-spacing:-.02em;color:var(--cyan-deep);line-height:1}
.stat-hi span{font-size:.9rem;color:var(--slate);max-width:34ch}
.psec-tint{background:linear-gradient(180deg,rgba(20,179,214,.035),transparent 70%)}
@media(max-width:640px){.feat-cols{grid-template-columns:1fr}.plat-k{min-width:0;width:100%}}
/* ===== TEAM GRID + NEWS LIST (Why CloudWorks) ===== */
.team-grid{margin-top:clamp(1.6rem,3vw,2.4rem);display:grid;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));gap:clamp(1rem,1.8vw,1.4rem)}
/* photo fills the whole card; name/role sit on a scrim over it */
.team-card{position:relative;isolation:isolate;border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;aspect-ratio:3/4;display:flex;flex-direction:column;justify-content:flex-end;
  padding:1.35rem 1.4rem;background:var(--haze)}
.tm-av{position:absolute;inset:0;z-index:-2;display:block;margin:0;border-radius:0}
/* real team photos replace the initials */
.team-card::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(9,14,20,0) 38%,rgba(9,14,20,.36) 62%,rgba(9,14,20,.82) 100%)}
.tm-av img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;display:block;
  transition:transform .5s var(--ease)}
.team-card:hover .tm-av img{transform:scale(1.04)}
.team-card h4{font-family:var(--font-display);font-weight:500;font-size:1.24rem;color:#fff;margin:0;
  text-shadow:0 1px 10px rgba(0,0,0,.45)}
.tm-role{font-size:.92rem;color:var(--sky);margin:.15rem 0 .1rem;text-shadow:0 1px 8px rgba(0,0,0,.45)}
.tm-loc{display:flex;align-items:center;gap:.45rem;font-size:.82rem;color:rgba(255,255,255,.78);text-shadow:0 1px 8px rgba(0,0,0,.45)}
.tm-flag{width:17px;height:12px;flex:none;border-radius:2px;display:block;
  box-shadow:0 0 0 1px rgba(255,255,255,.4),0 1px 4px rgba(0,0,0,.4)}
.news-list{margin-top:clamp(1.6rem,3vw,2.4rem);display:flex;flex-direction:column;border-top:1px solid var(--line)}
.news-item{display:grid;grid-template-columns:110px 1fr;gap:1.4rem;align-items:baseline;padding:1.3rem 0;border-bottom:1px solid var(--line)}
.news-date{font-family:var(--font-label);font-size:.8rem;color:var(--steel);letter-spacing:.03em;text-transform:uppercase}
.news-item h4{font-family:var(--font-display);font-weight:500;font-size:1.05rem;line-height:1.38;color:var(--ink);margin:0;max-width:none}
@media(max-width:600px){.news-item{grid-template-columns:1fr;gap:.4rem}.news-date{order:-1}}
/* ===== CORPORATE — password wall + media/downloads ===== */
.corp-gate{position:fixed;inset:0;z-index:3000;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1.5rem;padding:2rem;background:linear-gradient(162deg,#02080f,#04121f 60%,#061c30)}
/* logo sits above the card, not inside it */
.corp-gate>.brand-logo{height:32px;width:auto;filter:brightness(0) invert(1);flex:none}
.corp-gate-box{width:min(420px,92vw);text-align:center;background:rgba(14,26,40,.6);border:1px solid rgba(255,255,255,.12);border-radius:var(--r-lg);padding:2.4rem 2rem;-webkit-backdrop-filter:blur(16px) saturate(1.2);backdrop-filter:blur(16px) saturate(1.2);box-shadow:0 40px 80px -40px rgba(0,0,0,.8)}

.corp-gate-box h2{font-family:var(--font-display);font-weight:500;color:#fff;font-size:1.5rem;letter-spacing:-.02em;margin:0 0 .5rem}
.corp-gate-box>p{color:rgba(255,255,255,.7);font-size:.9rem;margin:0 0 1.4rem}
.corp-gate-box form{display:flex;flex-direction:column;gap:.7rem}
.corp-gate-box input{padding:.8rem 1rem;border-radius:var(--r-md);border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.06);color:#fff;font-size:1rem}
.corp-gate-box input::placeholder{color:rgba(255,255,255,.45)}
.corp-gate-box input:focus{outline:2px solid var(--cyan);outline-offset:1px;border-color:transparent}
.corp-gate-box .btn{justify-content:center}
.corp-hint{margin-top:1.2rem !important;font-size:.8rem !important;color:rgba(255,255,255,.6) !important}
.corp-hint a{color:var(--sky)}
.corp-err{color:#ff9b9b;font-size:.85rem;margin:.7rem 0 0 !important}
.corp-err a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.corp-err code{font-size:.95em;opacity:.9}
body.corp-locked{overflow:hidden}
.media-grid{margin-top:clamp(1.6rem,3vw,2.4rem);display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:clamp(.9rem,1.6vw,1.3rem)}
.media-card{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:2rem 1.7rem;display:flex;flex-direction:column;gap:1.1rem;transition:border-color .25s var(--ease),box-shadow .25s var(--ease),transform .25s var(--ease)}
.media-card:hover{border-color:rgba(20,179,214,.35);box-shadow:0 24px 50px -34px rgba(14,17,22,.25);transform:translateY(-2px)}
.media-logo{height:32px;display:flex;align-items:center}
.media-logo img{height:100%;width:auto;max-width:180px;object-fit:contain}
.media-card p{font-size:.9rem;color:var(--slate);line-height:1.5;margin:0}
.dl-card{display:flex !important;flex-direction:column;position:relative;text-decoration:none;color:inherit}
.dl-card .dl-ar{position:absolute;top:1.3rem;right:1.4rem;color:var(--cyan-deep);font-size:1.1rem;opacity:.5;transition:opacity .2s,transform .2s}
.dl-card:hover .dl-ar{opacity:1;transform:translateY(2px)}
/* current-page indication in the shared nav */
.nav-trigger.is-current{color:var(--cyan-deep)}
body.dark-hero #header:not(.scrolled) .nav-trigger.is-current{color:var(--sky)}
.dd-link.is-current{background:var(--dd-cur)}
.dd-link.is-current .dd-tt{color:var(--dd-ink)}
.mn-link.is-current{color:var(--cyan-deep)}
/* ---- client logos lifted into the hero (white, over the globe horizon) ---- */
.hero-v2 .hero-trust{position:absolute;left:0;right:0;bottom:clamp(2.2rem,7vh,4.5rem);z-index:4;pointer-events:none;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 11%,#000 89%,transparent);mask-image:linear-gradient(90deg,transparent,#000 11%,#000 89%,transparent)}
.hero-v2 .hero-trust .wrap{max-width:none;padding-inline:0}
.hero-v2 .hero-trust .logo-img{filter:brightness(0) invert(1);opacity:.6}
/* Corporate gate: subtle "enter without password" link */
.corp-skip{margin-top:.9rem !important;font-size:.82rem !important}
.corp-skip a{color:rgba(255,255,255,.55);text-decoration:none;border-bottom:1px dashed rgba(255,255,255,.25);padding-bottom:1px;transition:color .2s,border-color .2s}
.corp-skip a:hover{color:#fff;border-color:rgba(255,255,255,.6)}
/* the box swaps between its two faces with [hidden], and the form's own
   display:flex would otherwise outrank the attribute */
.corp-gate-box [hidden]{display:none !important}
/* the gate's other face: why there is nothing to reset, and who to ask */
.corp-recover h3{font-family:var(--font-display);font-weight:500;color:#fff;font-size:1.15rem;
  letter-spacing:-.015em;margin:0 0 .6rem}
.corp-recover p{color:rgba(255,255,255,.7);font-size:.87rem;line-height:1.55;margin:0 0 1.3rem}
.corp-recover .btn{width:100%;justify-content:center}
.corp-recover .corp-skip{margin-top:1.1rem !important}
/* ---- header CTA: flat, white, thin arrow-in-circle, animated on hover ---- */
.nav-right .btn-primary{color:#04141a;font-weight:450;box-shadow:none;letter-spacing:.005em}
.nav-right .btn-primary:hover{background:#2bc0e0;transform:none}
.nav-right .btn-primary svg{width:12px;height:12px;padding:5.5px;box-sizing:content-box;
  background:rgba(255,255,255,.22);border-radius:50%;margin-left:.25rem;
  transition:transform .3s var(--ease),background .3s var(--ease)}
.nav-right .btn-primary svg path{stroke-width:1.7}
.nav-right .btn-primary:hover svg{transform:translateX(3px);background:rgba(255,255,255,.34)}
/* "Trusted by" label + label-aware masking for the hero logo strip */
.hero-v2 .hero-trust{-webkit-mask-image:none;mask-image:none}
.hero-v2 .hero-trust .wrap{padding-inline:clamp(1rem,4vw,3rem)}
.hero-v2 .hero-trust .trust-inner{display:flex;align-items:center;gap:clamp(1rem,2.5vw,2rem)}
.hero-v2 .hero-trust .marquee{flex:1 1 auto;min-width:0;-webkit-mask-image:linear-gradient(90deg,#000 0,#000 86%,transparent);mask-image:linear-gradient(90deg,#000 0,#000 86%,transparent)}
/* The strip is absolute so it can float over the globe's horizon. With the
   globe gone on a phone and the hero sized by its content, there is nothing
   left to float over — it landed on top of the CTA. It joins the flow instead. */
@media(max-width:760px){
  .hero-v2 .hero-trust{position:static;margin-top:clamp(1.5rem,4vh,2.2rem)}
}
/* ===== HEADER — floating pill, colour logo, no scroll-shrink ===== */
/* `body>header` for the same reason as the sticky rule above. */
body>header{background:transparent;border:none;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;padding:.5rem clamp(.75rem,2.4vw,1.5rem)}
header.scrolled{background:transparent;border:none;box-shadow:none}
.nav{height:auto;padding:.5rem .6rem .5rem 1.5rem;border-radius:var(--pill);
  background:rgba(255,255,255,.8);-webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);
  border:1px solid rgba(14,17,22,.08);box-shadow:0 12px 34px -22px rgba(14,17,22,.3);
  transition:background .35s var(--ease),box-shadow .35s var(--ease)}
header.scrolled .nav{height:auto;background:rgba(255,255,255,.92);box-shadow:0 16px 42px -24px rgba(14,17,22,.4)}
.brand-logo{height:47px;transition:none}
header.scrolled .brand-logo{height:47px}
/* colour logo + dark nav on the dark hero (pill is light on every page now) */
body.dark-hero #header:not(.scrolled) .brand-logo{filter:none}
body.dark-hero #header:not(.scrolled) .nav-trigger,
body.dark-hero #header:not(.scrolled) .nav-trigger .chev{color:var(--ink)}
body.dark-hero #header:not(.scrolled) .nav-trigger:hover{color:var(--cyan-deep)}
body.dark-hero #header:not(.scrolled) .nav-trigger.is-current{color:var(--cyan-deep)}
body.dark-hero #header:not(.scrolled) .nav-trigger{text-shadow:none}
body.dark-hero #header:not(.scrolled) .burger{color:var(--ink)}
/* ---- pill appears ONLY on scroll; at the top the header is transparent ---- */
.nav{background:transparent;border-color:transparent;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
header.scrolled .nav{background:rgba(255,255,255,.9);-webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);border-color:rgba(14,17,22,.08);box-shadow:0 16px 42px -24px rgba(14,17,22,.4)}
.brand-logo{transition:filter .35s var(--ease)}
/* dark hero, at the top (no pill): white logo + white nav */
body.dark-hero #header:not(.scrolled) .brand-logo{filter:brightness(0) invert(1)}
body.dark-hero #header:not(.scrolled) .nav-trigger,
body.dark-hero #header:not(.scrolled) .nav-trigger .chev{color:#fff}
body.dark-hero #header:not(.scrolled) .nav-trigger:hover{color:var(--sky)}
body.dark-hero #header:not(.scrolled) .nav-trigger.is-current{color:var(--sky)}
body.dark-hero #header:not(.scrolled) .nav-trigger{text-shadow:0 1px 12px rgba(0,0,0,.45)}
body.dark-hero #header:not(.scrolled) .burger{color:#fff}
.nav{transition:background .35s var(--ease),box-shadow .35s var(--ease),border-color .35s var(--ease),-webkit-backdrop-filter .35s var(--ease),backdrop-filter .35s var(--ease)}

/* Scrolled header: split the backing into separate pill islands so the nav + CTA pills stay
   compact, independent of the (large) logo's height. Gaps between pills reveal the page behind. */
header.scrolled .nav{background:transparent;border-color:transparent;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;gap:clamp(.5rem,1vw,.9rem)}
header.scrolled .brand,
header.scrolled .nav-main{
  background:rgba(255,255,255,.92);
  -webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);
  border:1px solid rgba(14,17,22,.08);
  box-shadow:0 16px 42px -24px rgba(14,17,22,.4);
  border-radius:var(--pill)}
header.scrolled .brand{padding:5px 18px 5px 8px}
/* The nav and the CTA are two pills sitting side by side, so they have to be
   the same pill: same height, same vertical centre. They live in different
   containers (.nav-main vs .nav-right), so nothing makes them agree on their
   own — the CTA was 38px against the nav's 47 and sat 4px low. One shared
   height on both, and the row centres them together. */
header.scrolled .nav-main,
header.scrolled .nav-right .btn-primary{min-height:47px;box-sizing:border-box}
header.scrolled .nav-right .btn-primary{display:inline-flex;align-items:center}
header.scrolled .nav-main{padding:.3rem .45rem}
.brand,.nav-main{transition:background .32s var(--ease),box-shadow .32s var(--ease),border-color .32s var(--ease),padding .32s var(--ease)}

/* rounded bottom corners on the hero */
.hero-v2{border-bottom-left-radius:60px;border-bottom-right-radius:60px;overflow:hidden}
/* real Player Plus player in the homepage advert (crossfade like the landing) */
.pp-visual{position:relative}
.pp-shot{width:100%;height:auto;display:block;border-radius:14px;border:1px solid rgba(122,226,255,.18);box-shadow:0 30px 60px -28px rgba(0,0,0,.72)}
.pp-shot.b{position:absolute;inset:0;animation:ppCross 9s ease-in-out infinite}
@keyframes ppCross{0%,42%{opacity:0}50%,92%{opacity:1}100%{opacity:0}}
@media(prefers-reduced-motion:reduce){.pp-shot.b{animation:none;opacity:0}}
/* ===== PLAYER PLUS advert v2 — white, big centred player, floating badges, Möbius screen ribbon ===== */
.pp-advert{background:transparent}
.pp-stage{position:relative;margin:clamp(2rem,4vw,3.4rem) auto 0;width:100%;max-width:940px;min-height:clamp(320px,42vw,520px);display:grid;place-items:center;isolation:isolate}
.pp-player{position:relative;z-index:2;width:min(680px,90%);border-radius:16px;overflow:hidden;border:1px solid rgba(14,17,22,.1);box-shadow:0 50px 90px -40px rgba(14,17,22,.45),0 0 0 1px rgba(255,255,255,.6)}
.pp-player .pp-shot{width:100%;height:auto;display:block;border:0;border-radius:0;box-shadow:none}
.pp-player .pp-shot.b{position:absolute;inset:0;animation:ppCross 9s ease-in-out infinite}
.pp-badge{position:absolute;z-index:3;display:inline-flex;align-items:center;gap:.34rem;padding:.5rem .9rem;border-radius:999px;font-family:var(--font-label);font-size:.8rem;color:var(--slate);white-space:nowrap;background:rgba(255,255,255,.92);border:1px solid var(--line);box-shadow:0 14px 32px -16px rgba(14,17,22,.35);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);animation:ppFloat 6s ease-in-out infinite}
.pp-badge b{color:var(--ink);font-weight:600}
.pp-b1{top:5%;left:2%;animation-delay:0s}
.pp-b2{top:0;right:7%;animation-delay:-1.3s}
.pp-b3{top:45%;right:-1%;animation-delay:-2.5s}
.pp-b4{bottom:10%;left:0;animation-delay:-3.2s}
.pp-b5{bottom:2%;right:17%;animation-delay:-1.8s}
@keyframes ppFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
.pp-ribbon{position:absolute;inset:-12% -14%;z-index:0;overflow:hidden;perspective:1200px;pointer-events:none;opacity:.5;-webkit-mask-image:radial-gradient(72% 84% at 50% 50%,transparent 24%,#000 66%);mask-image:radial-gradient(72% 84% at 50% 50%,transparent 24%,#000 66%)}
.pp-ribbon-track{position:absolute;top:50%;left:0;display:flex;gap:20px;width:max-content;transform:translateY(-50%) rotate(-9deg);transform-style:preserve-3d;animation:ppRibbon 46s linear infinite}
@keyframes ppRibbon{from{transform:translateY(-50%) rotate(-9deg) translateX(0)}to{transform:translateY(-50%) rotate(-9deg) translateX(-50%)}}
.pp-rib{flex:none;width:146px;height:92px;border-radius:10px;overflow:hidden;transform-style:preserve-3d;box-shadow:0 12px 26px -12px rgba(14,17,22,.42);animation:ppTwist 7s ease-in-out infinite;animation-delay:calc(var(--i) * -.55s)}
@keyframes ppTwist{0%,100%{transform:rotateY(0) rotateX(0)}50%{transform:rotateY(180deg) rotateX(16deg)}}
.pp-rib img{width:100%;height:100%;object-fit:cover;display:block}
.pp-cta{margin-top:clamp(1.6rem,3vw,2.4rem);text-align:center}
@media(prefers-reduced-motion:reduce){.pp-badge,.pp-ribbon-track,.pp-rib,.pp-player .pp-shot.b{animation:none}.pp-ribbon{opacity:.28}}
@media(max-width:720px){.pp-badge{font-size:.72rem;padding:.4rem .7rem}.pp-b3{right:-3%}.pp-stage{min-height:340px}}
/* badges: icons + a touch taller; ribbon as a band under the player */
.pp-badge{padding:.62rem 1rem;font-size:.82rem;gap:.5rem;line-height:1}
.pp-b-ic{width:16px;height:16px;flex:none;color:var(--cyan-deep)}
.pp-ribbon{top:auto;bottom:-6%;left:-16%;right:-16%;height:54%;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent)}
/* ribbon: full-viewport-width band running through the middle of the player */
.pp-ribbon{position:absolute;left:50%;top:54%;right:auto;bottom:auto;transform:translate(-50%,-50%);width:100vw;height:clamp(170px,24vw,300px);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.pp-ribbon-track{transform:translateY(-50%) rotate(-7deg)}
@keyframes ppRibbon{from{transform:translateY(-50%) rotate(-7deg) translateX(0)}to{transform:translateY(-50%) rotate(-7deg) translateX(-50%)}}
/* centered head: keep the lead block centered too (it carries its own max-width) */
.head-2.center .lead{margin-left:auto;margin-right:auto}
/* on-page nav: drop the glass/cyan pill backgrounds — just dots + labels */
.onpage:hover .op-link,.onpage:hover .op-link.is-here{background:transparent;border-color:transparent;
  box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
/* tilt the whole band uniformly (not the long track) so tiles fill the full width evenly */
.pp-ribbon{transform:translate(-50%,-50%) rotate(-7deg)}
.pp-ribbon-track{transform:translateY(-50%)}
@keyframes ppRibbon{from{transform:translateY(-50%) translateX(0)}to{transform:translateY(-50%) translateX(-50%)}}
/* ===== Scale & Capability — two-col text + staggered bordered-card cluster ===== */
/* the illustration column carries four objects and their labels; the copy is
   three short paragraphs, so the row is split in the drawing's favour */
.scale-wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.18fr);gap:clamp(2rem,5vw,4.5rem);align-items:center}
.scale-wrap .head-2{max-width:none}
.scale-cluster{display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,1.5vw,20px);align-items:start}
.sc-col{display:flex;flex-direction:column;gap:clamp(14px,1.5vw,20px)}
.sc-col-b{margin-top:clamp(30px,5.5vw,68px)}          /* stagger the right column down, like the sketch */
.sc-card{display:flex;flex-direction:column;gap:.55rem;padding:clamp(1.3rem,2.1vw,1.9rem);
  min-height:clamp(172px,18vw,200px);border:1px solid var(--line);border-radius:var(--r-lg);background:#fff}
.sc-v{font-family:var(--font-display);font-weight:500;font-size:clamp(1.55rem,2.7vw,2.25rem);letter-spacing:-.03em;color:var(--ink);line-height:1}
.sc-l{font-size:.85rem;line-height:1.42;color:var(--slate)}
/* each scale card takes its own colour: deep ink, sky blue and grey */
.sc-card{border-color:transparent}
.sc-1{background:#1D242B}
.sc-1 .sc-v{color:#fff}
.sc-1 .sc-l{color:rgba(255,255,255,.66)}
.sc-2{background:#8FD5E8}
.sc-2 .sc-v{color:#0E1116}
.sc-2 .sc-l{color:rgba(14,17,22,.66)}
.sc-3{background:#DCE2E7}
.sc-3 .sc-v{color:#0E1116}
.sc-3 .sc-l{color:rgba(14,17,22,.62)}
.sc-hero.sc-4{background:#6FC7DF;border-color:transparent}
.sc-hero.sc-4 .sc-v{color:#0E1116;font-size:clamp(1.55rem,2.7vw,2.25rem)}
.sc-hero.sc-4 .sc-l{color:rgba(14,17,22,.68)}
/* scroll reveal — clean rise + fade (staggered via .d1/.d2/.d3) */
.sc-card[data-rise]{opacity:0;transform:translateY(30px);transition:opacity .7s var(--spring),transform .8s var(--spring)}
.sc-card[data-rise].in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.sc-card[data-rise]{opacity:1;transform:none}}
/* responsive: single column, no stagger */
@media(max-width:900px){
  .scale-wrap{grid-template-columns:1fr;gap:2.2rem}
  .sc-col-b{margin-top:0}
}
@media(max-width:540px){
  .scale-cluster{grid-template-columns:1fr;gap:14px}
  .sc-col-b{margin-top:0}
  .sc-card{min-height:0}
}
/* ===== Solutions — compact teasers (previews of the detailed sections further down) ===== */
.sol-core{margin-top:clamp(1.6rem,2.6vw,2.2rem);position:relative}
.sol-core-items{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.5rem,.85vw,.7rem)}
.sol-t{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:.55rem;padding:clamp(1.4rem,2.4vw,2rem);
  border:0;border-radius:var(--r-lg);background:var(--glass-2);text-decoration:none;color:inherit;overflow:hidden;
  -webkit-backdrop-filter:blur(18px) saturate(150%);backdrop-filter:blur(18px) saturate(150%);
  transition:transform .3s var(--spring),box-shadow .3s var(--ease)}
.sol-t:hover{transform:translateY(-5px);box-shadow:inset 0 0 0 1px rgba(20,179,214,.4)}
.sol-t-ic{flex:none;width:80px;height:auto;display:block;color:var(--cyan)}
.sol-t-ic svg{width:80px;height:auto;display:block}
.sol-t-ic .sol-ill{filter:url(#ai-grain)}
.sol-t-t{min-width:0;font-size:.92rem;line-height:1.55;color:var(--slate);max-width:32ch}
.sol-t-t b{display:block;margin-bottom:.45rem;font-size:1.24rem;color:var(--ink);font-weight:500;font-family:var(--font-display);letter-spacing:-.02em}
.sol-t-go{margin-top:auto;display:inline-flex;align-items:center;gap:.35rem;font-family:var(--font-label);font-size:.78rem;font-weight:600;color:var(--cyan-deep);white-space:nowrap}
.sol-t-go .ar{transition:transform .22s var(--ease)}
.sol-t:hover .sol-t-go .ar{transform:translateX(3px)}
@media(max-width:720px){.sol-core-items{grid-template-columns:1fr}}
/* Private CDN — the core the three share, with live connections flowing up into each solution */
.sol-connect{position:relative;height:clamp(56px,7vw,96px);margin:.3rem 0 -.3rem;pointer-events:none}
.sol-connect svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;display:block}
.sol-connect .sc-line{fill:none;stroke:var(--cyan);stroke-width:1.4;opacity:.2;vector-effect:non-scaling-stroke;stroke-linecap:round}
.sol-connect .sc-flow{fill:none;stroke-width:2.6;vector-effect:non-scaling-stroke;stroke-linecap:round;stroke-dasharray:.16 .84;filter:drop-shadow(0 0 4px rgba(34,195,230,.7));animation:scFlow 3.4s linear infinite}
.sol-connect .sc-flow.f1{animation-delay:-.3s}
.sol-connect .sc-flow.f2{animation-delay:-1.4s}
.sol-connect .sc-flow.f3{animation-delay:-2.5s}
@keyframes scFlow{to{stroke-dashoffset:-1}}
@media(max-width:720px){.sol-connect{display:none}}
.sol-core-foot{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;
  margin-top:0;padding:clamp(.4rem,.8vw,.7rem) 1rem clamp(.4rem,.7vw,.6rem);
  text-decoration:none;color:inherit;position:relative}
.sol-cdn-badge{position:relative;width:clamp(74px,9vw,104px);height:clamp(74px,9vw,104px);display:grid;place-items:center;color:var(--cyan);margin-bottom:.15rem}
.sol-cdn-badge .sol-ill{width:100%;height:100%;filter:url(#ai-grain)}
.sol-cdn-badge::before{content:"";position:absolute;inset:-16%;border-radius:50%;
  background:radial-gradient(circle,rgba(20,179,214,.2),transparent 66%);animation:cdnPulse 3.6s ease-in-out infinite}
@keyframes cdnPulse{0%,100%{transform:scale(.88);opacity:.55}50%{transform:scale(1.12);opacity:1}}
.sol-cdn-title{font-family:var(--font-display);font-size:clamp(1.15rem,1.7vw,1.45rem);color:var(--ink);font-weight:500;letter-spacing:-.02em}
.sol-cdn-title b{color:var(--cyan-deep);font-weight:600}
.sol-cdn-t{max-width:52ch;font-size:.9rem;line-height:1.55;color:var(--slate)}
.sol-cdn-go{margin-top:.15rem;display:inline-flex;align-items:center;gap:.35rem;font-family:var(--font-label);font-size:.82rem;font-weight:600;color:var(--cyan-deep)}
.sol-cdn-go .ar{transition:transform .22s var(--ease)}
.sol-core-foot:hover .sol-cdn-go .ar{transform:translateX(3px)}
.sol-core-foot:hover .sol-cdn-badge::before{animation-duration:1.9s}
@media(prefers-reduced-motion:reduce){.sol-connect .sc-flow,.sol-cdn-badge::before{animation:none}}
/* Perception Stream vector mark (replaces the render), reusing the glint */
.stream .stream-mark{position:absolute;right:clamp(-18px,1vw,22px);top:50%;transform:translateY(-50%);
  width:clamp(184px,21.6vw,320px);height:auto;pointer-events:none}
.stream-mark > path,.stream-mark > ellipse,.stream-mark > circle{opacity:.5}
.stream-mark .mk-glint{opacity:1}
.stream-mark .mk-glint path{stroke-width:1.4}
@media(max-width:1040px){.stream .stream-mark{position:static;transform:none;margin:1.75rem auto 0;width:min(224px,48%)}}
/* PAI product feature tags (Perception AI page — echoes the paicloud.ai product cards) */
.prods-ai .prod-tags{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:1rem;max-width:min(46ch,calc(100% - clamp(120px,15vw,190px)))}
.prods-ai .prod-tags span{font-family:var(--font-label);font-size:.68rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;
  color:rgba(255,255,255,.72);background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);border-radius:7px;padding:.32rem .58rem}
/* ===== Perception AI page — detailed product sections (echoes paicloud.ai) ===== */
.pai-list{margin-top:clamp(2.5rem,5vw,4rem);display:flex;flex-direction:column;gap:clamp(3.5rem,8vw,7rem)}
.pd-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4.5rem);align-items:center}
.pd-item.rev .pd-visual{order:-1}
.pd-logo img{height:30px;width:auto;display:block;margin-bottom:1.1rem}
.pd-eyebrow{display:inline-block;font-family:var(--font-label);font-size:.72rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--pc);margin-bottom:.7rem}
.pd-copy h2{font-family:var(--font-display);font-weight:500;font-size:clamp(1.8rem,3.4vw,2.7rem);letter-spacing:-.03em;line-height:1.06;color:#fff;margin:0 0 1rem}
.pd-copy>p{font-size:clamp(1rem,1.3vw,1.12rem);line-height:1.62;color:rgba(255,255,255,.7);margin:0 0 1.5rem;max-width:52ch}
.pd-feat{list-style:none;margin:0 0 1.9rem;padding:0;display:flex;flex-direction:column;gap:.72rem}
.pd-feat li{position:relative;padding-left:2rem;font-size:.98rem;line-height:1.45;color:rgba(255,255,255,.86)}
.pd-feat li::before{content:"";position:absolute;left:0;top:0;width:21px;height:21px;border-radius:50%;
  background:color-mix(in srgb,var(--pc) 26%,transparent);
  background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 5 5 9-11"/></svg>');
  background-size:12px;background-position:center;background-repeat:no-repeat}
.pd-item .pfm-link{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.34);box-shadow:none}
.pd-item .pfm-link:hover{background:rgba(255,255,255,.08);border-color:var(--pc);transform:translateY(-1px)}
.pd-panel{position:relative;border-radius:24px;overflow:hidden;padding:clamp(1.6rem,3vw,2.6rem);min-height:clamp(250px,30vw,360px);display:grid;place-items:center;
  background:rgba(19,24,32,.82);box-shadow:inset 0 0 0 1px rgba(255,255,255,.09)}
.pd-panel::before{content:"";position:absolute;inset:0;background:radial-gradient(78% 90% at 68% 12%,color-mix(in srgb,var(--pc) 34%,transparent),transparent 62%);pointer-events:none}
.pd-panel .prod-ill{position:static;right:auto;bottom:auto;transform:none;width:min(380px,92%);height:auto;opacity:1;color:var(--pc);filter:url(#ai-grain)}
@media(max-width:860px){.pd-grid{grid-template-columns:1fr;gap:1.8rem}.pd-item.rev .pd-visual{order:0}.pd-panel{min-height:0}}


/* ===== Solutions illustrated scene (replaces the CSS schema) ===== */
.sol-scene{position:relative;margin-top:clamp(1.4rem,2.4vw,2rem);isolation:isolate}
.sol-scene-svg{width:100%;height:auto;display:block;overflow:visible}
/* the plate marking and the pad indices, set in the site's mono */
.sol-mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-size:13px;
  letter-spacing:.12em;fill:var(--ink);fill-opacity:.42}
.sol-scene::after{content:none;position:absolute;left:0;right:0;bottom:-1px;height:34%;z-index:3;pointer-events:none;
  background:linear-gradient(to top,#fff 9%,rgba(255,255,255,.6) 46%,transparent)}
.sol-net{position:absolute;inset:0;width:100%;height:100%;overflow:visible;z-index:2;pointer-events:none}
.sol-net .nf{fill:none;stroke:#1FB7DE;stroke-width:4;stroke-linecap:round;animation:solNf 3.2s linear infinite}
@keyframes solNf{to{stroke-dashoffset:-1}}
/* comet pulse: 3 stacked layers per line — short bright head, longer fading tail,
   so each travelling strip is a gradient from full colour to transparent, not a solid band */
.sol-net .pl1{stroke-dasharray:.02 .98}
.sol-net .pl2{stroke-dasharray:.05 .95;opacity:.5}
.sol-net .pl3{stroke-dasharray:.11 .89;opacity:.2}
.sol-net .nf.pl1{filter:drop-shadow(0 0 5px rgba(31,183,222,.9))}
.sol-net .nf.pl2{filter:drop-shadow(0 0 3px rgba(31,183,222,.5))}
.sol-net .nm.pl1{filter:drop-shadow(0 0 4px rgba(63,192,228,.85))}
.sol-net .nm.pl2{filter:drop-shadow(0 0 3px rgba(63,192,228,.5))}
.sol-lbl{position:absolute;z-index:4;display:flex;flex-direction:column;gap:.12rem;width:min(20%,225px);
  padding:.68rem .8rem;border-radius:15px;text-decoration:none;color:inherit;
  background:rgba(255,255,255,.7);border:1px solid rgba(20,179,214,.16);
  -webkit-backdrop-filter:blur(11px) saturate(1.4);backdrop-filter:blur(11px) saturate(1.4);
  box-shadow:0 18px 40px -22px rgba(14,17,22,.42);
  transition:transform .28s var(--spring),box-shadow .28s var(--ease),border-color .28s var(--ease)}
.sol-lbl:hover{transform:translateY(-4px);border-color:rgba(20,179,214,.5);box-shadow:0 26px 52px -22px rgba(14,17,22,.52)}
.sol-lbl b{font-family:var(--font-display);font-size:clamp(.95rem,1.15vw,1.12rem);font-weight:500;letter-spacing:-.02em;color:var(--ink)}
.sol-lbl span{font-size:.77rem;line-height:1.4;color:var(--slate)}
.sol-lbl em{margin-top:.22rem;font-style:normal;font-family:var(--font-label);font-size:.73rem;font-weight:600;color:var(--cyan-deep)}
/* the cards straddle the front edge of their plinth and sit over the mesh —
   that overlap is what makes their glass read as glass */
.sol-lbl.vs{left:9%;top:60%}
.sol-lbl.ua{left:40%;top:60%}
.sol-lbl.ai{left:71%;top:60%}
/* the pull-up was tuned against the old raster, which had ~90px of empty
   frame under its subject. The drawing is cropped to its content, so there is
   nothing left to pull into — a negative margin now lands this on the cards. */
.sol-cdn-cap{position:relative;z-index:4;margin:clamp(1rem,2vw,1.6rem) auto 0;
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;
  max-width:min(560px,90%);text-decoration:none;color:var(--slate);background:none}
.sol-cdn-cap b{font-family:var(--font-display);font-size:clamp(1.2rem,1.9vw,1.65rem);font-weight:600;letter-spacing:-.02em;color:var(--ink)}
.sol-cdn-cap>span{font-size:clamp(.86rem,1vw,.98rem);line-height:1.5;color:var(--slate);max-width:46ch}
.sol-cdn-cap em{margin-top:.25rem;font-style:normal;display:inline-flex;align-items:center;gap:.42rem;
  padding:.5rem 1.2rem;border-radius:var(--pill);font-family:var(--font-label);font-size:.82rem;font-weight:600;
  color:var(--cyan-deep);background:transparent;border:1.5px solid rgba(20,179,214,.55);
  transition:background .25s var(--ease),border-color .25s var(--ease)}
.sol-cdn-cap em .ar{transition:transform .22s var(--ease)}
.sol-cdn-cap:hover em{background:rgba(20,179,214,.1);border-color:var(--cyan)}
.sol-cdn-cap:hover em .ar{transform:translateX(3px)}
@media(prefers-reduced-motion:reduce){.sol-net .nf,.sol-cdn-dot{animation:none}.sol-net .nf{opacity:.35}}
@media(max-width:760px){
  /* a 1160-unit drawing renders at 0.29x in a phone column, which leaves the
     objects at ~26px — unreadable. Drop the drawing and let the three link
     cards, which go static just below, carry the section on their own. */
  .sol-scene-svg{display:none}
  .sol-scene::after{display:none}
  .sol-lbl,.sol-cdn-cap{position:static;transform:none;width:auto;max-width:none;margin:.55rem 0 0;flex-direction:column;align-items:flex-start}
}

.sol-net .nm{fill:none;stroke:#3FC0E4;stroke-width:3.4;stroke-linecap:round;animation:solNf 3.6s linear infinite}
.sol-net .nm.long{stroke-width:3;animation-duration:6s}
@media(prefers-reduced-motion:reduce){.sol-net .nm{animation:none;opacity:0}}

.sol-float{position:absolute;z-index:2;pointer-events:none;height:auto;will-change:transform;animation-name:solFloat;animation-timing-function:ease-in-out;animation-iteration-count:infinite}
@keyframes solFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(calc(var(--amp,7px)*-1))}}
@media(max-width:760px){.sol-float{display:none}}
@media(prefers-reduced-motion:reduce){.sol-float{animation:none}}

/* Perception Stream — floating solution icons around the mark */
.stream-float{position:absolute;z-index:1;pointer-events:none;height:auto;will-change:transform;filter:drop-shadow(0 8px 14px rgba(20,40,80,.1));animation-name:solFloat;animation-timing-function:ease-in-out;animation-iteration-count:infinite}
@media(max-width:1040px){.stream-float{display:none}}
@media(prefers-reduced-motion:reduce){.stream-float{animation:none}}

/* 3-product PAI grid: featured Chat spans full width, other two share the row */
.prods-ai .prod.wide{grid-column:1 / -1}
@media(max-width:760px){.prods-ai .prod.wide{grid-column:auto}}

/* PAI products: one card per row */
.prods-ai{grid-template-columns:1fr}

/* Dark-hero header logo: keep brand-cyan icon, white wordmark (hero variant) instead of an all-white filter */
.brand-logo-hero{display:none}
body.dark-hero #header:not(.scrolled) .brand-logo-light{display:none}
body.dark-hero #header:not(.scrolled) .brand-logo-hero{display:block;filter:none}

.brand .brand-logo-hero{display:none}

/* device mockups: crisp (no grain), keep product-accent tint */
.prods-ai .prod-ill.dev-shot{filter:none}

/* full-bleed dashboard photo instead of the vector mockup — spans the whole card height, cropped by the rounded card edges */
.prods-ai .prod:has(.prod-photo){overflow:hidden}
/* NOTE: selector must out-specify `.prods-ai .prod img:not(.prod-ill){height:45px}` (the logo sizing),
   so the photo keeps its own full-height sizing — hence `.prod-ill.prod-photo`. */
.prods-ai .prod-ill.prod-photo{
  position:absolute;top:0;right:0;bottom:0;left:auto;
  width:clamp(400px,54%,640px);height:100%;margin:0;
  object-fit:cover;object-position:50% 50%;
  /* images are pre-exposed (gamma-lifted) so they read on the dark card; keep only a gentle polish */
  filter:brightness(1.05) saturate(1.05);opacity:1;pointer-events:none;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 18%);
          mask-image:linear-gradient(90deg,transparent 0,#000 18%)}
.prods-ai .prod:hover .prod-ill.prod-photo{opacity:1;transform:none}
/* keep the copy clear of the photo on these cards */
.prods-ai .prod:has(.prod-photo) .prod-t,
.prods-ai .prod:has(.prod-photo) .prod-d{max-width:min(44ch,calc(100% - clamp(400px,52vw,620px)))}
@media(max-width:640px){
  /* Stacked under the copy, the photo takes the CARD's width, not the content
     width: the card pads 1.3/1.4rem, so the picture cancels that on three
     sides and the rounded corners crop it — the same treatment the
     side-by-side version gets on desktop. The fade moves with it, top instead
     of left, because the photo now meets the text above it, not beside it. */
  .prods-ai .prod-ill.prod-photo{position:relative;top:auto;right:auto;bottom:auto;left:auto;
    /* max-width:none or the site-wide img clamp pulls it back to the content box */
    width:calc(100% + 2.8rem);max-width:none;height:auto;margin:1.1rem -1.4rem -1.3rem;object-fit:contain;
    -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 30%);
            mask-image:linear-gradient(180deg,transparent 0,#000 30%)}
  .prods-ai .prod:has(.prod-photo) .prod-t,.prods-ai .prod:has(.prod-photo) .prod-d{max-width:none}
}

/* ============ Perception Stream layer cards: taller + one brand-book family per card ============ */
/* The brand book's chromatic set is Cyan · Sky · Lavender (+ Ink). Its usage rule: cyan is the
   signal (mark, key actions, emphasis); sky & lavender are SUPPORT — tints, gradients, quiet
   backgrounds, never primary type. So each card takes one family, shown as a quiet tint wash +
   a tinted icon badge, while cyan stays the signal for the kicker, chip icons and CTA. Every
   value below is a ramp step straight from the brand book. */
.stream .layer{min-height:clamp(400px,33vw,450px);align-items:center;--sig:#0C7C95}
.stream .layer:nth-child(1){--lw:rgba(20,179,214,.15);--badge:#E9F6FA;--ring:#A8E0EE;--glyph:#0C7C95}   /* Cyan     */
.stream .layer:nth-child(2){--lw:rgba(122,226,255,.24);--badge:#EAFAFF;--ring:#9CEAFF;--glyph:#4FC3E6}  /* Sky      */
.stream .layer:nth-child(3){--lw:rgba(169,196,240,.26);--badge:#F3F7FE;--ring:#C8DCFB;--glyph:#8AAAE0}  /* Lavender */
/* quiet corner wash in the card's own family tint, over the neutral glass */
/* each layer keeps the same blurred mesh + corner wash — only the base colour changes */
.stream .layer{background:
  radial-gradient(150% 140% at 100% 0%, var(--lw), transparent 58%),
  var(--base,rgba(240,244,251,.82))}
.stream .layer:nth-child(1){--base:#1D242B}
.stream .layer:nth-child(2){--base:#8FD5E8}
.stream .layer:nth-child(3){--base:#DCE2E7}
/* card 1 is dark, so its type and chrome flip to light (legibility, not restyling) */
.stream .layer:nth-child(1)::after{opacity:.26}
.stream .layer:nth-child(1) h3{color:#fff}
.stream .layer:nth-child(1) .layer-main p{color:rgba(255,255,255,.72)}
.stream .layer:nth-child(1) .lay{color:#7AE2FF}
.stream .layer:nth-child(1) .chip{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.22);color:rgba(255,255,255,.9)}
.stream .layer:nth-child(1) .chip-ic{color:#7AE2FF}
.stream .layer:nth-child(1) .layer-main .textlink.cy{color:#7AE2FF}
.stream .layer:nth-child(1) .layer-main .textlink.cy:hover{color:#fff}
.stream .layer:nth-child(1) .layer-ic{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.24);color:#7AE2FF}
.stream .layer:nth-child(1) .layer-ix .depth i{background:rgba(255,255,255,.22)}
.stream .layer:nth-child(1) .layer-ix .depth i.on{background:#7AE2FF}
/* the shared cyan mesh, harmonised per family: sky = airier, lavender = shifted to periwinkle */
.stream .layer:nth-child(2)::after{filter:brightness(1.07) saturate(.9)}
.stream .layer:nth-child(3)::after{filter:hue-rotate(32deg) saturate(.8) brightness(1.05)}
/* the signal — cyan — is consistent across all three cards */
.stream .lay{color:var(--sig)}
.stream .layer-ix .depth i.on{background:var(--sig)}
.stream .chip-ic{color:var(--cyan)}
.stream .layer-main .textlink.cy{color:var(--sig)}
.stream .layer-main .textlink.cy:hover{color:var(--ink)}
.stream .layer:hover .layer-ix .depth i.on{box-shadow:0 0 8px -1px var(--cyan)}
/* the family colour lives in the icon badge (pale fill · mid ring · deep glyph) */
.stream .layer-ic{color:var(--glyph);background:var(--badge);border-color:var(--ring)}

/* ============ Global network map (embedded interactive POP map, perception-stream) ============ */
.popmap-wrap{position:relative;width:100vw;max-width:100%;margin:clamp(1.2rem,2.6vw,2.2rem) 0 0;background:transparent;
  height:clamp(400px,48vh,500px);overflow:hidden}   /* clip the empty band the map leaves below itself */
.popmap-frame{display:block;width:100%;height:100%;border:0;background:transparent}
/* CTAs stack under the lead, like every other inner-page hero */
.page-head-below{margin-top:clamp(.6rem,1.8vw,1.4rem);display:flex;flex-direction:column;align-items:flex-start;gap:clamp(1rem,2.2vw,1.7rem)}
.page-head-below .lead{margin:0;font-size:clamp(.92rem,1.05vw,1.05rem);line-height:1.55;max-width:64ch}
.page-head-below .page-cta{margin:0}
/* tighten the Stream → Player Plus vertical gap on the homepage (was ~119px+119px) */
#stream{padding-bottom:clamp(2rem,4vw,3.5rem)}
#player-plus{padding-top:clamp(2.5rem,4.5vw,4rem)}
@media(max-width:640px){.popmap-wrap{height:min(96vw,420px)}
  .page-head-below{flex-direction:column;align-items:stretch;justify-content:flex-start}
  .page-head-below .lead{flex:0 0 auto}
  .page-head-below .page-cta .btn{flex:1 1 auto;justify-content:center}}

/* ============ Delivery-design request modal (opened from the primary CTAs) ============ */
.qm{position:fixed;inset:0;z-index:3000;display:grid;place-items:center;padding:clamp(1rem,4vw,2rem)}
.qm[hidden],.qm-form[hidden],.qm-done[hidden]{display:none}
.qm-backdrop{position:absolute;inset:0;background:rgba(8,12,20,.55);-webkit-backdrop-filter:blur(6px) saturate(1.1);backdrop-filter:blur(6px) saturate(1.1);animation:qmFade .25s ease}
.qm-dialog{position:relative;width:min(540px,100%);max-height:calc(100dvh - 2rem);overflow:auto;background:#fff;border-radius:clamp(20px,2.4vw,28px);box-shadow:0 60px 120px -34px rgba(8,12,20,.6),0 0 0 1px rgba(8,12,20,.05);padding:clamp(1.7rem,3.6vw,2.7rem);animation:qmRise .34s var(--spring,cubic-bezier(.2,.9,.3,1)) backwards}
.qm-x{position:absolute;top:14px;right:14px;width:38px;height:38px;border-radius:50%;border:0;background:var(--cloud,#f1f4f9);color:var(--slate,#5b6675);display:grid;place-items:center;cursor:pointer;transition:background .2s,color .2s}
.qm-x:hover{background:#e6ebf2;color:var(--ink)}
.qm-x svg{width:18px;height:18px}
/* The step label used float:right, which floats to the dialog's edge and so
   landed underneath the absolutely-positioned close button. Laying the two
   out as a row and reserving the button's width keeps them apart at every
   size, rather than relying on the title being short enough. */
.qm-eyebrow{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding-right:2.75rem;
  font-family:var(--font-label);font-size:.72rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--cyan)}
.qm-head h2{font-family:var(--font-display);font-weight:500;font-size:clamp(1.4rem,2.6vw,1.85rem);letter-spacing:-.02em;color:var(--ink);margin:.5rem 0 .5rem;line-height:1.12}
.qm-sub{color:var(--slate,#5b6675);font-size:.95rem;line-height:1.5;margin:0 0 1.5rem}
.qm-form{display:flex;flex-direction:column;gap:.85rem}
.qm-row{display:grid;grid-template-columns:1fr 1fr;gap:.85rem}
.qm-form label{display:flex;flex-direction:column;gap:.34rem;font-size:.8rem;font-weight:500;color:var(--ink)}
.qm-form input,.qm-form textarea{font:inherit;font-size:.95rem;font-weight:400;color:var(--ink);background:var(--cloud,#f5f7fa);border:1px solid var(--line,#e5e9f0);border-radius:12px;padding:.7rem .85rem;width:100%;transition:border-color .2s,box-shadow .2s;-webkit-appearance:none;appearance:none}
.qm-form input::placeholder,.qm-form textarea::placeholder{color:var(--steel,#9aa4b2)}
.qm-form input:focus,.qm-form textarea:focus{outline:0;border-color:var(--cyan);box-shadow:0 0 0 3px rgba(20,179,214,.16)}
.qm-form textarea{resize:vertical;min-height:78px;line-height:1.45}
.qm-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.qm-submit{margin-top:.55rem;justify-content:center;width:100%}
.qm-done{text-align:center;padding:.6rem 0 .2rem}
.qm-done-ic{width:60px;height:60px;border-radius:50%;background:rgba(20,179,214,.12);color:var(--cyan-deep,#0C7C95);display:grid;place-items:center;margin:0 auto 1.1rem}
.qm-done-ic svg{width:28px;height:28px}
.qm-done h3{font-family:var(--font-display);font-weight:500;font-size:1.4rem;letter-spacing:-.01em;color:var(--ink);margin:0 0 .5rem}
.qm-done p{color:var(--slate,#5b6675);margin:0 0 1.5rem;line-height:1.5}
@keyframes qmFade{from{opacity:0}to{opacity:1}}
@keyframes qmRise{from{opacity:0;transform:translateY(24px) scale(.97)}to{opacity:1;transform:none}}
@media(max-width:480px){.qm-row{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){.qm-backdrop,.qm-dialog{animation:none}}

/* ============ Perception AI page — product family, lines, platform, security ============ */
/* family tiles (dark, inside pfm-ai) */
.pai-tiles{margin-top:clamp(1.8rem,3.2vw,2.7rem);display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(12px,1.4vw,18px)}
.pai-tile{--pc:var(--pai);position:relative;display:flex;flex-direction:column;gap:.5rem;padding:clamp(1.2rem,1.8vw,1.55rem);border-radius:22px;background:rgba(19,24,32,.9);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);overflow:hidden;text-decoration:none;transition:transform .3s var(--ease),box-shadow .3s var(--ease)}
.pai-tile::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background:radial-gradient(70% 130% at 90% 118%,var(--pc),transparent 64%);opacity:.4;transition:opacity .3s}
.pai-tile>*{position:relative;z-index:1}
.pai-tile:hover{transform:translateY(-3px);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--pc) 62%,transparent)}
.pai-tile:hover::before{opacity:.64}
.pai-tile img{height:26px;width:auto;display:block;margin-bottom:.15rem}
.pai-tile-n{font-family:var(--font-display);font-weight:600;font-size:1.1rem;letter-spacing:-.02em;color:#fff}
.pai-tile-d{font-size:.85rem;line-height:1.5;color:rgba(255,255,255,.62);flex:1}
.pai-tile-tags{display:flex;gap:.35rem;flex-wrap:wrap;margin-top:.35rem}
.pai-tile-tags span{font-family:var(--font-label);font-size:.6rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:rgba(255,255,255,.8);padding:.26rem .5rem;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14)}
@media(max-width:900px){.pai-tiles{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.pai-tiles{grid-template-columns:1fr}}

/* product-line groups within the dark section */
.pd-line{margin-top:clamp(3rem,6vw,5.5rem)}
.pd-line-head{max-width:660px;margin-bottom:clamp(1.6rem,3vw,2.4rem)}
.pd-line-logo img{height:30px;width:auto;display:block;margin-bottom:1rem}
.pd-line-kicker{display:block;font-family:var(--font-label);font-size:.72rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--pc);margin-bottom:.6rem}
.pd-line-head h2{font-family:var(--font-display);font-weight:500;font-size:clamp(1.7rem,3.2vw,2.5rem);letter-spacing:-.03em;line-height:1.06;color:#fff;margin:0 0 .8rem}
.pd-line-lede{font-size:clamp(1rem,1.25vw,1.1rem);line-height:1.6;color:rgba(255,255,255,.7);margin:0;max-width:58ch}
.pai-list{display:flex;flex-direction:column;gap:clamp(2.4rem,5vw,4rem)}
.pd-feat-eyebrow{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--font-label);font-size:.72rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--pc);margin-bottom:.7rem}
.pd-feat-eg{font-weight:500;letter-spacing:.02em;color:rgba(255,255,255,.44);text-transform:none}
.pd-copy h3{font-family:var(--font-display);font-weight:500;font-size:clamp(1.35rem,2.2vw,1.7rem);letter-spacing:-.02em;line-height:1.12;color:#fff;margin:0 0 .8rem}

/* platform grid (light) */
.plat-grid{margin-top:clamp(2rem,3.5vw,2.8rem);display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,20px)}
.plat-card{padding:clamp(1.5rem,2.4vw,2rem);border-radius:var(--r-lg);background:var(--cloud,#f6f8fb);border:1px solid var(--line)}
.plat-ic{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;background:rgba(20,179,214,.1);color:var(--cyan-deep);margin-bottom:1.05rem}
.plat-ic svg{width:22px;height:22px}
.plat-card h3{font-family:var(--font-display);font-weight:600;font-size:1.1rem;letter-spacing:-.02em;color:var(--ink);margin:0 0 .5rem}
.plat-card p{font-size:.92rem;line-height:1.55;color:var(--slate);margin:0}
@media(max-width:900px){.plat-grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.plat-grid{grid-template-columns:1fr}}

/* security grid (light) */
.sec-grid{margin-top:clamp(2rem,3.5vw,2.8rem);display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,20px)}
.sec-card{padding:clamp(1.5rem,2.4vw,2rem);border-radius:var(--r-lg);background:#fff;border:1px solid var(--line);box-shadow:0 24px 46px -34px rgba(14,17,22,.32)}
.sec-card h3{display:flex;align-items:flex-start;gap:.6rem;font-family:var(--font-display);font-weight:600;font-size:1.06rem;letter-spacing:-.02em;color:var(--ink);margin:0 0 .55rem}
.sec-card h3 svg{width:20px;height:20px;color:var(--cyan-deep);flex:none;margin-top:1px}
.sec-card p{font-size:.92rem;line-height:1.55;color:var(--slate);margin:0}
.sec-note{margin-top:clamp(1.4rem,2.4vw,2rem);font-size:.82rem;line-height:1.55;color:var(--steel);max-width:82ch}
@media(max-width:820px){.sec-grid{grid-template-columns:1fr}}

/* =====================================================================================
   SITE-WIDE HERO RULE  (Aug 2026)
   Every non-home page carries a rounded, inset hero card that contrasts tonally with the page:
     • light (CloudWorks) inner pages  ->  DARK card on the white page
     • dark  (PAI) pages               ->  LIGHTER card on the near-black page
   Inner heroes sit at ~half the homepage hero height. The homepage keeps its full-bleed
   reference hero (already dark + rounded-bottom). On PAI pages the scrolled header pills +
   their dropdowns turn dark too.
   ===================================================================================== */
:root{
  --hero-r:56px;                     /* rounded BOTTOM corners, like the homepage's 60px */
  --hero-card-h:56svh;               /* ~half the 100svh homepage hero */
}

/* ---------- shared shape: full-bleed, stuck to the top, rounded ONLY at the bottom (like the homepage hero) ---------- */
.page-head,
.hero-card{
  margin:0;
  border-radius:0 0 var(--hero-r) var(--hero-r);
  overflow:hidden;
  position:relative;
  isolation:isolate;
}

/* ---------- LIGHT (CloudWorks) inner pages -> DARK hero card ---------- */
.page-head{
  min-height:var(--hero-card-h);
  display:flex;align-items:center;
  padding:clamp(7.5rem,15vh,10.5rem) 0 clamp(2.5rem,5vh,4rem);   /* top clears the overlapping header */
  color:#fff;
  background:
    radial-gradient(72% 130% at 6% -24%, rgba(20,179,214,.18), transparent 56%),
    radial-gradient(60% 120% at 102% -8%, rgba(46,91,255,.15), transparent 55%),
    linear-gradient(158deg,#151d2a 0%,#0e1116 64%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 40px 80px -50px rgba(14,17,22,.5);
}
.page-head::after{                    /* faint grid texture, faded */
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px);
  background-size:46px 46px;
  -webkit-mask-image:radial-gradient(82% 92% at 28% 8%,#000 30%,transparent 80%);
  mask-image:radial-gradient(82% 92% at 28% 8%,#000 30%,transparent 80%);
}
.page-head>.wrap{position:relative;z-index:1;width:100%}
/* beat the per-page inline "inner-page chrome" <style> (same 0,1,x specificity, loaded later) */
.section.page-head{padding:clamp(7.5rem,15vh,10.5rem) 0 clamp(2.5rem,5vh,4rem)}
.section.page-head h1{color:#fff;-webkit-text-fill-color:#fff;max-width:20ch}
.page-head p,.page-head .lead{color:rgba(255,255,255,.74)}
.page-head .crumbs{color:rgba(255,255,255,.5)}
.page-head .crumbs a{color:rgba(255,255,255,.72)}
.page-head .crumbs a:hover{color:var(--sky)}
.page-head .crumb-sep{color:rgba(255,255,255,.28)}
.page-head .eyebrow,.page-head .kicker,.page-head .sec-eyebrow{color:var(--steel)}
.page-head .btn-ghost{color:#fff;border-color:rgba(255,255,255,.24);background:rgba(255,255,255,.04)}
.page-head .btn-ghost:hover{border-color:rgba(255,255,255,.5);background:rgba(255,255,255,.09)}
/* perception-stream hero carries a full-width map among its page-head children:
   stack them (block) instead of the single-column flex-row used by other inner heroes */
/* heroes that stack more than one .wrap (title + lead/CTA) must not use the single-column flex row */
.page-head:has(.popmap-wrap),
.page-head:has(.page-head-below){display:block}
.page-head:has(.popmap-wrap) .wrap,
.page-head:has(.page-head-below) .wrap{position:relative;z-index:1}
.page-head .popmap-wrap{margin-top:clamp(1.6rem,3vw,2.6rem)}

/* ---------- DARK (PAI) pages -> LIGHTER hero band (stays flush to the top under the header) ---------- */
body.pai .hero-card{
  min-height:var(--hero-card-h);
  background-color:#02080F;            /* same hero surface as perception-ai: deeper than the page ground */
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06),0 44px 90px -52px rgba(0,0,0,.72);
}

/* ---------- LIGHT-page custom hero (player-plus): DARK band, flush to the top ---------- */
body:not(.pai):has(.hero.hero-card) main{margin-top:0}     /* main is inside .pp; don't double-pull it */
body:not(.pai):has(.hero.hero-card) .pp{margin-top:-113px} /* pull the whole .pp wrapper up under the header (it's a BFC that clips a child pull) */
body:not(.pai) .hero-card{
  min-height:var(--hero-card-h);color:#fff;
  padding-top:clamp(7.5rem,15vh,10.5rem);padding-bottom:clamp(2rem,4.5vw,3.2rem);
  background:
    radial-gradient(72% 130% at 6% -24%, rgba(20,179,214,.18), transparent 56%),
    radial-gradient(60% 120% at 102% -8%, rgba(46,91,255,.15), transparent 55%),
    linear-gradient(158deg,#151d2a 0%,#0e1116 64%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 40px 80px -50px rgba(14,17,22,.5);
}
body:not(.pai) .hero-card::before{opacity:0}              /* tame player-plus's light hero glow on the dark card */
body:not(.pai) .hero-card .eyebrow{color:var(--steel)}
body:not(.pai) .hero-card .hero-title{color:#fff;-webkit-text-fill-color:#fff}
body:not(.pai) .hero-card .hero-title .accent{color:var(--sky);-webkit-text-fill-color:var(--sky)}
body:not(.pai) .hero-card .hero-sub{color:rgba(255,255,255,.76)}
body:not(.pai) .hero-card .hero-sub strong{color:#fff}
body:not(.pai) .hero-card .hero-stdbar .std{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.14);color:rgba(255,255,255,.82)}
body:not(.pai) .hero-card .hero-stdbar .std b{color:#fff}

/* ---------- PAI pages: dark scrolled-header pills + dark dropdowns (Rule 3) ---------- */
body.pai header.scrolled .brand,
body.pai header.scrolled .nav-main{
  background:rgba(16,20,28,.9);
  border-color:rgba(255,255,255,.1);
  box-shadow:0 18px 44px -24px rgba(0,0,0,.72);
}
body.pai header.scrolled .brand-logo{filter:brightness(0) invert(1)}
body.pai header.scrolled .nav-trigger,
body.pai header.scrolled .nav-trigger .chev{color:#fff}
body.pai header.scrolled .nav-trigger:hover,
body.pai header.scrolled .nav-trigger.is-current{color:var(--sky)}
body.pai header.scrolled .burger{color:#fff}
body.pai header.scrolled .nav-right .btn-primary{box-shadow:0 18px 44px -24px rgba(0,0,0,.72)}
/* dark dropdown panels on PAI pages */
body.pai .dd{background:rgba(16,20,28,.97);border-color:rgba(255,255,255,.1);box-shadow:0 30px 70px -30px rgba(0,0,0,.82)}
body.pai .dd-h{color:rgba(255,255,255,.5)}
body.pai .dd-tt{color:#fff}
body.pai .dd-dd{color:rgba(255,255,255,.62)}
/* the bubbles and the promo panel were still painted for the light site, so a
   light disc and a white wash sat inside the dark menu */
body.pai .dd-ic{background:rgba(255,255,255,.07);border-radius:12px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);border-color:transparent;color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
body.pai .dd-link:hover{background:rgba(255,255,255,.06)}
body.pai .dd-link:hover .dd-ic{background:rgba(255,255,255,.15);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.24)}
body.pai .dd-promo{background:linear-gradient(rgba(6,10,18,.74),rgba(6,10,18,.74)),url("sov-mesh.webp") center/cover no-repeat}
body.pai .dd-foot{border-top-color:rgba(255,255,255,.1)}
body.pai .dd-foot small{color:rgba(255,255,255,.5)}
body.pai .dd-col+.dd-col{border-left-color:rgba(255,255,255,.1)}

@media(max-width:760px){
  :root{--hero-card-h:40svh;--hero-inset:8px}
}

/* =====================================================================================
   BRAND ICON KEEPS ITS COLOUR EVERYWHERE.
   On dark backgrounds the logo was whitened wholesale (brightness(0) invert(1)), killing the
   cyan mark. Swap to the dark-bg variant instead — same file with a WHITE wordmark but the
   ICON still on the brand cyan gradient — so the mark stays brand-coloured in every context.
   ===================================================================================== */
body.dark-hero #header:not(.scrolled) .brand-logo,
body.pai header.scrolled .brand-logo,
html.night footer .brand-logo,
.corp-gate-box .brand-logo{
  content:url("perception-logo-hero.svg");
  filter:none;
}

/* =====================================================================================
   Perception-AI hero (perception-ai.html): reduce the bento from full product CARDS to a
   clean row of product LOGOS (mark + name only), and shorten the hero. Overrides the scoped
   paicloud CSS via higher `body.pai` specificity (no rebuild needed).
   ===================================================================================== */
body.pai .pai-hero.hero-card{min-height:auto}                         /* let the shorter content set the height */
body.pai .pai-hero{padding-bottom:clamp(2.4rem,5vw,3.6rem)}           /* was 100px */
body.pai .hero-bento{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
  grid-template-columns:none;
  gap:clamp(14px,2vw,26px);
  margin-top:clamp(2.2rem,4.5vw,3.4rem);                              /* was 112–160px */
}
body.pai .bento-tile{
  flex:0 0 auto;
  padding:14px 22px;border-radius:16px;
  background:rgba(255,255,255,.035);
  border:1px solid rgba(255,255,255,.08);
  box-shadow:none;
}
body.pai .bento-tile:hover{transform:translateY(-3px);background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.18);box-shadow:none}
/* strip everything except the logo (mark + name) */
body.pai .tile-aura,
body.pai .tile-stroke,
body.pai .tile-desc,
body.pai .tile-products{display:none}
body.pai .tile-head{margin-bottom:0;justify-content:center}
body.pai .tile-mark{width:30px;height:28px}

/* ============================================================= INNER-PAGE HERO ANIMATIONS
   A themed decorative layer per inner page, injected as the first child of .page-head:
     <div class="hero-fx hero-fx--THEME" aria-hidden="true"> … </div>
   Sits at z-index:0 inside the hero band (overflow:hidden + isolate): above the ::after grid
   (-1) and the bg gradient, below .wrap content (z-index:1). GPU-safe (transform/translate/
   rotate/opacity only), inset below the header, cleared from the left-aligned headline by a
   mask, hidden on phones, and frozen under prefers-reduced-motion. */
.hero-fx{position:absolute;inset:84px 0 0 0;z-index:0;pointer-events:none;overflow:hidden;
  -webkit-mask-image:linear-gradient(100deg,transparent 40%,#000 68%);
          mask-image:linear-gradient(100deg,transparent 40%,#000 68%)}
/* spanning themes: hold clear of the wider headline/lead by keeping the fx in the right band */
.hero-fx--stream,.hero-fx--live{-webkit-mask-image:linear-gradient(100deg,transparent 50%,#000 76%);
          mask-image:linear-gradient(100deg,transparent 50%,#000 76%)}
.hero-fx--edge{-webkit-mask-image:linear-gradient(100deg,transparent 46%,#000 74%);
          mask-image:linear-gradient(100deg,transparent 46%,#000 74%)}
.hero-fx svg{position:absolute;inset:0;width:100%;height:100%;display:block}
@media (max-width:860px){.hero-fx{inset:70px 0 0 0;opacity:.6;
  -webkit-mask-image:linear-gradient(100deg,transparent 14%,#000 56%);
          mask-image:linear-gradient(100deg,transparent 14%,#000 56%)}}
@media (max-width:560px){.hero-fx{display:none}}
@media (prefers-reduced-motion:reduce){.hero-fx{opacity:.3}.hero-fx *{animation:none!important}}

/* 1 · why-cloudworks — "the steady signal": a calm sine wave with a light pulse travelling it */
.hero-fx--signal .sg-wrap{transform-box:fill-box;transform-origin:center;animation:sgBreathe 7.5s ease-in-out infinite}
.hero-fx--signal path{fill:none;vector-effect:non-scaling-stroke}
.hero-fx--signal .sg-base{stroke:rgba(122,226,255,.14);stroke-width:1.5}
.hero-fx--signal .sg-mid {stroke:rgba(122,226,255,.09);stroke-width:1.5}
.hero-fx--signal .sg-live{stroke:rgba(160,235,255,.8);stroke-width:2;stroke-dasharray:170 1600;
  filter:drop-shadow(0 0 7px rgba(122,226,255,.55));animation:sgTravel 6.5s linear infinite}
@keyframes sgTravel{from{stroke-dashoffset:1770}to{stroke-dashoffset:0}}
@keyframes sgBreathe{0%,100%{transform:scaleY(.9)}50%{transform:scaleY(1.12)}}

/* 2 · video-streaming — horizontal streams of light flowing left→right (frames in transit) */
.hero-fx--stream i{position:absolute;left:-45%;width:55%;height:2px;border-radius:2px;
  background:linear-gradient(90deg,transparent,rgba(122,226,255,.6) 58%,rgba(198,244,255,.95),transparent);
  animation:stFlow linear infinite}
.hero-fx--stream i:nth-child(1){top:18%;height:1.5px;animation-duration:5s;  animation-delay:-.5s;opacity:.5}
.hero-fx--stream i:nth-child(2){top:33%;height:3px;  animation-duration:3.6s;animation-delay:-1.8s;opacity:.85}
.hero-fx--stream i:nth-child(3){top:47%;height:2px;  animation-duration:4.4s;animation-delay:-.9s; opacity:.7}
.hero-fx--stream i:nth-child(4){top:61%;height:2.5px;animation-duration:3.1s;animation-delay:-2.4s;opacity:.8}
.hero-fx--stream i:nth-child(5){top:75%;height:1.5px;animation-duration:5.6s;animation-delay:-.2s; opacity:.45}
.hero-fx--stream i:nth-child(6){top:89%;height:2px;  animation-duration:4s;  animation-delay:-3s;  opacity:.6}
@keyframes stFlow{from{translate:0}to{translate:260% 0}}

/* 2b · video-streaming — a CSS-3D server stack with orbiting screens, spinning on its own axis
   (built from cuboids: each .cub is a point at the model origin; its 5 <i> faces are placed
   around it with rotate+translateZ, so no library is needed) */
/* deliberately oversized: it bleeds past the hero edges and reads as background, not subject */
.hero-fx--stream3d{opacity:.42;
  -webkit-mask-image:linear-gradient(100deg,transparent 22%,#000 54%);
          mask-image:linear-gradient(100deg,transparent 22%,#000 54%)}
.hero-fx--stream3d .m3d-stage{position:absolute;left:74%;top:56%;width:0;height:0;perspective:1500px}
.m3d{position:absolute;left:0;top:0;transform-style:preserve-3d;
  animation:m3dSpin 34s linear infinite}
@keyframes m3dSpin{from{transform:rotateX(-20deg) rotateY(0)}to{transform:rotateX(-20deg) rotateY(360deg)}}
.cub{position:absolute;left:0;top:0;width:0;height:0;transform-style:preserve-3d;
  transform:translate3d(var(--x,0px),var(--y,0px),var(--z,0px))}
.cub>i{position:absolute;left:0;top:0;display:block;border-radius:3px;
  box-shadow:inset 0 0 0 1px rgba(150,215,245,.16)}
.cub .fz{width:var(--w);height:var(--h);margin:calc(var(--h)/-2) 0 0 calc(var(--w)/-2)}
.cub .fx{width:var(--d);height:var(--h);margin:calc(var(--h)/-2) 0 0 calc(var(--d)/-2)}
.cub .ft{width:var(--w);height:var(--d);margin:calc(var(--d)/-2) 0 0 calc(var(--w)/-2);border-radius:10px}
/* dark smoked glass */
.f-front{transform:translateZ(calc(var(--d)/2));background:rgba(24,58,84,.30)}
.f-back {transform:rotateY(180deg) translateZ(calc(var(--d)/2));background:rgba(18,44,66,.26)}
.f-left {transform:rotateY(-90deg) translateZ(calc(var(--w)/2));background:rgba(14,36,56,.34)}
.f-right{transform:rotateY(90deg)  translateZ(calc(var(--w)/2));background:rgba(14,36,56,.34)}
.f-top  {transform:rotateX(90deg)  translateZ(calc(var(--h)/2));
  background:linear-gradient(150deg,rgba(126,196,232,.20),rgba(18,44,66,.16))}
/* detail: vent slats + a status LED on the unit walls */
.c-unit .fz::before,.c-unit .fx::before{content:"";position:absolute;inset:34% 9% 34% 9%;border-radius:2px;
  background:repeating-linear-gradient(90deg,rgba(160,220,250,.16) 0 3px,transparent 3px 10px)}
.c-unit .fz::after{content:"";position:absolute;right:7%;top:50%;width:6px;height:6px;margin-top:-3px;
  border-radius:50%;background:rgba(122,226,255,.85);box-shadow:0 0 10px rgba(122,226,255,.9)}
.c-cap .f-top{background:linear-gradient(150deg,rgba(170,224,250,.3),rgba(20,50,74,.2))}
/* base: a thin cyan light strip all round */
.c-base>i{background:rgba(12,32,50,.34)}
.c-base .fz::after,.c-base .fx::after{content:"";position:absolute;left:6%;right:6%;bottom:4px;height:2px;
  border-radius:2px;background:rgba(122,226,255,.75);box-shadow:0 0 14px rgba(20,179,214,.85)}
.c-base .f-top{background:linear-gradient(150deg,rgba(110,185,225,.18),rgba(12,32,50,.2))}
/* orbiting video cards — dark glass, cyan edge */
.scr-orb{position:absolute;left:0;top:0;width:0;height:0;transform-style:preserve-3d;
  transform:rotateY(var(--a)) translateZ(var(--r)) translateY(var(--y))}
.scr{position:absolute;left:0;top:0;width:132px;height:84px;margin:-42px 0 0 -66px;
  border-radius:14px;display:grid;place-items:center;
  background:linear-gradient(152deg,rgba(36,80,112,.42),rgba(10,26,42,.34));
  box-shadow:inset 0 0 0 1px rgba(140,215,245,.3),0 22px 40px -22px rgba(0,0,0,.85);
  animation:scrBob 6.4s ease-in-out infinite}
.scr::before{content:"";position:absolute;left:12px;right:12px;bottom:11px;height:3px;border-radius:2px;
  background:linear-gradient(90deg,rgba(122,226,255,.85) 38%,rgba(140,215,245,.22) 38%)}
.scr-orb:nth-of-type(even) .scr{animation-delay:-3.1s}
.scr-orb:nth-of-type(3n) .scr{animation-delay:-1.7s}
.scr::after{content:"";width:0;height:0;margin:-8px 0 0 6px;
  border-left:22px solid rgba(150,225,255,.72);border-top:15px solid transparent;border-bottom:15px solid transparent}
@keyframes scrBob{0%,100%{translate:0 0}50%{translate:0 -12px}}


/* 2c · perception-stream — an isometric grid of linked server racks (the network fabric),
   built from the same .cub rig and spinning on its own axis */
.hero-fx--platform3d{opacity:.46;
  -webkit-mask-image:linear-gradient(100deg,transparent 20%,#000 52%);
          mask-image:linear-gradient(100deg,transparent 20%,#000 52%)}
.hero-fx--platform3d .m3d-stage{position:absolute;left:73%;top:54%;width:0;height:0;perspective:1700px}
.hero-fx--platform3d .m3d{animation-duration:44s}
/* link bars between the racks */
.c-link>i{background:rgba(122,226,255,.20);box-shadow:inset 0 0 0 1px rgba(150,215,245,.22)}
.c-link .f-top{background:rgba(160,225,252,.30)}
/* racks: vent slats + a status LED */
.c-rack .fz::before,.c-rack .fx::before{content:"";position:absolute;inset:12% 16%;border-radius:2px;
  background:repeating-linear-gradient(180deg,rgba(165,222,250,.18) 0 4px,transparent 4px 13px)}
.c-rack .fz::after{content:"";position:absolute;right:14%;top:8%;width:6px;height:6px;border-radius:50%;
  background:rgba(122,226,255,.9);box-shadow:0 0 10px rgba(122,226,255,.95)}
/* mint glass blocks resting on the corner racks */
.c-glass>i{background:rgba(110,206,190,.26);box-shadow:inset 0 0 0 1px rgba(190,240,228,.34)}
.c-glass .f-top{background:linear-gradient(150deg,rgba(190,242,228,.40),rgba(90,190,180,.22))}
/* brighter core in the middle of the fabric */
.c-core>i{background:rgba(36,86,124,.40);box-shadow:inset 0 0 0 1px rgba(150,215,245,.26)}
.c-core .f-top{background:linear-gradient(150deg,rgba(178,228,252,.42),rgba(24,60,92,.26))}

/* 3b · user-applications — same CSS-3D rig as video-streaming: a hub column with the
   audience's devices (TVs, tablets, phones) orbiting it, spinning on its own axis */
.hero-fx--apps3d{opacity:.42;
  -webkit-mask-image:linear-gradient(100deg,transparent 22%,#000 54%);
          mask-image:linear-gradient(100deg,transparent 22%,#000 54%)}
.hero-fx--apps3d .m3d-stage{position:absolute;left:73%;top:54%;width:0;height:0;perspective:1500px}
.hero-fx--apps3d .c-col .fz::before,.hero-fx--apps3d .c-col .fx::before{content:"";position:absolute;
  inset:8% 22%;border-radius:3px;
  background:repeating-linear-gradient(180deg,rgba(160,220,250,.14) 0 4px,transparent 4px 16px)}
.hero-fx--apps3d .c-col .fz::after{content:"";position:absolute;left:50%;top:14%;width:8px;height:8px;
  margin-left:-4px;border-radius:50%;background:rgba(122,226,255,.85);box-shadow:0 0 12px rgba(122,226,255,.9)}
/* device screens instead of the player cards */
.dv-tv   {width:158px;height:100px}
.dv-tab  {width:112px;height:86px}
.dv-phone{width:62px;height:116px;border-radius:12px}
.dv-tv   {margin:-50px 0 0 -79px}
.dv-tab  {margin:-43px 0 0 -56px}
.dv-phone{margin:-58px 0 0 -31px}
/* UI lines rather than a play arrow */
.hero-fx--apps3d .scr::after{content:"";position:absolute;left:11px;right:11px;top:13px;bottom:21px;
  width:auto;height:auto;margin:0;border:0;border-radius:6px;
  background:repeating-linear-gradient(180deg,rgba(155,220,250,.26) 0 4px,transparent 4px 12px)}
.hero-fx--apps3d .scr::before{left:11px;right:40%;bottom:9px;height:4px}

/* 3 · user-applications — app windows floating with gentle parallax */
.hero-fx--apps i{position:absolute;border-radius:13px;border:1px solid rgba(122,226,255,.2);
  background:linear-gradient(160deg,rgba(122,226,255,.07),rgba(122,226,255,.02));
  box-shadow:0 24px 60px -34px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,255,255,.06);
  animation:apFloat ease-in-out infinite}
.hero-fx--apps i::before{content:"";position:absolute;left:11px;top:10px;width:38%;height:5px;border-radius:3px;background:rgba(160,235,255,.5)}
.hero-fx--apps i::after{content:"";position:absolute;left:11px;top:26px;right:11px;bottom:12px;border-radius:7px;
  background:repeating-linear-gradient(180deg,rgba(122,226,255,.1) 0 4px,transparent 4px 12px)}
.hero-fx--apps i:nth-child(1){right:9%; top:8%; width:206px;height:136px;animation-duration:6.5s}
.hero-fx--apps i:nth-child(2){right:24%;top:40%;width:150px;height:104px;animation-duration:8s;  animation-delay:-2s;  opacity:.82}
.hero-fx--apps i:nth-child(3){right:15%;top:66%;width:120px;height:84px; animation-duration:7.2s;animation-delay:-1s;  opacity:.66}
.hero-fx--apps i:nth-child(4){right:37%;top:15%;width:96px; height:70px; animation-duration:9s;  animation-delay:-3.5s;opacity:.5}
@keyframes apFloat{0%,100%{translate:0 0}50%{translate:0 -16px}}

/* 4 · private-cdn — edge nodes with light packets zipping along the links */
.hero-fx--edge .ed-link{stroke:rgba(122,226,255,.16);stroke-width:1;vector-effect:non-scaling-stroke}
.hero-fx--edge .ed-flow{fill:none;stroke:#cdf3ff;stroke-width:2;stroke-linecap:round;vector-effect:non-scaling-stroke;
  stroke-dasharray:14 620;filter:drop-shadow(0 0 5px rgba(160,235,255,.7));animation:edFlow linear infinite}
.hero-fx--edge .ed-node{fill:rgba(160,235,255,.85)}
.hero-fx--edge .ed-node.hub{fill:#dff7ff}
.hero-fx--edge .ed-ring{fill:none;stroke:rgba(122,226,255,.55);stroke-width:1.5;transform-box:fill-box;transform-origin:center;animation:edPing 3.4s ease-out infinite}
@keyframes edFlow{from{stroke-dashoffset:634}to{stroke-dashoffset:0}}
@keyframes edPing{0%{transform:scale(.5);opacity:.7}70%{opacity:0}100%{transform:scale(3);opacity:0}}


/* 4b · private-cdn — three antenna towers on lit plinths with floating UI panels
   (client reference), same .cub rig, spinning on its own axis */
.hero-fx--towers3d{opacity:.44;
  -webkit-mask-image:linear-gradient(100deg,transparent 22%,#000 54%);
          mask-image:linear-gradient(100deg,transparent 22%,#000 54%)}
.hero-fx--towers3d .m3d-stage{position:absolute;left:74%;top:53%;width:0;height:0;perspective:1600px}
.hero-fx--towers3d .m3d{animation-duration:38s}
/* tower body: cable runs + a lit seam */
.c-tower .fz::before,.c-tower .fx::before{content:"";position:absolute;inset:10% 26%;border-radius:3px;
  background:repeating-linear-gradient(180deg,rgba(160,220,250,.13) 0 3px,transparent 3px 15px)}
.c-tower .fz::after{content:"";position:absolute;left:50%;top:12%;bottom:12%;width:2px;margin-left:-1px;
  border-radius:2px;background:linear-gradient(180deg,transparent,rgba(122,226,255,.5),transparent)}
/* plinths glow at the base like the reference */
.c-plinth>i{background:rgba(20,48,72,.34)}
.c-plinth .f-top{background:linear-gradient(150deg,rgba(150,214,246,.24),rgba(16,40,62,.18))}
.c-plinth .fz::after,.c-plinth .fx::after{content:"";position:absolute;left:8%;right:8%;bottom:3px;height:2px;
  border-radius:2px;background:rgba(140,236,214,.7);box-shadow:0 0 14px rgba(120,230,205,.8)}
/* mint-lit caps */
.c-capm>i{background:rgba(96,186,178,.28);box-shadow:inset 0 0 0 1px rgba(190,240,228,.3)}
.c-capm .f-top{background:linear-gradient(150deg,rgba(196,244,230,.44),rgba(70,170,168,.22))}
/* antenna masts */
.c-mast>i{background:rgba(178,224,250,.2);box-shadow:inset 0 0 0 1px rgba(200,238,255,.16)}
/* panel antennas around the mast */
.c-ant>i{background:rgba(150,206,238,.16);box-shadow:inset 0 0 0 1px rgba(198,236,255,.14)}
.c-ant .f-top{background:linear-gradient(150deg,rgba(200,238,255,.2),rgba(90,160,200,.1))}
/* the floating panels read as UI cards, not players */
.hero-fx--towers3d .scr{width:118px;height:78px;margin:-39px 0 0 -59px}
.hero-fx--towers3d .scr::after{content:"";position:absolute;left:11px;right:11px;top:13px;bottom:20px;
  width:auto;height:auto;margin:0;border:0;border-radius:6px;
  background:repeating-linear-gradient(180deg,rgba(155,220,250,.24) 0 4px,transparent 4px 12px)}
.hero-fx--towers3d .scr::before{left:11px;right:42%;bottom:9px;height:4px;background:rgba(140,236,214,.8)}

/* 5 · industry-broadcasters — concentric broadcast rings from a transmitter */
.hero-fx--broadcast{--ox:76%;--oy:40%}
.hero-fx--broadcast i{position:absolute;left:var(--ox);top:var(--oy);width:44px;height:44px;margin:-22px 0 0 -22px;
  border-radius:50%;border:1.5px solid rgba(122,226,255,.55);animation:bcRing 4.4s ease-out infinite}
.hero-fx--broadcast i:nth-child(2){animation-delay:1.1s}
.hero-fx--broadcast i:nth-child(3){animation-delay:2.2s}
.hero-fx--broadcast i:nth-child(4){animation-delay:3.3s}
.hero-fx--broadcast::before{content:"";position:absolute;left:var(--ox);top:var(--oy);width:12px;height:12px;margin:-6px 0 0 -6px;
  border-radius:50%;background:#bef4ff;box-shadow:0 0 12px rgba(160,235,255,.8)}
@keyframes bcRing{0%{transform:scale(.25);opacity:0}12%{opacity:.75}100%{transform:scale(9);opacity:0}}

/* 6 · industry-content-owners — a wall of catalogue tiles with a light sweep across it */
.hero-fx--catalog .ct-wall{position:absolute;inset:-12% -6% -12% 18%;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='54' height='72'%3E%3Crect x='3' y='3' width='44' height='62' rx='7' fill='%2379E2FF' fill-opacity='0.12'/%3E%3C/svg%3E");
  background-size:54px 72px;animation:ctDrift 20s linear infinite}
.hero-fx--catalog .ct-sweep{position:absolute;inset:0;
  background:linear-gradient(105deg,transparent 42%,rgba(198,244,255,.16) 50%,transparent 58%);animation:ctSweep 5.5s ease-in-out infinite}
@keyframes ctDrift{from{translate:0 0}to{translate:0 -72px}}
@keyframes ctSweep{0%{translate:-45% 0}100%{translate:60% 0}}

/* 7 · industry-sports — fast, tilted motion streaks + a LIVE pulse */
.hero-fx--live i{position:absolute;left:-50%;width:46%;height:2px;border-radius:3px;rotate:-11deg;
  background:linear-gradient(90deg,transparent,rgba(122,226,255,.75),rgba(214,246,255,.95),transparent);
  animation:lvDash linear infinite}
.hero-fx--live i:nth-child(1){top:24%;animation-duration:1.5s; animation-delay:-.2s;opacity:.8}
.hero-fx--live i:nth-child(2){top:40%;height:3px;animation-duration:1.1s;animation-delay:-.6s}
.hero-fx--live i:nth-child(3){top:55%;animation-duration:1.8s; animation-delay:-1s;opacity:.7}
.hero-fx--live i:nth-child(4){top:68%;height:2.5px;animation-duration:1.3s;animation-delay:-.4s;opacity:.85}
.hero-fx--live i:nth-child(5){top:82%;animation-duration:1.6s; animation-delay:-.8s;opacity:.6}
.hero-fx--live i:nth-child(6){top:32%;animation-duration:1s;  animation-delay:-1.3s;opacity:.5}
@keyframes lvDash{from{translate:0}to{translate:300% 0}}
.hero-fx--live b{position:absolute;right:15%;top:26%;width:10px;height:10px;border-radius:50%;background:#ff4d55;animation:lvLive 1.5s ease-out infinite}
@keyframes lvLive{0%{box-shadow:0 0 0 0 rgba(255,77,85,.6)}70%{box-shadow:0 0 0 18px rgba(255,77,85,0)}100%{box-shadow:0 0 0 0 rgba(255,77,85,0)}}

/* 8 · industry-telcos — telecom signal-strength bars + transmission arcs */
.hero-fx--telco{--bx:70%;--by:66%}
.hero-fx--telco i{position:absolute;bottom:calc(100% - var(--by));width:9px;border-radius:3px 3px 0 0;transform-origin:bottom center;
  background:linear-gradient(180deg,rgba(160,235,255,.85),rgba(122,226,255,.12));animation:tcBar ease-in-out infinite}
.hero-fx--telco i:nth-child(1){left:var(--bx);             height:28px;animation-duration:1.4s; animation-delay:-.1s}
.hero-fx--telco i:nth-child(2){left:calc(var(--bx) + 16px);height:46px;animation-duration:1.1s; animation-delay:-.5s}
.hero-fx--telco i:nth-child(3){left:calc(var(--bx) + 32px);height:68px;animation-duration:1.6s; animation-delay:-.9s}
.hero-fx--telco i:nth-child(4){left:calc(var(--bx) + 48px);height:94px;animation-duration:1.25s;animation-delay:-.3s}
.hero-fx--telco i:nth-child(5){left:calc(var(--bx) + 64px);height:122px;animation-duration:1.5s;animation-delay:-.7s}
@keyframes tcBar{0%,100%{transform:scaleY(.42)}50%{transform:scaleY(1)}}
.hero-fx--telco .tc-arc{position:absolute;left:calc(var(--bx) + 78px);top:calc(var(--by) - 122px);width:60px;height:60px;margin:-30px;
  border:2px solid transparent;border-top-color:rgba(160,235,255,.6);border-right-color:rgba(160,235,255,.6);border-radius:50%;animation:tcArc 3.2s ease-out infinite}
.hero-fx--telco .tc-arc:nth-of-type(2){animation-delay:1.6s}
@keyframes tcArc{0%{transform:rotate(-45deg) scale(.4);opacity:0}18%{opacity:.7}100%{transform:rotate(-45deg) scale(2.4);opacity:0}}

/* 9 · corporate — two soft brand spotlights drifting slowly (calm, spacious, enterprise) */
.hero-fx--corp i{position:absolute;border-radius:50%;filter:blur(34px);animation:cpDrift ease-in-out infinite}
.hero-fx--corp i:nth-child(1){right:12%;top:18%;width:230px;height:230px;background:radial-gradient(circle,rgba(20,179,214,.34),transparent 70%);animation-duration:15s}
.hero-fx--corp i:nth-child(2){right:34%;top:52%;width:170px;height:170px;background:radial-gradient(circle,rgba(46,91,255,.3),transparent 70%);animation-duration:19s;animation-delay:-5s}
@keyframes cpDrift{0%,100%{translate:0 0}50%{translate:-26px -20px}}



/* ============================================================= EXPLORE PILLS
   One look for every "Explore" button: grey hairline, ink label, and a line
   arrow inside a 1px circle. */
.sol-cdn-cap em,
.sol-lbl em,
.slab-sol .slab-explore{
  display:inline-flex;align-items:center;gap:.55rem;font-style:normal;
  padding:.42rem .42rem .42rem 1.05rem;border-radius:var(--pill);
  border:1px solid rgba(14,17,22,.26);background:transparent;
  font-family:var(--font-label);font-size:.82rem;font-weight:600;color:var(--ink);
  transition:border-color .25s var(--ease),background .25s var(--ease)}
/* pills hug their label — a column flex parent would otherwise stretch them full width */
.sol-cdn-cap em,.sol-lbl em,.slab-sol .slab-explore{align-self:flex-start;width:auto;flex:0 0 auto}
.sol-cdn-cap em{align-self:center}
.sol-lbl em{margin-top:.35rem;font-size:.75rem;padding:.34rem .34rem .34rem .85rem;gap:.45rem}
.sol-cdn-cap em .ar,
.sol-lbl em .ar,
.slab-sol .slab-explore .ar{
  width:22px;height:22px;flex:none;display:inline-grid;place-items:center;
  border:1px solid currentColor;border-radius:50%;opacity:.7;
  transition:transform .25s var(--ease),opacity .25s var(--ease)}
.sol-lbl em .ar{width:19px;height:19px}
.sol-cdn-cap em .ar svg,
.sol-lbl em .ar svg,
.slab-sol .slab-explore .ar svg{width:100%;height:100%;display:block}
.sol-cdn-cap:hover em,
.sol-lbl:hover em,
.slab-sol .slab-explore:hover{border-color:var(--steel);background:rgba(14,17,22,.03);color:var(--ink)}
.sol-cdn-cap:hover em .ar,
.sol-lbl:hover em .ar,
.slab-sol .slab-explore:hover .ar{opacity:1;transform:translateX(2px)}

/* the scale cluster sits lower so the cards centre against the body copy */
.scale-cluster{align-self:center}
.sc-col-a{margin-top:clamp(26px,4.5vw,58px)}

/* faint line icon behind each scale card — 1px stroke at any size via non-scaling-stroke */
.sc-card{position:relative;overflow:hidden}
.sc-bg{position:absolute;right:-16px;bottom:-20px;width:138px;height:138px;z-index:0;
  pointer-events:none;opacity:.16;stroke-linecap:round;stroke-linejoin:round}
.sc-bg *{vector-effect:non-scaling-stroke;stroke-width:1}
.sc-v,.sc-l{position:relative;z-index:1}
.sc-1 .sc-bg{color:#fff;opacity:.2}
.sc-2 .sc-bg,.sc-hero.sc-4 .sc-bg{color:#fff;opacity:.5}

/* ============================================================= BUTTON ARROWS
   Every .btn arrow sits in a circle, matching the header CTA. The header keeps its
   own (more specific) rule; ghost buttons get a 1px ring instead of a filled disc. */
.btn svg{width:13px;height:13px;padding:5.5px;box-sizing:content-box;border-radius:50%;
  margin-left:.15rem;transition:transform .28s var(--ease),background .28s var(--ease),box-shadow .28s var(--ease)}
.btn svg path{stroke-width:1.7}
.btn-primary svg{background:rgba(4,20,26,.15)}
.btn-primary:hover svg{background:rgba(4,20,26,.24);transform:translateX(2px)}
.btn-ghost svg{background:transparent;box-shadow:inset 0 0 0 1px currentColor;opacity:.85}
.btn-ghost:hover svg{opacity:1;transform:translateX(2px)}

/* PAI pages: one continuous blue-black ground. Every band (.pai-line, .pai-section,
   .pai-cta and the hero) painted its own fill, a 1px divider and an ambient radial
   glow wash — together those read as sections and coloured pools on the page
   background. Flatten all three. The hero art (.pai-hero::after) and the glows
   inside the product mockups (.fv-frame, .fv-video) belong to their own surfaces
   and stay. */
/* the page ground sits clearly above the hero (#02080F) so the hero reads as
   the deeper surface; #070A12 was only ~3 points apart and looked flat */
html:has(body.pai),body.pai,body.pai .pai-scope{background:#14181F}
body.pai .pai-scope .pai-line,
body.pai .pai-scope .pai-section,
body.pai .pai-scope .pai-cta{background-color:transparent;background-image:none;
  border-top:0;border-bottom:0}
/* the hero keeps a surface of its own, like the dark heroes on the rest of the
   site: the darkest stop of .hero-v2, so it reads deeper than the page ground */
body.pai .pai-scope .pai-hero{background:#02080F;border:0}
body.pai .pai-scope .pai-line::before,
body.pai .pai-scope .pai-section::before,
body.pai .pai-scope .pai-cta::before,
body.pai .pai-scope .pai-hero::before{display:none}

/* …but the CTA keeps its glow inside the card: same three radials as the section
   used to paint, clipped to the card's own radius. z-index:-1 puts it above the
   card's fill and below its content (the card is already a stacking context). */
body.pai .pai-scope .pai-cta-inner::before{content:"";position:absolute;inset:0;
  z-index:-1;pointer-events:none;border-radius:inherit;
  background:
    radial-gradient(44% 68% at 20% 100%, var(--chat-glow), transparent 64%),
    radial-gradient(42% 64% at 80% 0%, var(--subs-glow), transparent 62%),
    radial-gradient(40% 56% at 52% 60%, var(--wallet-glow), transparent 66%);
  opacity:.55}

/* PAI buttons wrap the arrow in .btn-arrow, which is itself the disc (30px, 36px
   on .btn-lg). The site-wide .btn svg circle was drawing a second one inside it. */
.btn .btn-arrow svg{padding:0;border-radius:0;background:none;box-shadow:none;
  opacity:1;width:15px;height:15px}

/* ---- video-streaming: the three model cards, tinted like the homepage scale
   cluster. Scoped to .slab-tint because .slab-card is shared by 17 pages. ---- */
.slab-tint .slab-card{position:relative;overflow:hidden;isolation:isolate;border-color:transparent}
/* deeper into the corner than it was: at 132px from right:-14/bottom:-18 the
   drawing reached 118px in from the card edge and 114px up from its floor,
   which is where the last two bullets live. */
.slab-tint .slab-card::after{content:"";position:absolute;right:-24px;bottom:-28px;width:124px;height:124px;
  z-index:-1;pointer-events:none;background-repeat:no-repeat;background-size:contain}
.slab-tint .slab-card:nth-child(1){background:#1D242B}
.slab-tint .slab-card:nth-child(1) h3{color:#fff}
.slab-tint .slab-card:nth-child(1) li{color:rgba(255,255,255,.72)}
.slab-tint .slab-card:nth-child(1)::after{background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%221%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Crect%20x%3D%2214%22%20y%3D%2226%22%20width%3D%2292%22%20height%3D%2262%22%20rx%3D%228%22%2F%3E%3Cpath%20d%3D%22M52%2044l24%2015-24%2015z%22%2F%3E%3Cpath%20d%3D%22M44%20100h32%22%2F%3E%3C%2Fsvg%3E");opacity:.20}
.slab-tint .slab-card:nth-child(2){background:#8FD5E8}
.slab-tint .slab-card:nth-child(2) h3{color:#0E1116}
.slab-tint .slab-card:nth-child(2) li{color:rgba(14,17,22,.7)}
.slab-tint .slab-card:nth-child(2)::after{background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%221%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M60%2018l42%2022-42%2022-42-22z%22%2F%3E%3Cpath%20d%3D%22M18%2062l42%2022%2042-22%22%2F%3E%3Cpath%20d%3D%22M18%2082l42%2022%2042-22%22%2F%3E%3C%2Fsvg%3E");opacity:.6}
.slab-tint .slab-card:nth-child(3){background:#DCE2E7}
.slab-tint .slab-card:nth-child(3) h3{color:#0E1116}
.slab-tint .slab-card:nth-child(3) li{color:rgba(14,17,22,.66)}
.slab-tint .slab-card:nth-child(3)::after{background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%221%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2242%22%2F%3E%3Cellipse%20cx%3D%2260%22%20cy%3D%2260%22%20rx%3D%2218%22%20ry%3D%2242%22%2F%3E%3Cpath%20d%3D%22M18%2060h84M27%2036h66M27%2084h66%22%2F%3E%3C%2Fsvg%3E");opacity:.75}
.slab-tint .slab-card:hover{border-color:transparent;box-shadow:0 24px 50px -34px rgba(14,17,22,.32)}
/* checkmarks instead of the square bullets */
.slab-tint .slab-card li::before{width:5px;height:9px;left:2px;top:.3em;
  background:none;border-radius:0;box-shadow:none;
  border:solid currentColor;border-width:0 1.6px 1.6px 0;transform:rotate(43deg)}

/* video-streaming 'The model': text left, streaming illustration right, riding
   the same solFloat keyframes the homepage objects use */
.model-split{display:grid;grid-template-columns:1fr minmax(0,.8fr);gap:clamp(1.8rem,5vw,4rem);align-items:center}
.model-split .head-2{max-width:none}
.model-ill{position:relative;display:grid;place-items:center;
  border-radius:30px;overflow:hidden;aspect-ratio:1;
  background:url("sov-mesh.webp") center/cover no-repeat}   /* mesh shows until the clip decodes; the clip carries the same mesh */   /* same mesh panel as .sov-facts on the homepage */
.model-media{width:100%;height:100%;object-fit:cover;display:block}
@media(max-width:900px){.model-split{grid-template-columns:1fr}.model-ill{max-width:420px;margin-inline:auto}}


/* .model-split also carries text blocks that are more than a .head-2 (a feature
   list, for instance), so the copy side gets its own column wrapper */
.model-copy{min-width:0}
.model-copy .head-2{max-width:none}
/* empty mesh panel used as an image placeholder */
.model-ill.is-placeholder{width:100%}

/* .pai-scope .btn-primary paints var(--text-on-primary), which is white; every
   other primary button on the site uses the dark ink. */
body.pai .pai-scope .btn-primary{color:#04141a}


/* dropdown swap: with one panel already open, the next appears with no rise/fade
   and its content slides in from the right instead */
html.dd-active .dd{transition:none}
.nav-item.dd-swap .dd-col,
.nav-item.dd-swap .dd-promo{animation:ddSwap .26s var(--ease) both}
.nav-item.dd-swap .dd-col:nth-of-type(2){animation-delay:.045s}
.nav-item.dd-swap .dd-promo{animation-delay:.08s}
@keyframes ddSwap{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .nav-item.dd-swap .dd-col,.nav-item.dd-swap .dd-promo{animation:none}
}

/* delivery modal, two steps: the choice grid on the left, the guide panel on the
   right — the mesh artwork the site uses for its illustration panels, with the
   hero lockup and a glass card whose copy follows the selection. Ported from
   the client's CTA-flow prototype, which forked this stylesheet; the base .qm
   rules above are shared, these are the additions. */
.qm-step-label{flex:none;color:var(--slate);font-weight:600;letter-spacing:.04em;white-space:nowrap}
.qm-choose{border:0;padding:0;margin:0;min-width:0}
.qm-choices{display:grid;grid-template-columns:1fr 1fr;gap:.65rem}
/* .qm-form label (above) lays every label out as a flex column; the choice
   card is a label too, so it needs the heavier selector to be a grid row */
.qm-form .qm-choice{position:relative;display:grid;grid-template-columns:38px 1fr 18px;gap:.7rem;align-items:center;
  min-height:72px;padding:.78rem;border:1px solid var(--line,#e5e9f0);border-radius:14px;
  background:var(--cloud,#f5f7fa);cursor:pointer;
  transition:border-color .18s,background .18s,box-shadow .18s,transform .18s}
.qm-choice:hover{transform:translateY(-1px);border-color:#a8dce8;background:#fff}
.qm-choice input{position:absolute;opacity:0;pointer-events:none}
.qm-choice:has(input:focus-visible){outline:3px solid rgba(20,179,214,.24);outline-offset:2px}
.qm-choice:has(input:checked){border-color:var(--cyan);background:#f4fcfe;box-shadow:0 0 0 2px rgba(20,179,214,.12)}
/* the AI card carries the PAI blue, as the product does everywhere else */
.qm-choice:has(input[data-key="ai"]){background:linear-gradient(135deg,rgba(46,91,255,.075),rgba(136,156,255,.035));border-color:rgba(46,91,255,.3);box-shadow:none}
.qm-choice:has(input[data-key="ai"]) small{color:var(--slate)}
.qm-choice:has(input[data-key="ai"]) .qm-choice-icon{background:rgba(46,91,255,.1);color:#2E5BFF;box-shadow:inset 0 0 0 1px rgba(46,91,255,.12)}
.qm-choice:has(input[data-key="ai"]:checked){background:linear-gradient(135deg,rgba(46,91,255,.12),rgba(136,156,255,.055));border-color:#637fff;box-shadow:0 0 0 2px rgba(46,91,255,.1)}
.qm-choice-icon{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;background:#fff;
  color:var(--cyan-deep,#0C7C95);font-size:1.1rem;box-shadow:inset 0 0 0 1px rgba(12,124,149,.12)}
.qm-choice strong,.qm-choice small{display:block}
.qm-choice strong{font-size:.88rem}
.qm-choice small{margin-top:.16rem;color:var(--slate);font-size:.72rem;line-height:1.25;font-weight:400}
.qm-choice i{width:17px;height:17px;border:1.5px solid #b6bec9;border-radius:50%;position:relative}
.qm-choice:has(input:checked) i{border-color:var(--cyan);background:var(--cyan)}
.qm-choice:has(input:checked) i::after{content:"";position:absolute;inset:4px;border-radius:50%;background:#fff}
.qm-next{width:100%;justify-content:center;margin-top:1rem}
.qm-details{display:flex;flex-direction:column;gap:.85rem}
.qm-details[hidden]{display:none}
.qm-back{align-self:flex-start;border:0;background:none;padding:0;color:var(--cyan-deep,#0C7C95);font:600 .76rem var(--font-label);cursor:pointer}
.qm-selection{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.72rem .85rem;border-radius:12px;background:#eefafd;color:var(--slate);font-size:.75rem}
.qm-selection strong{color:var(--ink);font-size:.85rem}

.qm-dialog{width:min(980px,100%);display:grid;grid-template-columns:minmax(0,1fr) 360px;
  /* minmax(0,1fr) so the row is bounded by the dialog's max-height instead of by
     its content. Without it the row grows to fit, max-height merely clips, and
     .qm-main -- the only scrollable pane, since this element is overflow:hidden
     to clip the aside's corners -- never becomes shorter than its content. The
     result was a modal whose lower half, Continue button included, could not be
     reached on a short screen. */
  grid-template-rows:minmax(0,1fr);
  align-items:stretch;gap:0;padding:0;overflow:hidden}
/* min-height:0 matters: .qm-dialog is a grid with overflow:hidden (it clips the
   aside's rounded corners), so the only thing that can scroll is this pane. As
   a grid item its default min-height:auto refuses to shrink below its content,
   which left overflow:auto inert and the Continue button unreachable on short
   screens. */
.qm-main{min-width:0;min-height:0;padding:clamp(1.5rem,3vw,2.2rem);overflow:auto}
.qm-aside{position:relative;display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;
  gap:clamp(2rem,4vh,3.2rem);padding:clamp(1.7rem,3vw,2.4rem);overflow:hidden;color:#fff;
  background:linear-gradient(165deg,rgba(8,20,34,.04) 0%,rgba(8,18,30,.24) 42%,rgba(8,18,30,.68) 100%),
    url("sov-mesh.webp") center/cover no-repeat}
.qm-aside::before{content:"";position:absolute;width:230px;height:230px;border:1px solid rgba(93,215,237,.28);border-radius:50%;
  right:-95px;top:-90px;box-shadow:0 0 0 42px rgba(93,215,237,.06),0 0 0 86px rgba(93,215,237,.035)}
.qm-guide-logo{position:relative;z-index:1;align-self:center;width:min(190px,68%);height:auto;display:block;margin:.2rem 0 0;
  filter:drop-shadow(0 8px 20px rgba(4,14,24,.24))}
.qm-guide{position:relative;z-index:1;margin:0;padding:1.25rem;border:1px solid rgba(255,255,255,.14);border-radius:18px;
  background:rgba(5,15,27,.48);-webkit-backdrop-filter:blur(10px) saturate(1.12);backdrop-filter:blur(10px) saturate(1.12);
  box-shadow:0 18px 44px -28px rgba(0,0,0,.8)}
.qm-guide-kicker{display:block;color:#62d7ed;font:600 .69rem var(--font-label);letter-spacing:.13em;text-transform:uppercase;margin-bottom:.8rem}
.qm-guide h3{font-family:var(--font-display);font-size:clamp(1.45rem,2.4vw,2rem);font-weight:500;letter-spacing:-.03em;line-height:1.06;margin:0 0 .9rem;color:#fff}
.qm-guide>p{font-size:.9rem;line-height:1.55;color:rgba(255,255,255,.7);margin:0 0 1.25rem}
.qm-guide ul{list-style:none;padding:0;margin:0 0 1.4rem;display:grid;gap:.65rem}
.qm-guide li{position:relative;padding-left:1.35rem;font-size:.82rem;line-height:1.4;color:rgba(255,255,255,.9)}
.qm-guide li::before{content:"\2713";position:absolute;left:0;color:#62d7ed;font-weight:700}
.qm-guide-note{display:grid;gap:.18rem;padding-top:1rem;border-top:1px solid rgba(255,255,255,.16)}
.qm-guide-note strong{font-size:.78rem;color:#fff}
.qm-guide-note span{font-size:.72rem;line-height:1.4;color:rgba(255,255,255,.58)}
@media(max-width:760px){
  .qm-dialog{grid-template-columns:1fr}
  .qm-aside{display:none}
}
@media(max-width:560px){
  .qm-choices,.qm-row{grid-template-columns:1fr}
  .qm-choice{min-height:64px}
  .qm-dialog{max-height:calc(100dvh - 1rem)}
  .qm-main{padding:1.3rem}
}

/* user-applications capability cards: reference palette (deep ink / sky / grey)
   with each card's own icon repeated large behind it. Tones are assigned per
   card so the 3-column grid does not repeat column-for-column. Scoped to
   .slab-paint because .slab-card is shared across 17 pages. */
.slab-paint .slab-card{position:relative;overflow:hidden;isolation:isolate;border-color:transparent;
  padding-bottom:116px}
/* The card's own icon, drawn large in the bottom corner. It reaches 126px up
   from the bottom edge and 130px in from the right, and the copy used to run
   straight through it — an outline crossing a line of text reads as a mistake
   however faint it is. The card reserves that band below the copy instead
   (see the padding-bottom on .slab-card), so the drawing keeps the corner and
   the text keeps its measure. */
.slab-paint .slab-bg{position:absolute;right:12px;bottom:12px;z-index:-1;pointer-events:none;
  width:104px;height:104px;display:block}
.slab-paint .slab-bg svg{width:100%;height:100%;fill:none;stroke:currentColor;
  stroke-linecap:round;stroke-linejoin:round}
.slab-paint .slab-bg svg *{vector-effect:non-scaling-stroke;stroke-width:1}
.slab-paint .slab-card:nth-child(1),
.slab-paint .slab-card:nth-child(6){background:#1D242B}
.slab-paint .slab-card:nth-child(1) h3,
.slab-paint .slab-card:nth-child(6) h3{color:#fff}
.slab-paint .slab-card:nth-child(1) p,
.slab-paint .slab-card:nth-child(6) p{color:rgba(255,255,255,.68)}
.slab-paint .slab-card:nth-child(1) .slab-bg,
.slab-paint .slab-card:nth-child(6) .slab-bg{color:#fff;opacity:.22}
.slab-paint .slab-card:nth-child(1) .sc-ic,
.slab-paint .slab-card:nth-child(6) .sc-ic{background:rgba(255,255,255,.12)}
.slab-paint .slab-card:nth-child(1) .sc-ic svg,
.slab-paint .slab-card:nth-child(6) .sc-ic svg{stroke:#fff}
.slab-paint .slab-card:nth-child(2),
.slab-paint .slab-card:nth-child(7),
.slab-paint .slab-card:nth-child(4){background:#8FD5E8}
.slab-paint .slab-card:nth-child(2) h3,
.slab-paint .slab-card:nth-child(7) h3,
.slab-paint .slab-card:nth-child(4) h3{color:#0E1116}
.slab-paint .slab-card:nth-child(2) p,
.slab-paint .slab-card:nth-child(7) p,
.slab-paint .slab-card:nth-child(4) p{color:rgba(14,17,22,.7)}
.slab-paint .slab-card:nth-child(2) .slab-bg,
.slab-paint .slab-card:nth-child(7) .slab-bg,
.slab-paint .slab-card:nth-child(4) .slab-bg{color:#fff;opacity:.55}
.slab-paint .slab-card:nth-child(2) .sc-ic,
.slab-paint .slab-card:nth-child(7) .sc-ic,
.slab-paint .slab-card:nth-child(4) .sc-ic{background:rgba(255,255,255,.5)}
.slab-paint .slab-card:nth-child(2) .sc-ic svg,
.slab-paint .slab-card:nth-child(7) .sc-ic svg,
.slab-paint .slab-card:nth-child(4) .sc-ic svg{stroke:#0B3B4A}
.slab-paint .slab-card:nth-child(3),
.slab-paint .slab-card:nth-child(8),
.slab-paint .slab-card:nth-child(5){background:#DCE2E7}
.slab-paint .slab-card:nth-child(3) h3,
.slab-paint .slab-card:nth-child(8) h3,
.slab-paint .slab-card:nth-child(5) h3{color:#0E1116}
.slab-paint .slab-card:nth-child(3) p,
.slab-paint .slab-card:nth-child(8) p,
.slab-paint .slab-card:nth-child(5) p{color:rgba(14,17,22,.66)}
.slab-paint .slab-card:nth-child(3) .slab-bg,
.slab-paint .slab-card:nth-child(8) .slab-bg,
.slab-paint .slab-card:nth-child(5) .slab-bg{color:#fff;opacity:.75}
.slab-paint .slab-card:nth-child(3) .sc-ic,
.slab-paint .slab-card:nth-child(8) .sc-ic,
.slab-paint .slab-card:nth-child(5) .sc-ic{background:rgba(255,255,255,.7)}
.slab-paint .slab-card:hover{border-color:transparent;box-shadow:0 24px 50px -34px rgba(14,17,22,.32)}

/* news rows mirror the wallet's numbers section exactly: arrow + big year +
   small accent month on the left, headline on the right, hairline between rows */
.news-list{border-top:1px solid var(--line)}
.news-item{display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,1fr);
  gap:clamp(24px,4.6vw,68px);align-items:center;padding:clamp(26px,3vw,44px) 0;
  border-bottom:1px solid var(--line)}
.news-num{display:flex;align-items:center;gap:clamp(14px,2vw,26px)}
.news-fig{font-family:var(--font-display);font-size:clamp(58px,9vw,140px);font-weight:800;
  line-height:.85;letter-spacing:-.05em;color:#A9ADB2;transition:color .2s var(--ease)}
.news-item:hover .news-fig{color:var(--ink)}
.news-unit{font-family:var(--font-label);font-style:normal;font-size:12px;font-weight:400;
  letter-spacing:.1em;text-transform:uppercase;color:var(--cyan-deep);white-space:nowrap}
.news-item h4{font-family:var(--font-body);font-weight:500;font-size:clamp(1rem,1.35vw,1.11rem);
  line-height:1.5;color:var(--slate);margin:0;max-width:none}
@media(max-width:860px){
  .news-item{grid-template-columns:1fr;gap:14px}
}

/* ---- why-cloudworks hero: a glass office tower on the shared .m3d rig ---- */
.hero-fx--office3d .m3d-stage{position:absolute;left:75%;top:52%;width:0;height:0;perspective:2000px}
.hero-fx--office3d .m3d{animation-duration:58s}
/* glass shell: barely-there faces, one hairline edge to read as a volume */
.o-glass>i{background:rgba(122,200,240,.028);box-shadow:inset 0 0 0 1px rgba(150,215,245,.13)}
.o-glass .f-top{background:linear-gradient(150deg,rgba(122,226,255,.09),rgba(18,44,66,.05))}
.o-core>i{background:rgba(14,36,56,.26)}
.o-core .f-top{background:linear-gradient(150deg,rgba(122,226,255,.12),rgba(14,36,56,.14))}
.o-slab>i{background:rgba(16,42,64,.32)}
.o-slab .f-top{background:linear-gradient(150deg,rgba(122,226,255,.15),rgba(14,38,58,.19))}
.o-plinth>i,.o-plinth2>i{background:rgba(10,28,44,.42)}
.o-plinth .f-top,.o-plinth2 .f-top{background:linear-gradient(150deg,rgba(122,226,255,.12),rgba(10,28,44,.2))}
.o-cap .f-top{background:linear-gradient(150deg,rgba(170,224,250,.26),rgba(20,50,74,.18))}
.o-mast>i{background:rgba(122,226,255,.4)}
.o-desk .f-top{background:linear-gradient(150deg,rgba(150,212,244,.24),rgba(18,46,70,.16))}
.o-desk>i{background:rgba(16,42,64,.3)}
/* stairs + landings */
.o-step>i,.o-landing>i{background:rgba(16,44,66,.34)}
.o-step .f-top,.o-landing .f-top{background:linear-gradient(150deg,rgba(122,226,255,.20),rgba(14,38,58,.16))}
/* lift shafts and cabs */
.o-shaft>i{background:rgba(122,200,240,.035);box-shadow:inset 0 0 0 1px rgba(150,215,245,.12)}
.o-lift>i{background:rgba(122,226,255,.30);box-shadow:inset 0 0 0 1px rgba(180,235,255,.45)}
.o-lift .f-top{background:linear-gradient(150deg,rgba(180,235,255,.42),rgba(20,90,130,.3))}

/* people as silhouettes: the four side faces carry a masked figure, so the
   shape reads from any angle as the tower turns */
.o-person>i{background:rgba(178,226,250,.85);box-shadow:none;
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%20112%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%225%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2232%22%20cy%3D%2216%22%20r%3D%2212%22%2F%3E%3Cpath%20d%3D%22M12%2074V50a20%2020%200%200%201%2040%200v24%22%2F%3E%3Cpath%20d%3D%22M24%2056v50M40%2056v50%22%2F%3E%3Cpath%20d%3D%22M32%2070v36%22%2F%3E%3C%2Fsvg%3E");mask-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%20112%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%225%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2232%22%20cy%3D%2216%22%20r%3D%2212%22%2F%3E%3Cpath%20d%3D%22M12%2074V50a20%2020%200%200%201%2040%200v24%22%2F%3E%3Cpath%20d%3D%22M24%2056v50M40%2056v50%22%2F%3E%3Cpath%20d%3D%22M32%2070v36%22%2F%3E%3C%2Fsvg%3E");
  -webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:bottom center;mask-position:bottom center}
.o-person .ft{display:none}

/* motion: people shift their weight, lifts run the shafts, screens breathe.
   All transform/opacity only, and driven by the independent translate
   property so it composes with .cub's own translate3d. */
@keyframes deskBob{0%,100%{translate:0 0 0}50%{translate:0 -3px 0}}
@keyframes liftA{0%{translate:0 150px 0}42%{translate:0 -120px 0}52%{translate:0 -120px 0}94%{translate:0 150px 0}100%{translate:0 150px 0}}
@keyframes liftB{0%{translate:0 -110px 0}46%{translate:0 140px 0}56%{translate:0 140px 0}96%{translate:0 -110px 0}100%{translate:0 -110px 0}}
@keyframes scrGlow{0%,100%{opacity:.55}50%{opacity:1}}
.o-person{animation:deskBob 3.6s ease-in-out infinite;animation-delay:calc(var(--i,0) * -.42s)}
.o-lift.lift-a{animation:liftA 13s cubic-bezier(.45,0,.3,1) infinite}
.o-lift.lift-b{animation:liftB 16s cubic-bezier(.45,0,.3,1) infinite}
.o-screen .f-front{background:linear-gradient(160deg,rgba(122,226,255,.55),rgba(20,120,170,.28));
  animation:scrGlow 4.2s ease-in-out infinite;animation-delay:calc(var(--i,0) * -.7s)}
.o-screen>i{background:rgba(16,44,68,.4)}
@media(prefers-reduced-motion:reduce){
  .o-person,.o-lift,.o-screen .f-front{animation:none}
}
/* the cluster: a ground plate and flat links between towers. Each link is one
   element rotated about Y so it points at its partner; the bar and its pulse
   are laid flat with rotateX(90deg). */
.o-ground>i{background:rgba(10,26,42,.34)}
.o-ground .f-top{background:linear-gradient(150deg,rgba(122,226,255,.09),rgba(10,26,42,.14))}
.o-link{position:absolute;left:0;top:0;width:0;height:0;transform-style:preserve-3d;
  transform:translate3d(var(--x),var(--y),var(--z)) rotateY(var(--ry))}
.o-link>i{display:block;position:absolute;left:0;top:0;height:2px;
  width:var(--len);margin:-1px 0 0 calc(var(--len) / -2);transform:rotateX(90deg)}
.o-link .lk{background:linear-gradient(90deg,rgba(122,226,255,0),rgba(122,226,255,.42) 18%,rgba(122,226,255,.42) 82%,rgba(122,226,255,0))}
.o-link .pulse{background:linear-gradient(90deg,rgba(122,226,255,0),rgba(190,240,255,.95),rgba(122,226,255,0));
  width:calc(var(--len) * .22);animation:linkPulse 4.6s linear infinite;
  animation-delay:calc(var(--i,0) * -.62s)}
@keyframes linkPulse{
  from{translate:calc(var(--len) * -.5) 0 0;opacity:0}
  12%{opacity:1}
  88%{opacity:1}
  to{translate:calc(var(--len) * .5) 0 0;opacity:0}
}
@media(prefers-reduced-motion:reduce){.o-link .pulse{animation:none;opacity:0}}

/* core values: reference palette with each card's own icon repeated behind it */
.corevals .coreval{position:relative;overflow:hidden;isolation:isolate}
.cv-bg{position:absolute;right:-16px;bottom:-20px;z-index:-1;pointer-events:none;
  width:132px;height:132px;display:block}
.cv-bg svg{width:100%;height:100%;fill:none;stroke:currentColor;
  stroke-linecap:round;stroke-linejoin:round}
.cv-bg svg *{vector-effect:non-scaling-stroke;stroke-width:1}
.corevals .coreval:nth-child(1){background:#1D242B;border-color:transparent}
.corevals .coreval:nth-child(1) h3{color:#fff}
.corevals .coreval:nth-child(1) p{color:rgba(255,255,255,.68)}
.corevals .coreval:nth-child(1) .cv-bg{color:#fff;opacity:.22}
.corevals .coreval:nth-child(1) .cv-ico{background:rgba(255,255,255,.12)}
.corevals .coreval:nth-child(1) .cv-ico svg{stroke:#fff}
.corevals .coreval:nth-child(2),
.corevals .coreval:nth-child(4){background:#8FD5E8;border-color:transparent}
.corevals .coreval:nth-child(2) h3,
.corevals .coreval:nth-child(4) h3{color:#0E1116}
.corevals .coreval:nth-child(2) p,
.corevals .coreval:nth-child(4) p{color:rgba(14,17,22,.7)}
.corevals .coreval:nth-child(2) .cv-bg,
.corevals .coreval:nth-child(4) .cv-bg{color:#fff;opacity:.55}
.corevals .coreval:nth-child(2) .cv-ico,
.corevals .coreval:nth-child(4) .cv-ico{background:rgba(255,255,255,.5)}
.corevals .coreval:nth-child(2) .cv-ico svg,
.corevals .coreval:nth-child(4) .cv-ico svg{stroke:#0B3B4A}
.corevals .coreval:nth-child(3){background:#DCE2E7;border-color:transparent}
.corevals .coreval:nth-child(3) h3{color:#0E1116}
.corevals .coreval:nth-child(3) p{color:rgba(14,17,22,.66)}
.corevals .coreval:nth-child(3) .cv-bg{color:#fff;opacity:.75}
.corevals .coreval:nth-child(3) .cv-ico{background:rgba(255,255,255,.7)}


/* challenge + solution as one horizontal pair, ribbon art across both cards */
.duo-cards{margin-top:clamp(1.8rem,3vw,2.6rem);display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(16px,2vw,24px);align-items:stretch}
.duo-card{position:relative;overflow:hidden;isolation:isolate;display:flex;flex-direction:column;
  gap:clamp(1rem,1.8vw,1.4rem);padding:clamp(1.7rem,3vw,2.4rem);border-radius:var(--r-lg);background:#DCE2E7}
.duo-card--dark{background:#1D242B}
.duo-pair{align-items:stretch}
.duo-pair .duo-card{gap:clamp(.85rem,1.4vw,1.1rem);justify-content:flex-start;text-align:center;
  align-items:center;padding:clamp(1.9rem,3.2vw,2.8rem)}
.duo-pair .duo-card::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("assets/wisp.svg") center/cover no-repeat}
.duo-card--slate{background:#C3CCD9}
.duo-eyebrow{font-family:var(--font-display);font-weight:600;font-size:clamp(1.25rem,1.9vw,1.6rem);
  letter-spacing:-.02em;color:var(--ink)}
.duo-card--dark .duo-eyebrow{color:#fff}
.duo-h{font-family:var(--font-display);font-weight:600;font-size:clamp(1.3rem,2.1vw,1.8rem);
  line-height:1.14;letter-spacing:-.028em;color:var(--ink);margin:0;text-wrap:balance;max-width:22ch}
.duo-card--dark .duo-h{color:#AFC3E8}
.duo-note{margin:0;font-size:.95rem;line-height:1.55;color:rgba(14,17,22,.6)}
.duo-note--lead{color:rgba(14,17,22,.72)}
.duo-pair .duo-note{max-width:46ch;font-size:.93rem}
.duo-card--dark .duo-note{color:rgba(255,255,255,.6)}
.duo-card--slate .duo-note{color:rgba(14,17,22,.72)}
.duo-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.66rem}
.duo-list li{position:relative;padding-left:1.5rem;font-size:1rem;line-height:1.45;color:rgba(14,17,22,.78)}
.duo-list li::before{content:"";position:absolute;left:2px;top:.34em;width:5px;height:9px;
  border:solid currentColor;border-width:0 1.6px 1.6px 0;transform:rotate(43deg);opacity:.75}
.duo-card--dark .duo-list li{color:rgba(255,255,255,.8)}

/* We Operate / You Own */
.own-card{width:100%;text-align:left;background:#16202C;border-radius:16px;
  padding:clamp(1rem,1.8vw,1.35rem) clamp(1rem,2vw,1.5rem);
  display:grid;grid-template-columns:auto 1fr;gap:clamp(.9rem,2vw,1.4rem);align-items:center}
.own-head{display:flex;flex-direction:column;align-items:center;gap:.4rem;color:#fff}
.own-head b{font-weight:600;font-size:.95rem;white-space:nowrap}
.own-ic{width:28px;height:28px;display:block;color:#AFC3E8}
.own-ic svg{width:100%;height:100%;display:block}
.own-list{margin:0;padding-left:1.15rem;display:grid;gap:.12rem}
.own-list li{font-size:.82rem;line-height:1.42;color:rgba(255,255,255,.82)}
@media(max-width:860px){
  .duo-cards{grid-template-columns:1fr}
  .duo-pair .duo-card{padding:clamp(1.5rem,5vw,2rem)}
  .own-card{grid-template-columns:1fr;gap:.8rem}
  .own-head{flex-direction:row;justify-content:flex-start}
}

/* six feature layers on video-streaming: the .stream palette runs three tones,
   so cards 4-6 repeat it and the sticky tops continue the ladder */
.stream .layer:nth-child(4){--lw:rgba(20,179,214,.15);--badge:#E9F6FA;--ring:#A8E0EE;--glyph:#0C7C95;--base:#1D242B}
.stream .layer:nth-child(5){--lw:rgba(122,226,255,.24);--badge:#EAFAFF;--ring:#9CEAFF;--glyph:#4FC3E6;--base:#8FD5E8}
.stream .layer:nth-child(6){--lw:rgba(169,196,240,.26);--badge:#F3F7FE;--ring:#C8DCFB;--glyph:#8AAAE0;--base:#DCE2E7}
.layer:nth-child(5){top:192px}.layer:nth-child(6){top:216px}
.stream .layer:nth-child(4)::after{opacity:.26}
.stream .layer:nth-child(4) h3{color:#fff}
.stream .layer:nth-child(4) .layer-main p{color:rgba(255,255,255,.72)}
.stream .layer:nth-child(4) .lay{color:#7AE2FF}
.stream .layer:nth-child(4) .chip{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.22);color:rgba(255,255,255,.9)}
.stream .layer:nth-child(4) .layer-main .textlink.cy{color:#7AE2FF}
.stream .layer:nth-child(4) .layer-main .textlink.cy:hover{color:#fff}
.stream .layer:nth-child(4) .layer-ic{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.24);color:#7AE2FF}
.stream .layer:nth-child(4) .layer-ix .depth i{background:rgba(255,255,255,.22)}
.stream .layer:nth-child(4) .layer-ix .depth i.on{background:#7AE2FF}

/* big ghosted index on each feature layer, counter-driven so it follows the DOM */
#features .solutions{counter-reset:layernum}
#features .layer{counter-increment:layernum}
#features .layer::before{content:counter(layernum,decimal-leading-zero);
  position:absolute;right:clamp(-10px,1vw,18px);bottom:clamp(-28px,-2vw,-10px);z-index:0;
  pointer-events:none;font-family:var(--font-display);font-weight:800;
  font-size:clamp(140px,17vw,260px);line-height:.78;letter-spacing:-.06em;
  color:#0E1116;opacity:.05}
#features .layer:nth-child(1)::before,
#features .layer:nth-child(4)::before{color:#fff;opacity:.07}
@media(max-width:760px){#features .layer::before{font-size:clamp(110px,26vw,150px);opacity:.04}}

/* the commercial chart is line art, not a mesh panel: no tinted plate behind it */
.model-ill.is-chart{background:none;padding:0;border-radius:0;aspect-ratio:auto}
.model-ill.is-chart img{width:100%;height:auto;display:block}
.model-ill.is-chart svg.cm-chart{width:100%;height:auto;display:block;overflow:visible}

/* brand-cyan CTA on the PAI hero (the PAI scope's own --primary is blue) */
body.pai .pai-scope .btn.btn-brand-cta{background:#14B3D6;color:#04141a;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 10px 28px -12px rgba(20,179,214,.75)}
body.pai .pai-scope .btn.btn-brand-cta:hover{background:#2BC0E0}
body.pai .pai-scope .btn.btn-brand-cta .btn-arrow{background:rgba(4,20,26,.16)}


/* on-demand screen sitting in the model panel, bleeding off the right edge so
   only the left half of the UI is in frame */
/* flex + flex-start pins the screen to the left edge; as a block child a
   178%-wide box was being centred, which cropped the wrong side */
.model-ill.is-screen{background:none;padding:0;border-radius:0;aspect-ratio:auto;
  overflow:hidden;position:relative;display:flex;justify-content:flex-start;align-items:center}
.od-screen{width:100%;max-width:none;background:#0B0D10;border-radius:18px;
  padding:clamp(14px,1.5vw,20px);box-shadow:0 40px 90px -46px rgba(14,17,22,.6),0 0 0 1px rgba(14,17,22,.08)}
.od-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:12px}
.od-head b{color:#fff;font-family:var(--font-display);font-weight:600;font-size:1rem;letter-spacing:-.01em}
.od-chips{display:inline-flex;gap:7px}
.od-chips i{font-style:normal;font-size:.72rem;font-weight:600;color:rgba(255,255,255,.66);
  border:1px solid rgba(255,255,255,.16);border-radius:999px;padding:.26rem .68rem}
.od-chips i.on{background:var(--cyan);border-color:transparent;color:#04141a}
.od-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.od-tile{position:relative;display:block;border-radius:10px;overflow:hidden;aspect-ratio:16/10;
  background:#151A1F;box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}
.od-tile img{width:100%;height:100%;object-fit:cover;display:block}
.od-tile.is-live{box-shadow:inset 0 0 0 2px var(--cyan)}
.od-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.94);color:#0a2c4c;box-shadow:0 8px 20px -6px rgba(0,0,0,.5)}
.od-play svg{width:16px;height:16px;margin-left:1px}
@media(max-width:900px){.od-screen{width:130%}}
/* grey line TV bezel around the screen, and the whole panel dissolves into the
   page on the right rather than ending on a hard crop */
.od-tv{flex:0 0 auto;width:178%;padding:clamp(10px,1vw,14px);border-radius:22px;
  border:1px solid rgba(14,17,22,.20);background:#fff;
  box-shadow:0 30px 70px -50px rgba(14,17,22,.35)}
.od-tv .od-screen{border-radius:14px;box-shadow:none}
.model-ill.is-screen{
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 48%,rgba(0,0,0,.35) 82%,transparent 99%);
          mask-image:linear-gradient(90deg,#000 0,#000 48%,rgba(0,0,0,.35) 82%,transparent 99%)}
/* a bare clip inside the TV bezel, same frame + right-edge fade as the on-demand screen */
.od-tv .tv-media{width:100%;height:auto;display:block;border-radius:14px}


/* ---- duo-pair refinement: the site's own tokens, elevated with machined depth
   (nested bezel, concentric radii, inset highlight) and a staggered reveal ---- */
#challenge{padding-top:clamp(3rem,6vw,5.5rem);padding-bottom:clamp(3rem,6vw,5.5rem)}
.duo-pair{gap:clamp(18px,2.2vw,28px)}
/* outer shell read: hairline ring + soft tinted lift + top highlight, no hard border */
.duo-pair .duo-card{border:0;border-radius:var(--r-lg);
  padding:clamp(1.5rem,2.6vw,2.3rem);
  box-shadow:0 0 0 1px rgba(14,17,22,.05),0 40px 90px -60px rgba(14,40,58,.5)}
.duo-card--dark{box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 0 0 1px rgba(255,255,255,.05),0 44px 90px -56px rgba(0,0,0,.7)}
.duo-card--slate{box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 0 0 1px rgba(14,17,22,.06),0 40px 90px -60px rgba(14,40,58,.4)}
/* eyebrow -> the site's mono label, not a heading */
.duo-eyebrow{font-family:var(--font-label);font-size:.72rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;line-height:1}
.duo-card--dark .duo-eyebrow{color:#7AE2FF}
.duo-card--slate .duo-eyebrow{color:var(--cyan-deep)}
.duo-h{font-size:clamp(1.4rem,2.15vw,1.9rem);margin-top:.55rem}
/* inner cores: We Operate / You Own as concentric bezelled panels */
.own-card{border-radius:calc(var(--r-lg) - 6px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 0 0 1px rgba(255,255,255,.05)}
.own-ic{border-radius:50%;background:rgba(122,226,255,.10);width:38px;height:38px;
  padding:8px;box-sizing:border-box;box-shadow:inset 0 0 0 1px rgba(122,226,255,.20)}
/* staggered reveal: right card and the inner panels cascade behind the left */
.duo-pair .duo-card:nth-child(2){transition-delay:.08s}
.own-card{opacity:0;transform:translateY(16px);transition:opacity .7s var(--spring),transform .7s var(--spring)}
.duo-card.in .own-card{opacity:1;transform:none}
.duo-card.in .own-card:nth-of-type(1){transition-delay:.16s}
.duo-card.in .own-card:nth-of-type(2){transition-delay:.26s}
@media(prefers-reduced-motion:reduce){
  .own-card{opacity:1;transform:none;transition:none}
}

/* ---- duo-pair: dark left / grey right, mesh fading up from the bottom, eyebrow
   as a pill at the top. ---- */
.duo-pair .duo-card{background:#1D242B;box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 0 0 1px rgba(255,255,255,.05),0 44px 90px -56px rgba(0,0,0,.7)}
.duo-pair .duo-card--slate{background:#DCE2E7;box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 0 0 1px rgba(14,17,22,.06),0 40px 90px -60px rgba(14,40,58,.4)}
/* mesh only at the bottom, faded up (top transparent) */
.duo-pair .duo-card::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("sov-mesh.webp") center/cover no-repeat;opacity:.9;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,transparent 22%,#000 100%);
          mask-image:linear-gradient(180deg,transparent 0,transparent 22%,#000 100%)}
.duo-card--dark::before{opacity:.5;mix-blend-mode:screen}

/* Eyebrow -> a tab straddling the card's top edge, half in and half out.

   That needs the card to stop clipping, which is what was holding the mesh
   inside its rounded corners — so the mesh layer takes the radius itself and
   the card lets things out. The pill leaves the flow, so the card gains top
   padding to keep the heading off the edge it used to sit above. */
.duo-pair .duo-card{overflow:visible;padding-top:clamp(2.6rem,4.4vw,3.6rem)}
.duo-pair .duo-card::before{border-radius:inherit}
.duo-pair .duo-eyebrow{position:absolute;top:0;left:50%;z-index:2;
  transform:translate(-50%,-50%);white-space:nowrap}
.duo-eyebrow{align-self:center;display:inline-flex;border-radius:999px;padding:.42rem .95rem;
  font-family:var(--font-label);font-size:.66rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;line-height:1}
/* Opaque, both of them. A 12% cyan wash was right while the pill sat inside
   the dark card — it read as a tint of the surface under it. Straddling the
   edge, half of it is over the white page, and a 12% fill there is a ghost
   with unreadable cyan type on it. Each pill now takes its own card's colour
   so the half that overhangs still reads as part of that card. */
.duo-card--dark .duo-eyebrow{background:#1D242B;color:#7AE2FF;
  box-shadow:inset 0 0 0 1px rgba(122,226,255,.34)}
.duo-card--slate .duo-eyebrow{background:#fff;color:var(--cyan-deep);
  box-shadow:inset 0 0 0 1px rgba(14,147,178,.22)}

/* dark card text light, grey card text ink */
.duo-card--dark .duo-h{color:#fff}
.duo-card--dark .duo-note,.duo-card--dark .duo-note--lead{color:rgba(255,255,255,.72)}
.duo-card--slate .duo-h{color:var(--ink)}
.duo-card--slate .duo-note,.duo-card--slate .duo-note--lead{color:rgba(14,17,22,.72)}

/* We Operate / You Own: frosted white glass on the grey card */
.own-card{background:rgba(255,255,255,.22);box-shadow:inset 0 0 0 1px #fff;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-radius:24px;padding:8px;
  grid-template-columns:auto 1fr;gap:0;align-items:stretch}
.own-inner{display:grid;grid-template-columns:auto 1fr;gap:clamp(.9rem,2vw,1.4rem);align-items:center;
  width:100%;background:rgba(255,255,255,.85);border-radius:18px;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.5);padding:clamp(1rem,1.8vw,1.35rem) clamp(1rem,2vw,1.4rem)}
.own-head{color:var(--ink)}
.own-ic{background:rgba(20,179,214,.12);color:var(--cyan-deep);box-shadow:inset 0 0 0 1px rgba(20,179,214,.22)}
.own-list li{color:rgba(14,17,22,.74)}
@media(prefers-reduced-motion:reduce){.own-card{transition:none}}
/* PS-BRAND-STORY : Perception Stream brand-led opening (glass mark hero + parent/tier architecture) */
:root{ --ent:#144ED6; --ent-soft:#4E8ADF; --pc-line:rgba(14,17,22,.16); }

/* hero: two columns, the glass brand mark is the visual focus */
.ps-hero-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.8fr);align-items:center;gap:clamp(1.6rem,5vw,4.5rem)}
.ps-hero-copy{position:relative;z-index:2}
.ps-hero .crumbs{margin-bottom:1.15rem}
.ps-hero h1{font-size:clamp(2.6rem,6vw,4.7rem);letter-spacing:-.04em}
.ps-hero .lead{margin-top:1.2rem;max-width:52ch}
.ps-hero .page-cta{margin-top:clamp(1.5rem,3vw,2.2rem);display:flex;gap:.7rem;flex-wrap:wrap}
.ps-hero-art{position:relative;display:flex;align-items:center;justify-content:center;min-height:clamp(230px,32vw,400px)}
.ps-hero-art::before{content:"";position:absolute;width:74%;aspect-ratio:1;border-radius:50%;z-index:0;
  background:radial-gradient(circle,rgba(20,179,214,.5),rgba(20,179,214,.1) 46%,transparent 70%)}
.ps-hero-art img{position:relative;z-index:1;width:min(100%,430px);height:auto;
  filter:drop-shadow(0 34px 60px rgba(20,179,214,.4)) drop-shadow(0 10px 24px rgba(0,0,0,.42));
  animation:psFloat 7.5s var(--ease) infinite}
@keyframes psFloat{0%,100%{transform:translateY(0) rotate(-.6deg)}50%{transform:translateY(-15px) rotate(.6deg)}}
@media(max-width:900px){
  .ps-hero-grid{grid-template-columns:1fr;gap:1rem}
  .ps-hero-art{order:-1;min-height:0}
  .ps-hero-art img{width:min(62%,280px)}
  .ps-hero-art::before{width:60%}
}

/* brand architecture: parent platform -> two product tiers */
.ps-arch .head-2{max-width:none}
.ps-arch .head-2 .lead{max-width:74ch}
.ps-tree{margin-top:clamp(2.2rem,4vw,3.4rem);display:flex;flex-direction:column;align-items:center}
.ps-parent{display:inline-flex;flex-direction:column;align-items:center;gap:.75rem;
  padding:clamp(1.1rem,2vw,1.5rem) clamp(1.7rem,3.4vw,2.6rem);border-radius:var(--r-lg);
  background:var(--glass);box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:blur(16px) saturate(150%);backdrop-filter:blur(16px) saturate(150%)}
.ps-parent-logo{height:clamp(32px,3.3vw,46px);width:auto;display:block}
.ps-parent-tag{font-family:var(--font-label);font-size:.68rem;letter-spacing:.17em;text-transform:uppercase;color:var(--steel)}
.ps-links{position:relative;width:100%;height:clamp(40px,5.5vw,60px)}
.pl-stem{position:absolute;left:50%;top:0;width:1.5px;height:46%;background:var(--pc-line);transform:translateX(-.75px)}
.pl-bar{position:absolute;left:25%;right:25%;top:46%;height:1.5px;background:var(--pc-line)}
.pl-drop{position:absolute;top:46%;bottom:0;width:1.5px;background:var(--pc-line)}
.pl-l{left:25%}.pl-r{right:25%}
.pl-l::after,.pl-r::after{content:"";position:absolute;left:50%;bottom:-3px;width:7px;height:7px;border-radius:50%;transform:translateX(-50%)}
.pl-l::after{background:var(--cyan)}.pl-r::after{background:var(--ent)}
.ps-tiers{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:clamp(16px,2.2vw,26px)}
.ps-tier{position:relative;overflow:hidden;isolation:isolate;display:flex;flex-direction:column;gap:1rem;
  padding:clamp(1.6rem,2.8vw,2.4rem);border-radius:var(--r-lg);text-decoration:none;color:inherit;
  background:var(--paper);box-shadow:var(--glass-shadow);
  transition:transform .5s var(--ease),box-shadow .5s var(--ease)}
.ps-tier::before{content:"";position:absolute;inset:0 0 auto 0;height:4px;z-index:2}
.ps-tier--core::before{background:linear-gradient(90deg,var(--cyan),var(--sky))}
.ps-tier--ent::before{background:linear-gradient(90deg,var(--ent),var(--ent-soft))}
.ps-tier::after{content:"";position:absolute;right:-46px;bottom:-56px;width:210px;height:210px;z-index:-1;
  border-radius:50%;opacity:.09}
.ps-tier--core::after{background:radial-gradient(circle,var(--cyan),transparent 68%)}
.ps-tier--ent::after{background:radial-gradient(circle,var(--ent),transparent 68%)}
.ps-tier:hover{transform:translateY(-6px);box-shadow:var(--shadow-lg)}
.ps-tier-tag{font-family:var(--font-label);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;color:var(--steel)}
.ps-tier-logo{height:clamp(30px,3vw,40px);width:auto;align-self:flex-start}
.ps-tier-desc{margin:0;font-size:clamp(1rem,1.3vw,1.14rem);line-height:1.5;color:var(--slate);max-width:34ch}
.ps-tier-go{margin-top:auto;display:inline-flex;align-items:center;gap:.4rem;font-family:var(--font-label);font-weight:600;font-size:.92rem}
.ps-tier-go svg{width:18px;height:18px;transition:transform .4s var(--ease)}
.ps-tier--core .ps-tier-go{color:var(--cyan-deep)}
.ps-tier--ent .ps-tier-go{color:var(--ent)}
.ps-tier:hover .ps-tier-go svg{transform:translateX(4px)}
@media(max-width:760px){
  .ps-tiers{grid-template-columns:1fr}
  .ps-links{display:none}
  .ps-tree{gap:1.1rem}
}

/* PS-PRODUCTS : Perception Stream — brand intro + two product-tier sections */
.ps-intro .head-2{max-width:none}
.ps-intro .head-2 .lead{max-width:74ch}
.ps-intro .ps-parent{margin:clamp(1.8rem,3.4vw,2.8rem) auto 0}

/* product-tier section: text + brand panel, alternating sides */
.ps-prod{--tier:var(--cyan);--tier-tint:rgba(20,179,214,.14);--tier-glow:rgba(20,179,214,.5)}
.ps-prod--ent{--tier:var(--ent);--tier-tint:rgba(20,78,214,.13);--tier-glow:rgba(20,78,214,.45)}
.ps-prod-grid{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);gap:clamp(2rem,5vw,4.5rem);align-items:center}
.ps-prod--flip .ps-prod-art{order:-1}
.ps-prod-copy{position:relative}
.ps-prod-num{display:inline-flex;align-items:baseline;font-family:var(--font-label);font-weight:600;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--steel)}
.ps-prod-num b{font-family:var(--font-display);font-size:1.05rem;letter-spacing:-.01em;color:var(--tier)}
.ps-prod-logo{height:clamp(30px,3.3vw,44px);width:auto;display:block;margin:.85rem 0 1.15rem}
.ps-prod-lede{margin:0;font-size:clamp(1.08rem,1.5vw,1.32rem);line-height:1.5;letter-spacing:-.01em;color:var(--ink);max-width:44ch;text-wrap:pretty}
.ps-prod-lede strong{color:var(--tier)}
.ps-prod-list{list-style:none;margin:1.3rem 0 1.7rem;padding:0;display:grid;gap:.62rem}
.ps-prod-list li{position:relative;padding-left:2rem;font-size:1rem;line-height:1.45;color:var(--slate)}
.ps-prod-list li::before{content:"";position:absolute;left:0;top:.05em;width:1.25rem;height:1.25rem;border-radius:50%;background:var(--tier-tint)}
.ps-prod-list li::after{content:"";position:absolute;left:.44rem;top:.34em;width:.3rem;height:.6rem;border:solid var(--tier);border-width:0 2px 2px 0;transform:rotate(43deg)}
.ps-prod-cta{display:flex;gap:.7rem;flex-wrap:wrap}
.ps-prod--core .ps-prod-cta .btn-primary{background:linear-gradient(180deg,#2bc0e0,var(--cyan));box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 12px 30px -14px rgba(20,179,214,.8)}
.ps-prod--ent .ps-prod-cta .btn-primary{background:linear-gradient(180deg,#3f74e6,var(--ent));box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 12px 30px -14px rgba(20,78,214,.8)}

/* brand panel: the glass mark on a tinted plate (no product visuals) */
.ps-prod-art{position:relative}
.ps-panel{position:relative;overflow:hidden;isolation:isolate;border-radius:var(--r-lg);
  min-height:clamp(300px,33vw,440px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1.4rem;
  box-shadow:var(--glass-shadow)}
.ps-panel--core{background:linear-gradient(158deg,rgba(20,179,214,.12),rgba(122,226,255,.05) 60%,rgba(240,244,251,.6))}
.ps-panel--ent{background:linear-gradient(158deg,rgba(20,78,214,.12),rgba(78,138,223,.05) 60%,rgba(240,244,251,.6))}
.ps-panel::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(14,17,22,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(14,17,22,.04) 1px,transparent 1px);
  background-size:38px 38px;-webkit-mask-image:radial-gradient(80% 80% at 50% 42%,#000 20%,transparent 78%);mask-image:radial-gradient(80% 80% at 50% 42%,#000 20%,transparent 78%)}
.ps-panel-glow{position:absolute;top:38%;left:50%;transform:translate(-50%,-50%);width:74%;aspect-ratio:1;border-radius:50%;z-index:0;
  background:radial-gradient(circle,var(--tier-glow),transparent 66%);filter:blur(6px);opacity:.7}
.ps-panel-mark{position:relative;z-index:1;width:min(60%,290px);height:auto;
  filter:drop-shadow(0 26px 46px rgba(14,17,22,.22));animation:psFloat 8s var(--ease) infinite}
.ps-panel--ent .ps-panel-mark{filter:hue-rotate(32deg) saturate(1.18) drop-shadow(0 26px 46px rgba(14,17,22,.24))}
.ps-panel-cap{position:relative;z-index:1;font-family:var(--font-label);font-weight:600;font-size:.72rem;letter-spacing:.17em;text-transform:uppercase;color:var(--steel)}

@media(max-width:900px){
  .ps-prod-grid{grid-template-columns:1fr;gap:clamp(1.4rem,4vw,2.2rem)}
  .ps-prod--flip .ps-prod-art{order:0}          /* text first on mobile for both */
  .ps-prod-lede{max-width:none}
  .ps-panel{min-height:clamp(240px,60vw,320px)}
}

/* PS-HERO-VIDEO : animated brand mark (black bg dropped via screen blend) + floating tier pills */
.ps-hero-art{overflow:visible}
.ps-hero-art .ps-hero-video{
  position:relative;z-index:1;width:min(118%,560px);height:auto;
  mix-blend-mode:screen;                 /* black background disappears on the dark hero */
  filter:none;
  animation:psFloat 8s var(--ease) infinite;
}
.ps-hero-art::before{opacity:.55}        /* soft cyan bed stays behind the mark */
.ps-hero-pill{
  position:absolute;z-index:3;display:inline-flex;align-items:center;
  padding:.52rem .9rem;border-radius:var(--pill);
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:blur(15px) saturate(165%);backdrop-filter:blur(15px) saturate(165%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 0 0 1px rgba(255,255,255,.55),0 20px 44px -20px rgba(0,0,0,.55);
  animation:psFloat 6.5s var(--ease) infinite;
}
.ps-hero-art .ps-hero-pill img{width:auto;height:21px;filter:none;animation:none;position:relative;z-index:1;display:block}
.ps-hero-pill--core{top:12%;left:-5%;animation-delay:-1s}
.ps-hero-pill--ent{bottom:15%;right:-3%;animation-delay:-3.3s}
@media(max-width:900px){
  .ps-hero-art .ps-hero-video{width:min(84%,340px)}
  .ps-hero-pill{padding:.42rem .72rem}
  .ps-hero-art .ps-hero-pill img{height:16px}
  .ps-hero-pill--core{top:4%;left:2%}
  .ps-hero-pill--ent{bottom:4%;right:2%}
}

/* PS-HERO-VIDEO-MASK */
.ps-hero-art .ps-hero-video{-webkit-mask-image:radial-gradient(74% 76% at 50% 46%,#000 48%,transparent 84%);mask-image:radial-gradient(74% 76% at 50% 46%,#000 48%,transparent 84%)}

/* PS-HERO-SAT : smaller central mark + larger tier pills as connected satellites */
.ps-hero-art{overflow:visible}
.ps-hero-art .ps-hero-video{width:min(66%,320px);z-index:2;animation:psFloatSm 8.5s var(--ease) infinite}
@keyframes psFloatSm{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}

/* orbit ring + connector lines behind the mark */
.ps-orbit{position:absolute;inset:0;width:100%;height:100%;z-index:1;pointer-events:none;overflow:visible}
.ps-orbit-ring{fill:none;stroke:rgba(255,255,255,.09);stroke-width:1;stroke-dasharray:2 7;vector-effect:non-scaling-stroke}
.ps-orbit-link{stroke:rgba(122,226,255,.4);stroke-width:1.3;stroke-dasharray:2.5 4.5;vector-effect:non-scaling-stroke;stroke-linecap:round}
.ps-orbit-hub{fill:rgba(122,226,255,.7)}

/* bigger satellite pills, anchored to the orbit endpoints */
.ps-hero-pill{z-index:4;padding:.62rem 1.1rem;gap:.55rem;
  background:rgba(255,255,255,.78);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 0 0 1px rgba(255,255,255,.6),0 22px 50px -20px rgba(0,0,0,.6)}
.ps-hero-art .ps-hero-pill img{height:30px}
.ps-hero-pill--core{left:20%;top:22%;right:auto;bottom:auto;transform:translate(-50%,-50%);animation:psSat 7s var(--ease) infinite}
.ps-hero-pill--ent{left:80%;top:78%;right:auto;bottom:auto;transform:translate(-50%,-50%);animation:psSat 7.8s var(--ease) infinite;animation-delay:-2.6s}
@keyframes psSat{0%,100%{transform:translate(-50%,-50%)}50%{transform:translate(-50%,calc(-50% - 9px))}}

@media(max-width:900px){
  .ps-hero-art{min-height:clamp(240px,64vw,340px)}
  .ps-hero-art .ps-hero-video{width:min(52%,220px)}
  .ps-hero-art .ps-hero-pill img{height:24px}
  .ps-hero-pill{padding:.5rem .85rem}
  .ps-hero-pill--core{left:22%;top:17%}
  .ps-hero-pill--ent{left:78%;top:83%}
}

/* PS-REFINE : equal (un-squished) hero pills · impulse connectors · big tier logos in panels */
/* equal-width pills so both tier logos render full-size and balanced */
.ps-hero-pill{width:166px;justify-content:center}
@media(max-width:900px){.ps-hero-pill{width:138px}}

/* impulse energy flowing along the connectors toward the hub */
.ps-orbit-link{stroke:rgba(122,226,255,.52);stroke-dasharray:2 8;animation:psImpulse 1.4s linear infinite}
@keyframes psImpulse{from{stroke-dashoffset:0}to{stroke-dashoffset:10}}
.ps-orbit-hub{animation:psHub 1.9s var(--ease) infinite}
@keyframes psHub{0%,100%{opacity:.55}50%{opacity:1}}
.ps-orbit-ring{animation:psRing 4.5s var(--ease) infinite}
@keyframes psRing{0%,100%{opacity:.5}50%{opacity:.92}}

/* big Core / Enterprise tier logos inside the product panels */
.ps-panel-logo{position:relative;z-index:1;width:min(76%,320px);height:auto;
  filter:drop-shadow(0 18px 38px rgba(14,17,22,.16));animation:psFloatSm 9s var(--ease) infinite}

/* PS-CONST : static logo composition in the intro (Perception Stream hub + Core/Enterprise satellites) */
.ps-const{position:relative;width:min(600px,94%);aspect-ratio:16/9;margin:clamp(2rem,4vw,3.4rem) auto 0}
.ps-const::before{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:40%;aspect-ratio:1;border-radius:50%;z-index:0;
  background:radial-gradient(circle,rgba(20,179,214,.13),transparent 70%)}
.ps-const-orbit{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:1}
.ps-const-orbit ellipse{fill:none;stroke:rgba(14,17,22,.11);stroke-width:1;stroke-dasharray:2 7;vector-effect:non-scaling-stroke}
.ps-const-orbit line{stroke:rgba(20,179,214,.42);stroke-width:1.3;stroke-dasharray:2.5 4.5;stroke-linecap:round;vector-effect:non-scaling-stroke}
.ps-const-orbit circle{fill:rgba(20,179,214,.55)}
.ps-const-hub,.ps-const-pill{position:absolute;display:inline-flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.92);border-radius:var(--pill);
  box-shadow:inset 0 1px 0 #fff,0 0 0 1px var(--hair),0 22px 48px -22px rgba(14,17,22,.3);
  -webkit-backdrop-filter:blur(8px) saturate(150%);backdrop-filter:blur(8px) saturate(150%)}
.ps-const-hub{left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;padding:.95rem 1.6rem}
.ps-const-hub img{height:clamp(34px,4vw,46px);width:auto;display:block}
.ps-const-pill{z-index:2;width:172px;padding:.6rem 1rem}
.ps-const-pill img{height:30px;width:auto;display:block}
.ps-const-pill--core{left:19%;top:24%;transform:translate(-50%,-50%)}
.ps-const-pill--ent{left:81%;top:76%;transform:translate(-50%,-50%)}
@media(max-width:760px){
  .ps-const{aspect-ratio:3/4;width:100%;max-width:360px}
  .ps-const-hub{padding:.7rem 1.1rem}
  .ps-const-hub img{height:30px}
  .ps-const-pill{width:142px}
  .ps-const-pill img{height:24px}
  .ps-const-pill--core{left:27%;top:17%}
  .ps-const-pill--ent{left:73%;top:83%}
}

/* VS-REFINE : video-streaming — image pillars, stacked horizontal duo cards, checkmark own-lists */
/* B: three image + description cards */
.pill-feats{margin-top:clamp(1.8rem,3vw,2.6rem);display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,2.8vw,38px)}
.pill-feat{display:flex;flex-direction:column;align-items:flex-start;gap:.5rem}
.pill-feat img{width:clamp(104px,10vw,140px);height:auto;margin-bottom:.15rem}
.pill-feat h3{font-family:var(--font-display);font-weight:600;font-size:clamp(1.12rem,1.5vw,1.42rem);letter-spacing:-.02em;color:var(--ink);margin:0}
.pill-feat p{margin:0;font-size:.98rem;line-height:1.52;color:var(--slate);max-width:38ch}
@media(max-width:760px){.pill-feats{grid-template-columns:1fr;gap:1.8rem}}

/* D: the two duo cards side by side, each stacked internally (heading above
   body). They were the other way round — one column of full-width cards, each
   split heading | body — which reads as two consecutive sections rather than
   as a pair being set against each other. Side by side IS the comparison.

   The internal split has to go with it: at half the width there is no room for
   a heading column beside a body column, so each card returns to a stack. The
   two-up lists inside the slate card and the two pans inside the dark one stay
   two-up, because both are themselves comparisons. */
.duo-pair{grid-template-columns:1fr 1fr}
.duo-pair .duo-card{display:flex;flex-direction:column;text-align:left;
  align-items:flex-start;gap:clamp(1.1rem,2vw,1.6rem)}
.duo-lead{display:flex;flex-direction:column;align-items:flex-start;gap:clamp(.7rem,1.4vw,1rem)}
.duo-lead .duo-h{max-width:20ch}
.duo-lead .duo-note{max-width:46ch}
/* Side by side the two cards stretch to a shared height, and the dark one's
   content is the shorter of the two — so its scale used to end mid-card with
   a hand's width of empty under it. margin-top:auto drops the body to the
   floor of whichever card has slack; the card that is already full does not
   move, so this needs no measuring and holds at any width. */
.duo-body{display:grid;gap:clamp(12px,1.6vw,18px);width:100%;margin-top:auto}
.duo-card--slate .duo-body{grid-template-columns:1fr 1fr;align-items:start}
@media(max-width:900px){
  .duo-pair{grid-template-columns:1fr}
  .duo-card--slate .duo-body{grid-template-columns:1fr}
}

/* C: checkmark bullets (not numbers) + a fuller white background */
.own-card{padding:5px}
.own-inner{background:#fff;align-items:start}
.own-list{padding-left:0;list-style:none;gap:.34rem}
.own-list li{position:relative;padding-left:1.55rem}
.own-list li::before{content:"";position:absolute;left:0;top:.14em;width:1.05rem;height:1.05rem;border-radius:50%;
  background:rgba(20,179,214,.14) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%230E93B2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 5 5 9-11"/></svg>') center/.62rem no-repeat}

/* VS-REFINE-2 : bigger pillar images */
.pill-feat img{width:clamp(160px,18vw,224px)}
@media(max-width:760px){.pill-feat img{width:clamp(150px,42vw,200px)}}

/* VS-REFINE-3 : own-card icon/label stacked ABOVE the list */
.own-inner{grid-template-columns:1fr;gap:clamp(.7rem,1.4vw,1rem);align-items:start}
.own-head{flex-direction:row;align-items:center;justify-content:flex-start;gap:.55rem}

/* VS-REFINE-4 : equal image heights so pillar titles/text align */
.pill-feat img{width:auto;height:clamp(150px,17vw,196px);object-fit:contain;object-position:left center}
@media(max-width:760px){.pill-feat img{height:clamp(140px,40vw,190px)}}

/* The pillar features are drawn now, not photographed. One shared viewBox means
   the three scenes already render at the same height, so nothing has to be
   forced to line the headings up — height here is only the display size. */
.pill-feat svg.pill-ill{width:100%;height:auto;display:block;margin:0 0 .35rem;overflow:visible}

/* ---------- Perception AI card: a contained slab, not a full-bleed band.
     Its background stops a little outside the content column rather than running
     to the viewport edge. ---------- */
.pfm-ai{width:calc(100% - clamp(1.25rem,4vw,2.5rem) * 2);
  max-width:calc(var(--wrap) + 88px);margin-inline:auto}


/* =====================================================================
   USER APPLICATIONS — the application suite
   One branded service interface (.ua-ui) shown inside three chromes, so the
   browser, phone and television read as the same product rather than three
   unrelated mockups. The chrome changes; the interface does not.
   ===================================================================== */
/* A self-contained device is shown whole: no right-edge fade, no clipping.
   (.is-screen masks its right edge — that was built for a screen deliberately
   running off the column, which these are not.) */
/* width:100% is load-bearing: under 900px .model-ill takes margin-inline:auto,
   and auto margins make a grid item shrink to its content — which for these
   shells is nothing, since their interface is absolutely positioned. */
.model-ill.is-device{background:none;padding:0;border-radius:0;aspect-ratio:auto;
  width:100%;overflow:visible;display:grid;grid-template-columns:minmax(0,1fr);
  justify-items:center;align-items:center;-webkit-mask-image:none;mask-image:none}

/* consecutive leads need air between them; .lead itself carries no margin */
.head-2 .lead + .lead{margin-top:.85rem}
.model-split.is-rev{grid-template-columns:minmax(0,.8fr) 1fr}
.model-split.is-rev .model-copy{order:2}
.model-split.is-rev .model-ill{order:1}
@media(max-width:860px){
  .model-split.is-rev{grid-template-columns:1fr}
  .model-split.is-rev .model-copy{order:1}
  .model-split.is-rev .model-ill{order:2}
}

/* ---- the device shells ---- */
.dvc{position:relative;width:100%;margin-inline:auto}
.dvc-screen{position:relative;overflow:hidden;background:#0A0D11}
/* a single soft sheen across every screen, so the three read as one family */
.dvc-screen::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3;
  background:linear-gradient(128deg,rgba(255,255,255,.13),rgba(255,255,255,0) 42%)}

/* browser */
.dvc-web{max-width:560px}
.dvc-web .dvc-body{border-radius:14px;overflow:hidden;background:#F2F5F9;
  box-shadow:inset 0 0 0 1px rgba(14,17,22,.08),0 34px 70px -34px rgba(14,17,22,.42),
    0 4px 12px -6px rgba(14,17,22,.18)}
.dvc-bar{display:flex;align-items:center;gap:.55rem;padding:9px 12px;background:#E9EDF3;
  box-shadow:inset 0 -1px 0 rgba(14,17,22,.07)}
.dvc-dots{display:inline-flex;gap:5px;flex:0 0 auto}
.dvc-dots i{width:8px;height:8px;border-radius:50%;background:rgba(14,17,22,.16)}
.dvc-url{flex:1;min-width:0;height:19px;border-radius:99px;background:#fff;
  box-shadow:inset 0 0 0 1px rgba(14,17,22,.07);
  display:flex;align-items:center;padding:0 9px;gap:5px;
  font-size:.6rem;color:var(--steel);letter-spacing:.01em;overflow:hidden;white-space:nowrap}
.dvc-url svg{width:9px;height:9px;flex:0 0 auto;opacity:.55}
/* 16:9, and the captures are cut to 16:9 too (see _shots-webp.js), so the
   picture meets the glass exactly — nothing cropped at render, no pillars. */
.dvc-web .dvc-screen{aspect-ratio:16/9}

/* phone */
.dvc-phone{max-width:248px}
.dvc-phone .dvc-body{border-radius:34px;padding:7px;background:linear-gradient(160deg,#20262E,#0E1216);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 30px 60px -28px rgba(14,17,22,.5)}
/* the phone captures, status and navigation rows already trimmed, are
   576x1154 — the glass takes that shape so the app own bottom bar survives */
.dvc-phone .dvc-screen{border-radius:27px;aspect-ratio:576/1154}
.dvc-notch{position:absolute;z-index:4;left:50%;top:8px;transform:translateX(-50%);
  width:58px;height:15px;border-radius:99px;background:#0A0D11}

/* television */
.dvc-tv{max-width:620px}
.dvc-tv .dvc-body{border-radius:16px;padding:9px;background:linear-gradient(160deg,#252B33,#0F1317);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 40px 76px -36px rgba(14,17,22,.5)}
.dvc-tv .dvc-screen{border-radius:9px;aspect-ratio:16/9}
.dvc-stand{margin:0 auto;width:26%;height:9px;border-radius:0 0 8px 8px;
  background:linear-gradient(180deg,#252B33,#171C22)}
.dvc-stand+.dvc-foot{margin:0 auto;width:44%;height:5px;border-radius:99px;
  background:rgba(14,17,22,.16)}

/* ---- the interface itself ---- */
/* ---- the product screenshots inside the device mock-ups ----
   The captures are laid in a row, one screen wide each, and the row is walked
   left a screen at a time: the page being read holds still, then the next one
   slides in from the right — the way a person would swipe through them. A copy
   of the first capture closes the row, so the last step lands on the frame the
   loop opened with and there is nothing to jump back from.
   Percentages on the row's transform are its own width, and the row is exactly
   one screen wide with its captures overflowing to the right, so -100% is one
   screen however wide the device is drawn.
   The images are cropped to fill the glass: the phone captures have had their
   status and navigation rows trimmed already and start below the frame's own
   notch, while the wider desktop captures are anchored to the top, where the
   product's header is. */
.dvc-shots{position:absolute;inset:0;z-index:2;overflow:hidden}
.dvc-track{position:absolute;inset:0;display:flex;flex-wrap:nowrap;will-change:transform;
  animation-timing-function:cubic-bezier(.5,0,.15,1);animation-iteration-count:infinite}
.dvc-track img{flex:0 0 100%;width:100%;height:100%;display:block;
  object-fit:cover;object-position:top center}
/* nothing for a notch to sit over once the status row is cropped away, and
   the glass now matches the capture exactly, so the deck fills it whole */
.dvc-screen:has(.dvc-shots) .dvc-notch{display:none}
.dvc-shots--4 .dvc-track{animation-name:slide4;animation-duration:20s}
.dvc-shots--5 .dvc-track{animation-name:slide5;animation-duration:25s}
/* each step is a long hold and a short move: the reader gets four fifths of it
   to look at the page and the last fifth to be carried to the next */
@keyframes slide4{
  0%,21%  {transform:translate3d(0,0,0)}
  25%,46% {transform:translate3d(-100%,0,0)}
  50%,71% {transform:translate3d(-200%,0,0)}
  75%,96% {transform:translate3d(-300%,0,0)}
  100%    {transform:translate3d(-400%,0,0)}
}
@keyframes slide5{
  0%,16%  {transform:translate3d(0,0,0)}
  20%,36% {transform:translate3d(-100%,0,0)}
  40%,56% {transform:translate3d(-200%,0,0)}
  60%,76% {transform:translate3d(-300%,0,0)}
  80%,96% {transform:translate3d(-400%,0,0)}
  100%    {transform:translate3d(-500%,0,0)}
}
/* where you are in the set, under the frame. Same clock as the row, and the
   mark changes hands halfway through the slide rather than at either end of
   it, so the pip and the picture agree at every moment you look. */
.dvc-pips{display:flex;justify-content:center;gap:7px;margin-top:16px}
.dvc-pips i{width:6px;height:6px;border-radius:99px;background:rgba(14,17,22,.16);
  animation-timing-function:linear;animation-iteration-count:infinite}
.dvc-pips--4 i{animation-name:pip4;animation-duration:20s;animation-delay:calc(var(--i) * 5s)}
.dvc-pips--5 i{animation-name:pip5;animation-duration:25s;animation-delay:calc(var(--i) * 5s)}
@keyframes pip4{0%,22%{background:var(--cyan)} 24%,100%{background:rgba(14,17,22,.16)}}
@keyframes pip5{0%,17%{background:var(--cyan)} 19%,100%{background:rgba(14,17,22,.16)}}
@media(prefers-reduced-motion:reduce){
  .dvc-track,.dvc-pips i{animation:none}
  .dvc-pips i[style*="--i:0"]{background:var(--cyan)}
}

.ua-ui{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
  padding:clamp(9px,2.1%,15px);gap:clamp(7px,1.6%,11px);
  font-family:var(--font-body);color:#fff}
.ua-bar{display:flex;align-items:center;gap:.5rem;flex:0 0 auto}
.ua-logo{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-display);
  font-weight:600;font-size:.62rem;letter-spacing:-.01em;color:#fff;white-space:nowrap}
.ua-logo svg{width:13px;height:13px;flex:0 0 auto;color:var(--cyan)}
.ua-nav{display:inline-flex;gap:4px;margin-left:auto;min-width:0;overflow:hidden}
.ua-nav i{font-style:normal;font-size:.52rem;font-weight:600;letter-spacing:.02em;
  color:rgba(255,255,255,.6);padding:3px 7px;border-radius:99px;
  background:rgba(255,255,255,.07);white-space:nowrap}
.ua-nav i.on{background:var(--cyan);color:#04141a}
.ua-me{width:14px;height:14px;border-radius:50%;flex:0 0 auto;
  background:linear-gradient(150deg,#7AE2FF,#14B3D6)}

.ua-hero{position:relative;flex:1 1 auto;min-height:0;border-radius:9px;overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
.ua-hero img{width:100%;height:100%;object-fit:cover;display:block}
.ua-hero::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(6,9,12,0) 38%,rgba(6,9,12,.86))}
.ua-badge{position:absolute;z-index:2;left:8px;top:8px;display:inline-flex;align-items:center;gap:4px;
  font-size:.48rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:3px 6px;border-radius:99px;background:#E5484D;color:#fff}
.ua-badge::before{content:"";width:4px;height:4px;border-radius:50%;background:#fff}
.ua-cap{position:absolute;z-index:2;left:9px;right:9px;bottom:8px}
.ua-cap b{display:block;font-family:var(--font-display);font-weight:600;
  font-size:.68rem;letter-spacing:-.01em;line-height:1.2}
.ua-cap span{display:block;font-size:.5rem;color:rgba(255,255,255,.62);margin-top:2px}
.ua-bar-progress{margin-top:5px;height:2.5px;border-radius:99px;background:rgba(255,255,255,.22);overflow:hidden}
.ua-bar-progress i{display:block;height:100%;width:38%;border-radius:99px;background:var(--cyan)}

.ua-rail{flex:0 0 auto}
.ua-rail-t{display:block;font-size:.5rem;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:rgba(255,255,255,.5);margin-bottom:5px}
.ua-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.ua-tiles span{position:relative;display:block;border-radius:6px;overflow:hidden;aspect-ratio:16/10;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09)}
.ua-tiles img{width:100%;height:100%;object-fit:cover;display:block}

/* phone: the same interface, laid out for one thumb */
.dvc-phone .ua-ui{padding:20px 10px 10px;gap:9px}
.dvc-phone .ua-nav{display:none}
.dvc-phone .ua-hero{flex:0 0 34%}
.dvc-phone .ua-rail{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
.dvc-phone .ua-tiles{grid-template-columns:repeat(2,1fr);gap:6px}
.dvc-phone .ua-tabs{margin-top:auto;display:flex;justify-content:space-around;
  padding-top:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}
.dvc-phone .ua-tabs i{font-style:normal;font-size:.44rem;font-weight:600;letter-spacing:.02em;
  color:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;gap:3px}
.dvc-phone .ua-tabs i::before{content:"";width:11px;height:11px;border-radius:3px;
  background:rgba(255,255,255,.28)}
.dvc-phone .ua-tabs i.on{color:var(--cyan)}
.dvc-phone .ua-tabs i.on::before{background:var(--cyan)}
.ua-tabs{display:none}

/* television: fewer, larger things, read from the sofa */
.dvc-tv .ua-ui{padding:13px 15px;gap:10px}
.dvc-tv .ua-logo{font-size:.74rem}
.dvc-tv .ua-nav i{font-size:.58rem;padding:4px 9px}
.dvc-tv .ua-cap b{font-size:.86rem}
.dvc-tv .ua-cap span{font-size:.56rem}
.dvc-tv .ua-tiles{grid-template-columns:repeat(5,1fr)}
.dvc-tv .ua-rail-t{font-size:.54rem}

/* ---- set-top-box call-out ---- */
/* No shadow under this panel: the tint and the hairline carry it, which is
   all a note needs sitting under a full-bleed section. --glass-shadow bundles
   the ring in with the drop, so the two are written out here and only the
   drop and the cyan bloom are dropped. */
.stb-note{display:grid;grid-template-columns:auto 1fr;gap:clamp(1rem,2.4vw,1.8rem);
  align-items:center;padding:clamp(1.4rem,3vw,2.1rem) clamp(1.4rem,3.2vw,2.4rem);
  border-radius:var(--r-lg);background:var(--glass);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px var(--hair)}
/* the box itself, drawn in the projection the server cabinet and the device
   illustrations use — white faces, hairline edges, one cyan tell */
.stb-ill{width:clamp(156px,18vw,216px);height:auto;display:block;flex:0 0 auto;overflow:visible}
@media(max-width:640px){.stb-ill{width:172px}}
.stb-note h3{font-family:var(--font-display);font-weight:500;font-size:clamp(1.05rem,1.7vw,1.28rem);
  letter-spacing:-.015em;margin-bottom:.45rem}
.stb-note p{color:var(--slate);font-size:clamp(.94rem,1.15vw,1.02rem);line-height:1.6;max-width:70ch}
@media(max-width:640px){.stb-note{grid-template-columns:1fr}}

/* ---- the platforms a block is about, under its copy ----
   The ribbon at the top of the page names every screen at once. Each block
   below then carries only its own, in the ribbon's pills at about two thirds
   the size: small enough to read as a caption under the paragraph rather than
   as a second headline, and the same drawing of each platform either way. */
.copy-pills{display:flex;flex-wrap:wrap;gap:.42rem;margin-top:clamp(1.2rem,2.4vw,1.7rem)}
.copy-pills .plat-pill{padding:.3rem .8rem .3rem .42rem;gap:.42rem;font-size:.79rem;
  white-space:nowrap;background:#fff}
.copy-pills .pp-ic{width:28px;height:28px}

/* ---- "one partner" statement ---- */
.partner-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,2.4vw,1.8rem);
  margin-top:clamp(1.8rem,4vw,2.8rem)}
.partner-grid p{color:var(--slate);font-size:clamp(.94rem,1.15vw,1.02rem);line-height:1.62;
  padding-top:1.1rem;box-shadow:inset 0 1px 0 var(--line)}
@media(max-width:820px){.partner-grid{grid-template-columns:1fr}}

/* =====================================================================
   HOMEPAGE — the media journey, and the network stats row
   The journey is a square isometric drawing generated by
   _illustration/journey.js; the rules it needs are here, the rules that
   make it are in _illustration/STYLE.md. Colour lives in SVG gradients,
   so this block only sizes the drawing and types its glass overlays.
   ===================================================================== */
.jrn{position:relative}
.jrn-svg{width:100%;height:auto;display:block;overflow:visible}

/* label pills and tooltips are UI laid over the isometry: screen-aligned,
   set in the site's own faces rather than the drawing's line weight */
.jrn-lbl{font-family:var(--font-label);font-size:11.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;fill:var(--ink);fill-opacity:.78}
.jrn-mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size:10.5px;letter-spacing:.04em;fill:var(--ink);fill-opacity:.62}
/* an axis caption set INTO the drawing rather than over it: the transform puts
   it in the ground plane, so it takes the drawing's quiet ink rather than the
   pill's UI weight */
.cm-axis{font-family:var(--font-label);font-size:11px;font-weight:600;
  letter-spacing:.15em;text-transform:uppercase;fill:var(--ink);fill-opacity:.5}

/* the tooltips are timed in SMIL against the pulse's own clock, so there is
   no CSS animation to keep in step — only the reduced-motion escape, which
   pins all four open rather than hiding the copy */
@media(prefers-reduced-motion:reduce){.jrn-tip{opacity:1!important}}

/* stats, now a single row under Solutions */
.scale-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(14px,1.5vw,20px);margin-top:clamp(2.2rem,4vw,3.4rem)}
/* a quarter-width card cannot carry the two-column display size */
.scale-row .sc-card{min-height:clamp(158px,15vw,178px)}
.scale-row .sc-v,.scale-row .sc-hero.sc-4 .sc-v{font-size:clamp(1.35rem,1.9vw,1.75rem)}
@media(max-width:900px){.scale-row{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:540px){.scale-row{grid-template-columns:1fr}
  .scale-row .sc-card{min-height:0}}

/* #scale lost its right-hand cluster; the journey scene takes that column */
.scale-wrap{align-items:center}

/* SVG text scales with the viewBox, so once the scene has the full column
   the 11.5px labels would render small. Size them up in viewBox units. */
@media(max-width:900px){.jrn{max-width:540px;margin-inline:auto}}
/* On a phone a 640-unit scene renders at ~0.47x, which would put the labels at
   under 7px. Give it the full viewport, drop the two layers that cannot survive
   the shrink, and scale each pill about its own centre so the glass grows with
   the type instead of being overrun by it. */
@media(max-width:700px){
  .jrn{width:100vw;max-width:none;margin-inline:calc(50% - 50vw)}
  .jrn-tip,.jrn-idx{display:none}
  .jrn-pill{transform-box:fill-box;transform-origin:center;transform:scale(1.5)}
}

/* Faint pulses running the CDN mesh. Each link is normalised to pathLength 1,
   so one keyframe drives every link at the same beat whatever its length; the
   stagger comes from a seeded per-link delay in the markup. */
.net-ill .net-live,
.app-ill .net-live,
.pill-ill .net-live,
.sol-scene-svg .net-live{stroke-dasharray:.16 .84;stroke-dashoffset:0;stroke-opacity:.85;
  animation:netFlow 4.6s linear infinite}
@keyframes netFlow{to{stroke-dashoffset:-1}}
@media(prefers-reduced-motion:reduce){.net-ill .net-live,.app-ill .net-live,
  .pill-ill .net-live,.sol-scene-svg .net-live{animation:none;stroke-opacity:0}}

/* Pillar scene motion. The wavefronts are SMIL (a radius has to animate in user
   units, and a CSS transform would scale the stroke with it); the coins bob with
   a plain translate, which is why they are CSS — this is the layer that can be
   switched off. */
.pill-ill .net-grow{animation-name:netGrow;animation-timing-function:cubic-bezier(.22,1,.36,1);
  animation-iteration-count:infinite}
.pill-ill .coin-air{animation-name:coinBob;animation-timing-function:ease-in-out;
  animation-iteration-count:infinite}
@keyframes netGrow{0%,4%{opacity:0;transform:translateY(6px)}14%,90%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(6px)}}
@keyframes coinBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@media(prefers-reduced-motion:reduce){
  .pill-ill .coin-air,.pill-ill .net-grow{animation:none;opacity:1}
  .pill-ill .net-wave{display:none}
}

/* The backbone banner. Held to the width it was drawn for: the system runs on
   one line weight, and stretching this to the full wrap would draw its hairlines
   at nearly twice the weight of every other illustration on the site. */
/* The backbone drawing stands in the right column of a .model-split. .model-ill
   is already a square with aspect-ratio 1, so the square viewBox fills it; the
   mesh panel every other .model-ill carries is cleared, because this one is a
   drawing on the page white rather than a picture in a frame. */
.model-ill.is-net{background:none;border-radius:0;overflow:visible}
.model-ill.is-net svg.bb-ill{width:100%;height:auto;display:block;overflow:hidden}

/* user-applications: the head block and its drawing share a row, the three
   prose columns keep the full width under them. Same proportions as
   .model-split; a separate name because the copy side here is a head-2 rather
   than a feature block, and the drawing is square rather than framed. */
.app-split{display:grid;grid-template-columns:1fr minmax(0,.72fr);
  gap:clamp(1.8rem,5vw,4rem);align-items:center}
.app-split .head-2{max-width:none}
.model-ill.is-app{background:none;border-radius:0;overflow:visible}
.model-ill.is-app svg.app-ill{width:100%;height:auto;display:block;overflow:visible}
@media(max-width:900px){.app-split{grid-template-columns:1fr}
  .model-ill.is-app{max-width:380px;margin-inline:auto}}

/* a mark over each prose column: the rule the paragraph used to carry moves to
   the item, so the mark sits inside the column rather than above its border */
.pg-item{display:flex;flex-direction:column;align-items:flex-start;
  padding-top:1.1rem;box-shadow:inset 0 1px 0 var(--line)}
.pg-item p{padding-top:0;box-shadow:none;margin:.55rem 0 0}
.pg-item svg.pg-ic{width:26px;height:26px;display:block;margin:0 0 .15rem}


/* =====================================================================
   The device mockups: line-art chrome, real screens.

   The chrome is the illustrations' language — white surfaces, one hairline in
   their ink, no metal gradients — so the mockups sit with the drawings around
   them instead of reading as a photograph of hardware. What is inside the
   bezel is left alone: the screenshots are the only place on the page that
   shows the product, and the UI's own type is white, which needs the dark
   screen it was designed against.
   ===================================================================== */
:root{--dvc-line:rgba(14,56,69,.15);--dvc-line2:rgba(14,56,69,.09);--dvc-ink:rgba(14,56,69,.62)}

.dvc-web .dvc-body,
.dvc-phone .dvc-body,
.dvc-tv .dvc-body{background:#fff;
  box-shadow:0 0 0 1px var(--dvc-line),0 18px 44px -30px rgba(14,56,69,.4)}
.dvc-bar{background:#fff;border-bottom:1px solid var(--dvc-line2)}
.dvc-dots i{background:var(--dvc-line);width:7px;height:7px}
.dvc-url{background:#fff;box-shadow:inset 0 0 0 1px var(--dvc-line2);color:var(--dvc-ink)}
.dvc-phone .dvc-screen,
.dvc-tv .dvc-screen{box-shadow:inset 0 0 0 1px var(--dvc-line2)}
.dvc-notch{background:var(--dvc-line)}
.dvc-stand,.dvc-stand+.dvc-foot{background:#F1F5FA;box-shadow:0 0 0 1px var(--dvc-line)}

/* The devices drift. A plain translate, so it cannot touch the stroke width,
   and on a wrapper group that carries no transform attribute of its own — a
   CSS transform replaces an SVG one rather than composing with it. */
.app-ill .dev-float{animation-name:devFloat;animation-timing-function:ease-in-out;
  animation-iteration-count:infinite}
@keyframes devFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@media(prefers-reduced-motion:reduce){.app-ill .dev-float{animation:none}}

/* ===== .slab.is-tint — one row of four filled cards, each with a white line
   mark washed into its corner. The same treatment .slab-tint gives the three
   Playback / Platform / Delivery cards on perception-stream.html, extended by
   one step because there are four of these.

   Scoped to the modifier: .slab itself is on thirteen pages and none of them
   should move because this one section wanted colour.

   The ramp runs dark to light — Ink, Cyan, Sky, Haze — so the row reads as one
   object rather than four unrelated colours, and the type flips to white on
   the two dark steps. ===== */
.slab.is-tint{grid-template-columns:repeat(4,1fr)}
@media(max-width:1080px){.slab.is-tint{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.slab.is-tint{grid-template-columns:1fr}}

/* The mark reaches 90px up from the bottom edge and the copy used to run
   straight through it. The card reserves that band below the copy instead —
   padding, not a height, so it holds however long a line runs — and the band
   is the smallest one the mark fits in: 8px of air, then the mark. */
.slab.is-tint .slab-card{position:relative;overflow:hidden;isolation:isolate;
  background:var(--sbg);border-color:transparent;padding-bottom:98px}
.slab.is-tint .slab-card>h3{color:var(--sbf)}
.slab.is-tint .slab-card>p{color:var(--sbm)}
.slab.is-tint .slab-card:hover{border-color:transparent;
  box-shadow:0 24px 50px -34px rgba(14,17,22,.32)}

/* The mark is a watermark, so it is sized to the card and allowed to run off
   two edges — one that fits neatly inside a tidy square stops reading as one.
   Always white, as in the example, at every step of the ramp; only the opacity
   changes, because white on ink and white on haze are nowhere near the same
   strength. */
.slab.is-tint .sb-art{position:absolute;right:-26px;bottom:-42px;width:132px;height:132px;
  color:#fff;opacity:var(--sbo,.5);pointer-events:none;z-index:-1;
  transition:opacity .3s var(--ease),transform .3s var(--ease)}
.slab.is-tint .slab-card:hover .sb-art{opacity:calc(var(--sbo,.5) + .14);
  transform:translate(-3px,-3px)}

.sb--capacity{--sbg:#1D242B;--sbf:#fff;    --sbm:rgba(255,255,255,.72);--sbo:.24} /* Ink  */
.sb--transit {--sbg:#14B3D6;--sbf:#fff;    --sbm:rgba(255,255,255,.86);--sbo:.46} /* Cyan */
.sb--routing {--sbg:#8FD5E8;--sbf:#0E1116; --sbm:rgba(14,17,22,.7);    --sbo:.62} /* Sky  */
.sb--edge    {--sbg:#DCE2E7;--sbf:#0E1116; --sbm:rgba(14,17,22,.66);   --sbo:.78} /* Haze */
/* ===== end .slab.is-tint ===== */

/* ===== .slab.is-line — the boxed card stripped back to an open column.
   Same parts as .pg-item on user-applications.html: the rule sits on the item
   as an inset box-shadow rather than a border, so it lands inside the column
   and lines up across the row whatever the cards' heights. ===== */
.slab.is-line{grid-template-columns:repeat(3,1fr);gap:clamp(1rem,2.4vw,1.8rem)}
@media(max-width:820px){.slab.is-line{grid-template-columns:1fr}}

.slab.is-line .slab-card{background:none;border:0;border-radius:0;
  padding:1.1rem 0 0;box-shadow:inset 0 1px 0 var(--line);
  display:flex;flex-direction:column;align-items:flex-start}
.slab.is-line .slab-card:hover{border-color:transparent;box-shadow:inset 0 1px 0 var(--line);
  transform:none}
.slab.is-line svg.pg-ic{width:26px;height:26px;display:block;margin:0 0 .55rem}
.slab.is-line .slab-card h3{margin:0 0 .4rem}
/* ===== end .slab.is-line ===== */

/* ===== perception-stream illustrations — holders for the six finished scenes.
   Sizes match the source build the artwork came from, so the drawings sit at
   the scale they were drawn for. They carry their own soft shadows, hence no
   drop-shadow filter and no multiply blend. ===== */
/* The intro's drawing is a band, so it runs the full width of the wrap under
   the copy rather than sharing a column with it. The copy keeps a measure —
   a lead set to the whole width of a 1280 wrap is unreadable — but the band
   is not held to it. */
.ps-intro .wrap{display:block}
.ps-intro .head-2{max-width:none}
.ps-intro .head-2 .lead{max-width:64ch}
.ps-const{width:100%;aspect-ratio:auto;margin:clamp(1.6rem,3.5vw,3rem) 0 0}
.ps-const::before{display:none}
.ps-const-ill{width:100%;height:auto;display:block}

/* No panel behind the two product drawings. The artwork carries its own
   isometric ground, so the tinted card, its grid mesh and its glow were a
   second background stacked under the first. Four things go: the tier
   gradient, the glass shadow, the ::after mesh and the .ps-panel-glow blob.
   The logo, the drawing and the caption stay, spaced as they were. */
.ps-panel{background:none;box-shadow:none;min-height:0;overflow:visible;isolation:auto;
  gap:clamp(.7rem,1.4vw,1.1rem);padding:clamp(1.4rem,2.6vw,2.2rem) 0 clamp(1.1rem,2vw,1.6rem)}
.ps-panel::after{display:none}
.ps-panel-glow{display:none}

/* The tier lockup and its caption both moved into the copy column: the mark
   now hovers inside the drawing, so the panel was showing it twice, and the
   caption on its own under the drawing said nothing about the drawing. They
   sit on one line beside each other — see core-devices.js, which moves them. */
.ps-prod-head{display:flex;align-items:center;flex-wrap:wrap;
  gap:clamp(.7rem,1.4vw,1.1rem);margin:.85rem 0 1.15rem}
.ps-prod-head .ps-prod-logo{margin:0}
.ps-prod-cap{font-family:var(--font-label);font-weight:600;font-size:.72rem;
  letter-spacing:.17em;text-transform:uppercase;color:var(--steel)}

/* Enterprise wears Core's cyan on this page. Two things carry the tier blue:
   the --tier custom property, which feeds the ticks and the emphasis in the
   lede, and a dedicated gradient on its primary button. Both are pointed back
   at the cyan; the button simply loses its override and falls through to the
   default primary. Its mark and its lockup are recoloured in the artwork
   itself, in core-devices.js, since an <img> cannot be restyled from here. */
.ps-prod--ent{--tier:var(--cyan);--tier-tint:rgba(20,179,214,.14);
  --tier-glow:rgba(20,179,214,.5)}
/* the base primary restated, not cleared: CSS has no way to switch a rule
   off, and background:none would take the base fill with it */
.ps-prod--ent .ps-prod-cta .btn-primary{background:var(--cyan);color:#04141a;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 10px 28px -12px rgba(20,179,214,.75)}
.ps-prod--ent .ps-prod-cta .btn-primary:hover{background:#2bc0e0}
.ps-panel-ill{position:relative;z-index:1;width:min(100%,490px);height:auto;display:block;filter:none}
@media(max-width:900px){
  .ps-panel-logo{width:min(52%,200px)}
  .ps-panel-ill{width:min(100%,460px)}
}

/* Sized on width so the two deployment cards' drawings sit at the same scale.
   The card gives them 451px of content width and the managed row has a whole
   auto track, so they were running at about two thirds of the room available. */
.dep2-ill,.dep-managed-ill{mix-blend-mode:normal;height:auto;filter:none}
.dep2-ill{width:min(100%,440px)}
/* a clamp, not a percentage: this one sits in an auto grid track, and a
   percentage there resolves against a track sized by its own content */
.dep-managed-ill{width:clamp(210px,30vw,360px)}
/* ===== end perception-stream illustrations ===== */

/* ===== hero video card → round play button ================================
   Collapsed it is a 60px circle fixed in the corner; expanded it is the card
   the hero starts with. Both states are written out because a transition
   cannot run between a pixel value and auto — --fab-h is measured once in
   site.js and re-measured on resize, since the title wraps differently at
   different widths.

   Scoped to `body` rather than `.hero-v2`: while collapsed the button is
   reparented to <body> to escape .hero's isolation:isolate, so for half its
   life it is not inside the hero at all. The descendant selector also keeps
   these rules above the base ones on specificity rather than on source order.
   ===== */
.hero-v2 .hero-fab{
  transition:transform .35s var(--ease),width .42s var(--ease),height .42s var(--ease),
    padding .42s var(--ease),border-radius .42s var(--ease),
    border-color .3s var(--ease),box-shadow .3s var(--ease)}
body .hero-fab.is-measuring{transition:none}

/* Width and height are animated here rather than transform, and deliberately.
   A card becoming a circle is a change of box, not of scale: scaling would
   squash the 16:9 thumbnail into the circle and drag the type down with it.
   The cost the usual advice warns about is page reflow, and there is none —
   the element is position:fixed in both states, so the layout work is confined
   to the element itself. */
/* Collapsed, the button IS the cyan disc — everything it used to sit on is
   taken out from under it. Three circles of the same 60px at the same 50%
   radius do not resolve to one edge: the card's dark glass and the thumbnail's
   near-black both antialias a pixel proud of the disc, and what you see is a
   dark ring nobody drew. The shadow loses its black half for the same reason
   and keeps only the cyan halo. */
body .hero-fab.is-mini{
  position:fixed;right:clamp(1rem,2.4vw,1.75rem);bottom:clamp(1rem,2.4vw,1.75rem);
  z-index:90;
  width:60px;height:60px;padding:0;gap:0;border-radius:50%;
  background:transparent;border-color:transparent;
  transition:transform .35s var(--ease),width .42s var(--ease),height .42s var(--ease),
    padding .42s var(--ease),border-radius .42s var(--ease),background-color .3s var(--ease),
    border-color .3s var(--ease),box-shadow .3s var(--ease);
  box-shadow:0 14px 30px -14px rgba(20,179,214,.8)}
body .hero-fab.is-mini:hover{transform:none}
body .hero-fab.is-mini .hff-shot{aspect-ratio:1;border-radius:50%;
  background:transparent;box-shadow:none}
body .hero-fab.is-mini .hff-shot img{opacity:0}
body .hero-fab.is-mini .hff-shot::after{opacity:0}
body .hero-fab.is-mini .hff-play{width:100%;height:100%;box-shadow:none}
body .hero-fab.is-mini .hff-play svg{width:20px;height:20px}
/* out of flow rather than hidden: left in the column the text keeps its height
   and the circle comes out an oval */
body .hero-fab.is-mini .hff-badge,
body .hero-fab.is-mini .hff-title{position:absolute;left:11px;right:11px;bottom:14px;
  opacity:0;pointer-events:none}
.hff-shot,.hff-shot img,.hff-shot::after,.hff-play,.hff-badge,.hff-title{
  transition:opacity .28s var(--ease),aspect-ratio .42s var(--ease),
    width .42s var(--ease),height .42s var(--ease),border-radius .42s var(--ease)}

/* Back to the full card under the cursor. Gated on a real pointer: on a
   touchscreen :hover latches after a tap and the card would stick open behind
   the player it just launched. */
@media(hover:hover) and (min-width:901px){
  body .hero-fab.is-mini:hover,
  body .hero-fab.is-mini:focus-visible{
    width:clamp(255px,25vw,319px);height:var(--fab-h,auto);
    padding:11px 11px 14px;gap:.68rem;border-radius:22px;
    background:rgba(14,26,40,.62);
    transform:translateY(-4px);border-color:rgba(122,226,255,.5);
    box-shadow:0 36px 70px -28px rgba(0,0,0,.85),0 0 30px -10px rgba(122,226,255,.35)}
  body .hero-fab.is-mini:hover .hff-shot,
  body .hero-fab.is-mini:focus-visible .hff-shot{aspect-ratio:16/9;border-radius:13px;
    background:#05121e;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
  body .hero-fab.is-mini:hover .hff-shot img,
  body .hero-fab.is-mini:focus-visible .hff-shot img,
  body .hero-fab.is-mini:hover .hff-shot::after,
  body .hero-fab.is-mini:focus-visible .hff-shot::after{opacity:1}
  body .hero-fab.is-mini:hover .hff-play,
  body .hero-fab.is-mini:focus-visible .hff-play{width:42px;height:42px;
    box-shadow:0 8px 20px -6px rgba(0,0,0,.55)}
  body .hero-fab.is-mini:hover .hff-play svg,
  body .hero-fab.is-mini:focus-visible .hff-play svg{width:15px;height:15px}
  body .hero-fab.is-mini:hover .hff-badge,
  body .hero-fab.is-mini:focus-visible .hff-badge,
  body .hero-fab.is-mini:hover .hff-title,
  body .hero-fab.is-mini:focus-visible .hff-title{position:static;opacity:1;pointer-events:auto}
}
/* Parked, the card is moved to <body> — so `.hero-v2 .hero-fab`, which holds
   the card itself (a left-aligned column on glass), no longer reaches it and
   the badge and title fell back to a centred inline row on nothing. The card
   is restated here, and its panel is denser than the hero's: over a white
   section .62 washed out to grey. */
body .hero-fab.is-mini{display:flex;flex-direction:column;align-items:stretch;text-align:left;
  -webkit-backdrop-filter:blur(16px) saturate(1.3);backdrop-filter:blur(16px) saturate(1.3)}
@media(hover:hover) and (min-width:901px){
  body .hero-fab.is-mini:hover,
  body .hero-fab.is-mini:focus-visible{background:rgba(9,20,33,.9);border-color:rgba(122,226,255,.5)}
}
/* ===== end hero fab collapse ===== */

/* ===== the Challenge card: a figure between two cycling decks ===============
   Replaces the balance scale. Five cards a side share one slot and run the
   same keyframes a fifth of the loop apart, each rising in, holding, and
   leaving within its own fifth. The two sides use different periods so they
   drift rather than flip together. ===== */
/* THE PAIR IS ONE WEIGHT. The Challenge card used to be near black against
   its light sibling, which made the section read as a before/after rather
   than as two halves of one argument. Both now sit on the same light ground,
   and the Challenge card's contents — heading, note, eyebrow, its mesh
   overlay — come with it; left alone they were white on white.

   The mesh behind them stops screening. On a dark card screen lightens and
   the mesh reads; on a light one it blows out to a flat wash. */
.duo-cards .duo-card--dark,.duo-cards .duo-card--slate{background:#EDF1F5;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 0 0 1px rgba(14,17,22,.05)}
.duo-cards .duo-card--dark::before{opacity:.26;mix-blend-mode:normal}
.duo-cards .duo-card--dark .duo-h{color:var(--ink)}
.duo-cards .duo-card--dark .duo-note,
.duo-cards .duo-card--dark .duo-note--lead{color:rgba(14,17,22,.72)}
.duo-cards .duo-card--dark .duo-eyebrow{background:#fff;color:var(--cyan-deep)}

/* The dark card is stretched to the height of its packed sibling, and
   .duo-body is pushed to the bottom by a margin-top:auto meant for that
   sibling's list. Left alone the drawing sat in a strip at the foot of a
   719px card with 260px of nothing above it. Here it takes the free height
   and centres in it instead. */
.duo-card--dark .duo-body:has(.chal-anim){margin-top:0;flex:1;
  display:flex;flex-direction:column;justify-content:center}

.chal-anim{width:100%;display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:clamp(8px,1.6vw,18px);margin-top:clamp(.9rem,2.4vw,1.8rem)}

/* Sized on height, not width: sad.svg is 650x978 and Happy.svg 769x1097, so
   equal widths would draw one figure taller than the other and the pair would
   not read as the same person twice. */
.chal-figure{height:clamp(150px,17vw,208px);width:auto;display:block;
  opacity:.9;filter:drop-shadow(0 22px 40px rgba(0,0,0,.45))}

/* One slot, five cards deep. The height is fixed because the cards are out of
   flow: without it the row would collapse to nothing. */
/* The whole deck is on show: five cards standing one behind another, the
   nearest at the bottom in full and the ones behind it stepping up and back.
   They march — every card moves forward one place each turn, the front one
   drops out of the bottom and rejoins at the back — so the queue reads as
   endless, which is the line the card is making.

   --step is the pitch between cards. It has to clear a card's own height or
   the labels print through each other, which is exactly what went wrong when
   they were stacked eight pixels apart. */
.chal-stack{position:relative;overflow:hidden;--step:74px;
  height:clamp(300px,36vw,364px);
  /* the deck dissolves into the card at the top instead of meeting a hard
     clip, so the queue reads as continuing rather than being cut off */
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 20%);
          mask-image:linear-gradient(180deg,transparent 0,#000 20%)}
/* Every card is the same size. Their labels run from two words to five, so
   left to the text they came out at one, two and three lines and the deck
   read as a ragged pile. A fixed height set to the longest of them, with the
   text centred in it, makes the deck a deck. */
.chal-card{position:absolute;left:0;right:0;bottom:0;
  height:58px;display:flex;align-items:center;padding:0 .82rem;border-radius:13px;
  font-family:var(--font-body);font-size:.79rem;line-height:1.28;font-weight:500;
  color:var(--ink);background:linear-gradient(180deg,#fff,#f4f8fb);
  box-shadow:inset 0 0 0 1px rgba(14,17,22,.09);
  transform-origin:bottom center;
  animation:chalCycle 20s cubic-bezier(.5,0,.15,1) infinite;
  animation-delay:calc(var(--i) * -4s)}
/* The two sides keep the same clock and sit at the same height — they are a
   pair, and giving them different periods made them read as two unrelated
   things ticking away. Half a place out of phase is enough to stop them
   moving as one block: one side glides while the other rests. */
.chal-stack--r .chal-card{animation-delay:calc(var(--i) * -4s - 2s)}

@keyframes chalCycle{
  /* Five places, a fifth of the loop each: rest, then glide to the next.

     The glide is safe. Every card runs this same timeline with a delay of
     exactly one fifth, so all five are always in the same part of it — they
     rest together and move together, and the gap between any two stays one
     place for the whole journey. A card is never caught halfway across its
     neighbour's label. That is why this can be smooth; the earlier version
     snapped to avoid an overlap that lockstep already rules out.

     A sixth position below the front one lets the leading card sink out and
     fade rather than vanish, and the loop then restarts it, invisible, at the
     back. Depth is opacity and a little scale — no blur, so the text stays
     sharp wherever a card is in the queue — and the ring picks up the accent
     at the front, which is what marks the card being read now. */
  0%       {transform:translateY(calc(var(--step) * -4)) scale(.9);  opacity:0}
  6%,11%   {transform:translateY(calc(var(--step) * -4)) scale(.9);  opacity:.2}
  20%,31%  {transform:translateY(calc(var(--step) * -3)) scale(.926);opacity:.36}
  40%,51%  {transform:translateY(calc(var(--step) * -2)) scale(.951);opacity:.55}
  60%,71%  {transform:translateY(calc(var(--step) * -1)) scale(.976);opacity:.76}
  80%,91%  {transform:translateY(0) scale(1);opacity:1;
            box-shadow:inset 0 0 0 1.4px rgba(20,179,214,.5)}
  100%     {transform:translateY(var(--step)) scale(1);  opacity:0}
}

@media(prefers-reduced-motion:reduce){
  /* no cycle: the first card of each deck simply sits there */
  /* no march: the deck simply stands there, each card in its own place */
  .chal-card{animation:none}
  .chal-card[style*="--i:0"]{transform:translateY(0);opacity:1}
  .chal-card[style*="--i:1"]{transform:translateY(calc(var(--step) * -1)) scale(.975);opacity:.75}
  .chal-card[style*="--i:2"]{transform:translateY(calc(var(--step) * -2)) scale(.95);opacity:.54}
  .chal-card[style*="--i:3"]{transform:translateY(calc(var(--step) * -3)) scale(.925);opacity:.36}
  .chal-card[style*="--i:4"]{transform:translateY(calc(var(--step) * -4)) scale(.9);opacity:.2}
}
/* the phone layout for both decks lives with the Solution card, below */
/* ===== end Challenge card ===== */

/* ===== the corporate gate's backdrop: the office tower, turning ==========
   The hero version insets itself below the header and wipes in from the left,
   because the hero's copy sits on the left. The gate's copy sits in the
   middle, so it fills the whole gate and is masked with a hole in the centre
   instead — the tower reads at the edges and never behind the form. ===== */
.corp-gate-fx{inset:0;
  -webkit-mask-image:radial-gradient(58% 52% at 50% 50%,transparent 30%,#000 78%);
          mask-image:radial-gradient(58% 52% at 50% 50%,transparent 30%,#000 78%)}
/* centred on the mask's hole, so the cluster comes out evenly all round the
   form rather than piling up under it */
.corp-gate-fx .m3d-stage{left:50%;top:50%;transform:scale(.95)}
/* the gate stacks its own children, so the form has to be lifted over it */
.corp-gate>.brand-logo,.corp-gate .corp-gate-box{position:relative;z-index:1}
@media(max-width:700px){.corp-gate-fx .m3d-stage{transform:scale(.6)}}
/* ===== end corporate gate backdrop ===== */

/* ===== corporate: the brand cards ==================================
   Ordinary slab cards carrying a mark instead of a lead line. The marks are
   full lockups of different widths, so they are sized on height and pinned
   left — matching them on width would render one twice the size of another.
   The row is left to the slab grid, which already wraps at 248px. ===== */
.corp-brand{display:flex;flex-direction:column;align-items:flex-start;gap:1.1rem;
  text-decoration:none;color:inherit}
.corp-brand img{height:clamp(26px,3vw,34px);width:auto;display:block}
.corp-brand h3{margin:0}
/* the catch-all card is quieter than the two named brands */
.corp-brand--more img{opacity:.55}
.corp-brand--more h3{color:var(--slate);font-size:1.05rem}
/* ===== end corporate brand cards ===== */

/* ===== the Solution card: a figure between two marching decks ==============
   The Challenge card's mechanism, with two differences: the headings stay
   put, because "We Operate" and "You Own" are what the lists are for rather
   than entries in them; and there are 8 places instead of five, so the deck
   runs taller than its window and the top is masked away. ===== */
.duo-card:not(.duo-card--dark) .duo-body:has(.sol-anim){margin-top:0;flex:1;
  display:flex;flex-direction:column;justify-content:center}

.sol-anim{width:100%;display:grid;grid-template-columns:1fr auto 1fr;
  align-items:start;gap:clamp(8px,1.6vw,18px);margin-top:clamp(.9rem,2.4vw,1.8rem)}
.sol-side{min-width:0}
/* the heading holds its ground above the deck */
.sol-side .own-head{margin:0 0 .7rem}

/* height comes from .chal-figure, which both figures share */
.sol-figure{align-self:center}

/* the deck itself is the Challenge card's, restyled for a light card */
/* the same pitch and the same card as Challenge, so the pair reads as one
   mechanism seen twice */
.sol-stack{--step:74px;height:clamp(300px,36vw,364px)}
.sol-stack .chal-card{color:var(--ink);
  background:linear-gradient(180deg,#fff,#f4f8fb);
  box-shadow:inset 0 0 0 1px rgba(14,17,22,.09);
  animation-name:solCycle;animation-duration:27.2s;
  animation-delay:calc(var(--i) * -3.4s)}
.sol-stack--r .chal-card{animation-delay:calc(var(--i) * -3.4s - 1.7s)}

@keyframes solCycle{
  0%,9% {transform:translateY(calc(var(--step) * -7)) scale(0.9);opacity:0.2}
  12.5%,21.5% {transform:translateY(calc(var(--step) * -6)) scale(0.91);opacity:0.31}
  25%,34% {transform:translateY(calc(var(--step) * -5)) scale(0.93);opacity:0.43}
  37.5%,46.5% {transform:translateY(calc(var(--step) * -4)) scale(0.94);opacity:0.54}
  50%,59% {transform:translateY(calc(var(--step) * -3)) scale(0.96);opacity:0.66}
  62.5%,71.5% {transform:translateY(calc(var(--step) * -2)) scale(0.97);opacity:0.77}
  75%,84% {transform:translateY(calc(var(--step) * -1)) scale(0.99);opacity:0.89}
  87.5%,96.5% {transform:translateY(calc(var(--step) * -0)) scale(1);opacity:1;box-shadow:inset 0 0 0 1.4px rgba(20,179,214,.5)}
  100% {transform:translateY(var(--step)) scale(1);opacity:0}
}

@media(prefers-reduced-motion:reduce){
  .sol-stack .chal-card{animation:none}
}
/* ===== Challenge + Solution on a phone: the decks lie down ==========
   Stacked into one column the two decks made a 600px tower of labels under a
   96px figure. A deck is a queue, and a queue reads as well lying down: one
   row above the figure, one below, each card travelling right to left across
   its own row. The cards are square-ish here rather than the desktop's wide
   strips — at this width a strip is all padding and a truncated label.
   Spacing between cards is the travel divided by five, so the travel is set
   well wider than the screen to keep a gap between them. ===== */
@media(max-width:620px){
  .chal-anim,.sol-anim{grid-template-columns:1fr;grid-template-rows:auto auto auto;
    justify-items:stretch;gap:12px}
  .chal-anim .chal-stack--l{grid-row:1}
  .chal-anim .chal-figure{grid-row:2}
  .chal-anim .chal-stack--r{grid-row:3}
  .sol-anim .sol-side:first-of-type{grid-row:1}
  .sol-anim .sol-figure{grid-row:2}
  .sol-anim .sol-side:last-of-type{grid-row:3}
  .chal-anim .chal-figure,.sol-anim .sol-figure{order:0;justify-self:center;
    height:clamp(132px,34vw,168px);width:auto}
  .sol-side{width:100%;max-width:none}
  .sol-side .own-head{margin:0 0 .5rem}

  /* the slot is a row now: one card tall, the full width, fading at both ends */
  .chal-anim .chal-stack,.sol-anim .chal-stack{
    width:100%;max-width:none;transform:none;
    height:clamp(96px,26vw,112px);
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14%,#000 86%,transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 14%,#000 86%,transparent 100%)}

  .chal-anim .chal-card,.sol-anim .chal-card{
    top:0;bottom:auto;left:0;right:auto;
    width:clamp(104px,30vw,124px);height:clamp(96px,26vw,112px);
    padding:.6rem .68rem;border-radius:16px;
    align-items:flex-end;font-size:.76rem;line-height:1.24;
    transform-origin:center;opacity:1;
    box-shadow:inset 0 0 0 1px rgba(14,17,22,.09);
    animation:chalScroll 19s linear infinite;
    animation-delay:calc(var(--i) * -3.8s)}
  /* the two rows keep the same clock, half a place apart, as they do on the
     desktop — one row glides while the other is between cards */
  /* Eight cards, so eight places: the travel is set to eight times the same
     pitch, and the duration to keep the speed identical to the Challenge's. */
  .sol-anim .chal-card{animation-name:solScroll;animation-duration:30.4s}
  .chal-anim .chal-stack--r .chal-card,
  .sol-anim .sol-stack--r .chal-card{animation-delay:calc(var(--i) * -3.8s - 1.9s)}
  /* the card being read now still takes the accent ring */
  .chal-anim .chal-card[style*="--i:0"],.sol-anim .chal-card[style*="--i:0"]{
    box-shadow:inset 0 0 0 1.4px rgba(20,179,214,.5)}
}
@keyframes chalScroll{
  from{transform:translateX(calc(100vw + 60px))}
  to  {transform:translateX(-190px)}
}
@keyframes solScroll{
  from{transform:translateX(calc(100vw + 440px))}
  to  {transform:translateX(-190px)}
}
/* No travel to sit through: the row becomes one the reader pushes themselves. */
@media(max-width:620px) and (prefers-reduced-motion:reduce){
  .chal-anim .chal-stack,.sol-anim .chal-stack{
    overflow-x:auto;overflow-y:hidden;display:flex;gap:10px;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch}
  .chal-anim .chal-card,.sol-anim .chal-card{position:relative;flex:0 0 auto;
    transform:none;scroll-snap-align:start}
}
/* ===== end Solution card ===== */

/* ===== the Stream hero: the rendered clip ==========================
   Was sixteen stacked copies of the mark on a CSS 3D rig; it is a rendered
   animation now. The clip keeps its black ground because WebP's alpha plane
   is lossless and keying it out cost fifteen megabytes; screen blending does
   the same job at no cost, and the mask fades the four edges. ===== */
/* .page-head>.wrap is position:relative with z-index:1 — a stacking context
   holding nothing, so anything blending inside it would composite against
   transparency and keep its black. Positioned but not isolating: the wrap
   still paints over .hero-fx and over the grid ::after at z-index:-1. */
.ps-hero>.wrap{z-index:auto}

/* .ps-hero-art img already sets width:min(100%,430px) and carries an element
   in its selector, so a bare .ps-hero-vid loses to it and the clip came out
   at 430px whatever it asked for. Same shape of selector, one class more. */
.ps-hero-art img.ps-hero-vid{display:block;width:min(146%,600px);max-width:none;height:auto;
  /* Wider than its column, so it still spills to the right — but only as far
     as the section, not past it. At -46% the mark ran 126px off the edge and
     the right of it was cut by overflow:hidden rather than faded by the mask
     below; -8% brings it inside, and the fade does the work it is there for.
     The left of the frame is black and screens to nothing, so the copy it
     passes over is untouched. */
  margin-inline:auto;
  /* black contributes nothing over the band's own gradient */
  mix-blend-mode:screen;
  /* One fade, at the foot. The other three edges do not need one: the frame
     is black there and screens to nothing, so there is no edge to hide — only
     the reflection under the mark reads as a cut, and this is what softens it.
     A single layer, so there is nothing left to composite. */
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 72%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0,#000 72%,transparent 100%);
  /* it is decoration; it must never be what the layout waits for */
  contain:paint}
.ps-hero-art{min-height:0}

@media(max-width:900px){
  .ps-hero-art{order:-1}
  .ps-hero-art img.ps-hero-vid{width:min(96%,430px);margin-inline:auto}
}
/* ===== end Stream hero ===== */

/* ===== mobile fixes: measured at 375px =========================
   Found by measuring, not by eye — boxes past the viewport edge, computed
   font sizes under 11.5px, hit areas under 40px. See mobile-fixes.js for
   what each one was. ===== */

/* 1. the products ribbon is width:100vw inside a 335px stage, so it ran nine
   pixels past both edges and the page scrolled sideways. It is meant to
   bleed, so the section clips it — clip, not hidden: hidden would make this a
   scroll container and any sticky inside it would stop working. */
@media(max-width:760px){
  .section:has(.pp-ribbon){overflow-x:clip}
}

/* 2 + 3. the platform band is 3.5:1 — at phone width it came out 95px tall
   with 4.6px labels. It scrolls at a readable size instead of being crushed,
   and the scroll is padded so the drawing does not start against the edge. */
@media(max-width:760px){
  .ps-const{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
    margin-inline:calc(clamp(1.25rem,4vw,2.5rem) * -1);
    padding-inline:clamp(1.25rem,4vw,2.5rem);scrollbar-width:none}
  .ps-const::-webkit-scrollbar{display:none}
  .ps-const-ill{width:640px;max-width:none;flex:none}
}
/* the labels answer to a pointer that can hover; on touch there is none, so
   they only get in the way */
@media(hover:none){
  .bd-tip{display:none}
}

/* 4. nothing on this site should be under 11px; these were 9.9 */
@media(max-width:760px){
  .s3d-name{font-size:11px;letter-spacing:.12em}
}

/* 5. inline links were 21-25px tall. Coarse pointers only, so the desktop
   line rhythm is left alone. */
@media(pointer:coarse){
    /* 44px touch targets. .textlink and .crumbs a sit inline in prose and in the
     breadcrumb row, so they take inline-flex; footer links are block-level and
     inline-flex would run them together on one line. */
  .textlink,.crumbs a{display:inline-flex;align-items:center;min-height:44px}
  .foot-col a{display:flex;align-items:center;min-height:44px}
}

/* 6. the decks stack on a phone; at the desktop pitch the Solution card's
   animation alone ran 776px */
/* the decks lie down on a phone now — see "the decks lie down", above */
/* ===== end mobile fixes ===== */

/* ===== phone header: the mark alone, the burger in a chip =========
   The lockup is four parts wordmark to one part symbol; at 47px the word
   is 3px of x-height. Below the breakpoint where the nav collapses, the
   symbol carries it alone and the two remaining controls become the same
   white circle. ===== */
.brand-mark{display:none;flex:none}

@media(max-width:920px){
  /* The lockup has three forms on this site — plain, --light and --hero —
     and the hero one is shown by a rule carrying an id and three classes.
     Both selectors below are written to outrank it rather than reach for
     !important: the second is the same weight and comes later. */
  #header .brand .brand-logo{display:none}
  body.dark-hero #header:not(.scrolled) .brand .brand-logo{display:none}
  .brand .brand-mark{display:block;height:34px;width:34px}

  /* AT THE TOP the bar is bare — the mark and the burger sit straight on the
     hero, the way the wordmark did. The chip belongs to the scrolled state,
     which is the only state that has to separate itself from the content
     running under it. The burger's own 1px box goes with it. */
  header .brand{padding:7px;gap:0;border-radius:50%}
  .burger{width:46px;height:46px;border-radius:50%;
    background:transparent;border-color:transparent;box-shadow:none}

  /* ...and both take the same white chip once the page moves */
  header.scrolled .brand,
  header.scrolled .burger{
    background:rgba(255,255,255,.92);
    -webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);
    border:1px solid rgba(14,17,22,.08);
    box-shadow:0 16px 42px -24px rgba(14,17,22,.4)}
  header.scrolled .brand{padding:7px}
  header.scrolled .burger{color:var(--ink)}
}
/* ===== end phone header ===== */

/* ===== corporate hero: replaced by three cards ==================
   No head and no ground: the page is three cards on the ordinary canvas.
   .prods-ai carries them — the homepage's own card film, hairline and
   corner glow, scoped to that class rather than to .pfm-ai, so the cards
   keep their look without the section having to be an ink slab. Only the
   two-column split inside each card and the panels are new here. ===== */
/* first and only section, under a header that floats over the page */
.corp-sec{padding-top:clamp(7.5rem,14vh,10rem)}

/* the accents are values the site already carries: the wallet violet, the
   brand cyan and the PAI blue. .prod::before reads --pc for the corner glow. */
.c-media{--pc:#725ED4}.c-future{--pc:#14B3D6}.c-res{--pc:#2E5BFF}

/* copy on the left, the card's own material on the right — the shape the
   homepage's cards take with their photo, built here out of content */
.corp-prods .prod{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:clamp(1.5rem,3vw,3rem);align-items:center;
  padding:clamp(1.7rem,2.8vw,2.5rem);border-radius:24px;min-height:clamp(240px,24vw,300px)}
.corp-prods .cp-copy{display:flex;flex-direction:column;align-items:flex-start;gap:.55rem}
.cp-eyebrow{font-family:var(--font-label);font-size:.7rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--sky)}
.corp-prods .prod-t{font-family:var(--font-display);font-weight:600;
  font-size:clamp(1.4rem,2.1vw,1.95rem);letter-spacing:-.025em;line-height:1.1;color:#fff}
.corp-prods .prod-d{font-size:.95rem;line-height:1.6;color:rgba(255,255,255,.66);
  max-width:46ch;text-wrap:pretty}

/* ---- the studios ---- */
.corp-studios{display:grid;grid-template-columns:repeat(3,1fr);gap:.7rem}
.corp-studio{display:flex;flex-direction:column;justify-content:space-between;gap:1.1rem;
  min-height:132px;padding:1rem 1.05rem;border-radius:15px;text-decoration:none;
  background:rgba(255,255,255,.055);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);
  transition:background .26s var(--ease),box-shadow .26s var(--ease),transform .26s var(--ease)}
.corp-studio:hover{background:rgba(255,255,255,.09);transform:translateY(-2px);
  box-shadow:inset 0 0 0 1px rgba(122,226,255,.34)}
/* The marks are drawn at wildly different widths. height:22px with
   max-width:100% squashed the ENTYEN lockup, because a fixed height and a
   capped width fight: the box shrinks and the picture distorts inside it.
   Both axes are maxima instead, so each mark scales to whichever it hits. */
.corp-studio img{height:auto;width:auto;max-height:22px;max-width:100%;
  object-fit:contain;object-position:left center;display:block}
.corp-studio span{font-size:.82rem;line-height:1.35;color:rgba(255,255,255,.78)}

/* ---- the downloads ---- */
.corp-dls{display:flex;flex-direction:column;gap:.5rem}
.corp-dl{position:relative;display:grid;gap:.12rem;padding:.82rem 3rem .85rem 1.05rem;
  border-radius:13px;text-decoration:none;
  background:rgba(255,255,255,.055);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);
  transition:background .26s var(--ease),box-shadow .26s var(--ease)}
.corp-dl:hover{background:rgba(255,255,255,.09);box-shadow:inset 0 0 0 1px rgba(122,226,255,.34)}
.cd-t{font-family:var(--font-display);font-weight:500;font-size:1rem;letter-spacing:-.01em;color:#fff}
.cd-d{font-size:.82rem;line-height:1.4;color:rgba(255,255,255,.55)}
.cd-ar{position:absolute;right:1.1rem;top:50%;transform:translateY(-50%);
  width:17px;height:17px;color:var(--sky);opacity:.55;transition:opacity .22s,transform .22s}
.corp-dl:hover .cd-ar{opacity:1;transform:translateY(-42%)}

/* ---- the future card has no material yet, so the panel carries the mark ---- */
.cp-mark{display:grid;place-items:center;min-height:132px}
.cp-mark img{width:min(72%,300px);height:auto;display:block;opacity:.13}

@media(max-width:900px){
  .corp-prods .prod{grid-template-columns:1fr;gap:1.4rem;align-items:start;min-height:0}
  .corp-prods .prod-d{max-width:none}
  .cp-mark{min-height:0}
  .cp-mark img{width:min(46%,190px)}
}
@media(max-width:560px){
  /* three marks across a phone leaves each about 90px, which is under the
     width the ENTYEN lockup needs to stay legible */
  .corp-studios{grid-template-columns:1fr}
  .corp-studio{flex-direction:row;align-items:center;justify-content:flex-start;
    gap:.85rem;min-height:0;padding:.85rem 1rem}
  .corp-studio img{max-height:19px;flex:none}
}
@media(prefers-reduced-motion:reduce){
  .corp-studio,.corp-dl,.cd-ar{transition:none}
  .corp-studio:hover{transform:none}
}
/* ===== end corporate hero ===== */

/* ============================================================= HERO REEL (phone)
   The arc (five rings, radius 800px) is a desktop picture: on a phone it shows
   four cropped tiles behind the headline and nothing else, and the space under
   the CTA runs empty down to the client logos. Below 760px the arc is switched
   off — its sixty lazy tiles never load, a hidden image has no box to intersect
   — and this ring takes its place: nine screens on a 190px orbit, the front ones
   large and sharp, the sides angled, dimmed and blurred, the back half hidden by
   its own backface. Depth is an animation, not a script: the ring turns one slot
   every 3s and each tile runs the same 27s dim cycle, offset by its own slot, so
   a tile is brightest exactly as it faces the camera. */
.hero-reel{display:none}
@media(max-width:760px){
  .hero-v2 .hero-arc{display:none}
  .hero-reel{display:block;position:relative;z-index:2;margin:clamp(.2rem,1.5vh,.8rem) 0 0}
  .hr-stage{position:relative;height:204px;perspective:640px;perspective-origin:50% 46%;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 22%,#000 78%,transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 22%,#000 78%,transparent 100%)}
  .hr-ring{position:absolute;left:50%;top:49%;width:0;height:0;transform-style:preserve-3d;
    transform:rotateX(-7deg);animation:hrSpin 27s linear infinite}
  .hr-t{position:absolute;left:0;top:0;width:132px;height:82px;margin:-41px 0 0 -66px;
    transform:rotateY(calc(var(--i) * 40deg)) translateZ(205px);
    border-radius:10px;overflow:hidden;background:#0a2b46;backface-visibility:hidden;
    box-shadow:0 16px 30px -14px rgba(0,0,0,.8),inset 0 0 0 1px rgba(255,255,255,.12);
    animation:hrDim 27s linear infinite;animation-delay:calc(var(--i) * -3s)}
  .hr-t img{width:100%;height:100%;object-fit:cover;display:block}
  .hr-t::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(168deg,rgba(4,18,32,.22),transparent 60%)}
  /* the stage light the ring stands on */
  .hr-floor{position:absolute;left:50%;bottom:0;width:340px;height:86px;transform:translateX(-50%);
    pointer-events:none;filter:blur(3px);
    background:radial-gradient(50% 50% at 50% 50%,rgba(20,179,214,.42),transparent 72%)}
  .hr-sig{display:block;width:100%;height:30px;margin-top:-2px;overflow:visible}
  .hrs-base{fill:none;stroke:rgba(122,226,255,.22);stroke-width:1}
  .hrs-pulse{fill:none;stroke:rgba(150,225,250,.9);stroke-width:1.6;stroke-linecap:round;
    stroke-dasharray:54 900;animation:hrsRun 3.6s linear infinite}
}
@keyframes hrSpin{to{transform:rotateX(-7deg) rotateY(360deg)}}
/* a tile faces the camera at 0%/100%; by 27% it is edge-on and gone, and the
   opacity ramp finishes the backface’s job in engines where the filter below
   flattens the tile and takes backface-visibility with it */
@keyframes hrDim{
  0%{filter:brightness(1) blur(0);opacity:1}
  16%{filter:brightness(.8) blur(.5px);opacity:1}
  27%,73%{filter:brightness(.5) blur(1.4px);opacity:0}
  84%{filter:brightness(.8) blur(.5px);opacity:1}
  100%{filter:brightness(1) blur(0);opacity:1}}
@keyframes hrsRun{from{stroke-dashoffset:954}to{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){
  .hr-ring,.hr-t,.hrs-pulse{animation:none}
  .hr-t{opacity:1;filter:none}}

/* the architecture drawing belongs to the three cards above it, so it sits in
   their section rather than one of its own. Wider than a phone by nature — six
   stations reading left to right is what it is — so it scrolls sideways in its
   own panel instead of reflowing into something that loses the sequence. */
.ovp-arch{display:block;width:100%;max-width:1180px;height:auto;
  /* Air above, less below. The drawing needs a clear break from the three
     cards it follows — they read as one band and it as another — while under
     it the section's own 105px of padding lands on top of the empty margin the
     drawing already carries, which left far more white than the break above.
     The negative bottom takes that doubling back out. */
  margin:clamp(2.6rem,5vw,4.75rem) auto -3.5rem}
@media(max-width:860px){
  /* Below 860 the picture element swaps in the stacked drawing, so there is
     nothing left to scroll sideways -- it just fits the column. */
  .ovp-arch{width:100%;max-width:none}
}

/* ===== cookie notice and settings ============================================
   A glass bar at the foot of the window in the site's own panel language. It
   has two faces: the short question, and the categories behind it. ===== */
.ck-bar{position:fixed;left:50%;bottom:clamp(.8rem,2vw,1.4rem);transform:translate(-50%,140%);
  z-index:80;width:min(940px,calc(100vw - 2rem));
  padding:clamp(.9rem,2vw,1.15rem) clamp(1.1rem,2.4vw,1.5rem);
  border-radius:var(--r-md);background:var(--glass-2);border:1px solid var(--glass-brd);
  -webkit-backdrop-filter:blur(18px) saturate(1.25);backdrop-filter:blur(18px) saturate(1.25);
  box-shadow:var(--shadow);opacity:0;
  transition:transform .42s var(--ease),opacity .42s var(--ease)}
.ck-bar.is-in{transform:translate(-50%,0);opacity:1}
.ck-bar.is-panel{width:min(560px,calc(100vw - 2rem));padding:clamp(1.2rem,2.4vw,1.5rem)}
.ck-face[hidden]{display:none}
.ck-ask{display:flex;align-items:center;gap:clamp(1rem,3vw,2rem);flex-wrap:wrap}
.ck-copy{flex:1 1 20rem;margin:0;font-size:.84rem;line-height:1.55;color:var(--slate)}
.ck-copy a{color:var(--cyan-deep);text-decoration:none;border-bottom:1px solid rgba(20,179,214,.35);
  padding-bottom:1px;transition:border-color .2s var(--ease)}
.ck-copy a:hover{border-bottom-color:var(--cyan-deep)}
.ck-acts{display:flex;gap:.6rem;align-items:center;flex:0 0 auto}
.ck-btn{font-family:var(--font-body);font-size:.82rem;font-weight:600;letter-spacing:.005em;
  padding:.6rem 1.1rem;border-radius:var(--pill);cursor:pointer;border:1px solid transparent;
  transition:.2s var(--ease)}
.ck-ghost{background:transparent;border-color:var(--line);color:var(--slate)}
.ck-ghost:hover{border-color:var(--ink);color:var(--ink)}
.ck-yes{background:var(--cyan);color:#04141a;border-color:var(--cyan)}
.ck-yes:hover{background:#2bc0e0;border-color:#2bc0e0}
.ck-link{background:none;padding:.6rem .2rem;color:var(--slate);text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:rgba(84,96,108,.4)}
.ck-link:hover{color:var(--ink);text-decoration-color:currentColor}

/* the second face */
.ck-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.4rem}
.ck-head h2{font-family:var(--font-display);font-weight:500;font-size:1.05rem;letter-spacing:-.015em;
  color:var(--ink);margin:0}
.ck-x{background:none;border:0;cursor:pointer;font-size:1.4rem;line-height:1;color:var(--steel);
  padding:.1rem .3rem;border-radius:6px;transition:color .2s var(--ease)}
.ck-x:hover{color:var(--ink)}
.ck-cats{list-style:none;margin:0 0 1.1rem;padding:0}
.ck-cat{padding:.85rem 0;border-bottom:1px solid var(--line-2)}
.ck-cat:last-child{border-bottom:0}
.ck-cat-d{margin:.3rem 0 0 3.15rem;font-size:.79rem;line-height:1.5;color:var(--steel)}
.ck-sw{display:flex;align-items:center;gap:.8rem;cursor:pointer}
.ck-sw.is-locked{cursor:default}
.ck-sw input{position:absolute;opacity:0;width:0;height:0}
.ck-track{flex:none;width:36px;height:20px;border-radius:999px;background:var(--haze);
  border:1px solid var(--line);position:relative;transition:.2s var(--ease)}
.ck-track::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;
  background:#fff;box-shadow:0 1px 2px rgba(14,17,22,.25);transition:transform .2s var(--ease)}
.ck-sw input:checked+.ck-track{background:var(--cyan);border-color:var(--cyan)}
.ck-sw input:checked+.ck-track::after{transform:translateX(16px)}
.ck-sw input:disabled+.ck-track{opacity:.55}
.ck-sw input:focus-visible+.ck-track{outline:2px solid var(--cyan);outline-offset:2px}
.ck-cat-t{font-size:.88rem;font-weight:600;color:var(--ink)}
.ck-cat-t em{font-style:normal;font-weight:400;font-size:.74rem;color:var(--steel);margin-left:.4rem}
.ck-panel .ck-acts{justify-content:flex-end}

@media(max-width:560px){
  .ck-ask{gap:.85rem}
  .ck-acts{width:100%;flex-wrap:wrap}
  .ck-ghost,.ck-yes{flex:1}
}
/* the dark pages carry the bar in their own key */
html.night .ck-bar,body.pai .ck-bar{background:rgba(14,26,40,.78);border-color:rgba(255,255,255,.14)}
html.night .ck-copy,body.pai .ck-copy,html.night .ck-cat-d,body.pai .ck-cat-d{color:rgba(255,255,255,.68)}
html.night .ck-head h2,body.pai .ck-head h2,
html.night .ck-cat-t,body.pai .ck-cat-t{color:#fff}
html.night .ck-copy a,body.pai .ck-copy a{color:var(--sky);border-bottom-color:rgba(122,226,255,.4)}
html.night .ck-ghost,body.pai .ck-ghost,
html.night .ck-link,body.pai .ck-link{border-color:rgba(255,255,255,.22);color:rgba(255,255,255,.8)}
html.night .ck-ghost:hover,body.pai .ck-ghost:hover,
html.night .ck-link:hover,body.pai .ck-link:hover{border-color:#fff;color:#fff}
html.night .ck-cat,body.pai .ck-cat{border-bottom-color:rgba(255,255,255,.1)}
html.night .ck-track,body.pai .ck-track{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.2)}
@media(prefers-reduced-motion:reduce){.ck-bar,.ck-track,.ck-track::after{transition:none}}

/* ===== the legal page ========================================================
   One column, set for reading rather than scanning: a measure in the low
   seventies, headings that step down clearly, and lists that keep a hanging
   marker. The two notices are separate sections so each can be linked to. ===== */
.legal-wrap{max-width:74ch}
.legal-head{padding-bottom:0}
.legal-head h1{font-size:clamp(2.1rem,4.4vw,3.1rem);letter-spacing:-.035em}
.legal-sep{color:rgba(255,255,255,.4);font-weight:300;margin:0 .15rem}
.legal-head .lead{margin-top:1.1rem;max-width:56ch}
/* the head is the dark band, so this row is lit for it */
.legal-jump{margin-top:1.8rem;display:flex;gap:.7rem;align-items:center;flex-wrap:wrap;font-size:.88rem}
.legal-jump a{color:var(--sky);text-decoration:none;border-bottom:1px solid rgba(122,226,255,.4);
  padding-bottom:2px;transition:border-color .2s var(--ease)}
.legal-jump a:hover{border-bottom-color:var(--sky)}
.legal-jump span{color:rgba(255,255,255,.35)}
.legal-sec{padding-top:clamp(2.4rem,5vw,3.4rem)}
.legal-sec+.legal-sec{border-top:1px solid var(--line-2)}
.legal-sec h2{font-family:var(--font-display);font-weight:500;font-size:clamp(1.6rem,3vw,2.1rem);
  letter-spacing:-.025em;color:var(--ink);margin:0 0 1.4rem}
.legal-sec h3{font-family:var(--font-display);font-weight:500;font-size:1.06rem;letter-spacing:-.012em;
  color:var(--ink);margin:2.2rem 0 .6rem}
.legal-sec h2+h3{margin-top:1.4rem}
.legal-sec p{color:var(--slate);font-size:.94rem;line-height:1.72;margin:0 0 1rem}
.legal-sec a{color:var(--cyan-deep);text-decoration:none;border-bottom:1px solid rgba(20,179,214,.3);
  transition:border-color .2s var(--ease)}
.legal-sec a:hover{border-bottom-color:var(--cyan-deep)}
.legal-sec ul{margin:0 0 1.2rem;padding-left:1.15rem;list-style:disc}
.legal-sec li{color:var(--slate);font-size:.94rem;line-height:1.72;margin-bottom:.5rem;padding-left:.2rem}
.legal-sec li::marker{color:var(--cyan)}

/* ===== Cross-document view transitions ==============================
   Navigation between pages is a full document load. Opting in lets the
   browser hold the outgoing page's pixels, fetch the next one, and cross-fade
   between them -- which removes the white flash without turning the site into
   a single-page app. Browsers without support simply navigate as before.
   ===== */
@view-transition { navigation: auto; }

/* The transition is motion, so it follows the same preference everything else
   on the site does. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
