@import url("https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,700,900&display=swap");
/* ============================================================
   DARK WATER — Immersive Agency Design System
   Dark-mode-first · deep ocean · liquid glass · bioluminescent
   ============================================================ */
:root{
  /* Black-meets-water: a truer inky abyss for more depth + contrast */
  --void:#010204; --abyss:#03050B; --deep:#060A13; --deep-2:#0A1020; --ink-panel:#0D1422;
  --aqua:#0077FF; --aqua-bright:#3B9EFF; --aqua-deep:#0A80FF; --aqua-soft:#9CC9FF;
  --sapphire:#0A5FCC; --abyss-blue:#012A4A;
  /* Signature water gradient — foam → aqua → deep sapphire (more richness/depth than flat teal) */
  --grad-aqua:linear-gradient(135deg,#3B9EFF 0%,#0077FF 48%,#0A5FCC 100%);
  --grad-aqua-h:linear-gradient(90deg,#0A80FF,#3B9EFF 50%,#0A80FF);
  /* Iconic ribbon stops (the Dark Water "light through water") */
  --ribbon-1:#3B9EFF; --ribbon-2:#0077FF; --ribbon-3:#0A80FF; --ribbon-4:#062E66;
  --text:#E8EEF6; --text-soft:#AEBBD0; --text-mut:#7C89A1;
  --line:rgba(255,255,255,.08); --line-2:rgba(59,158,255,.18);
  --glass:rgba(255,255,255,.045); --glass-2:rgba(255,255,255,.07);
  --glass-brd:rgba(255,255,255,.10);
  --shadow:0 30px 80px rgba(0,0,0,.55), 0 8px 30px rgba(0,0,0,.4);
  --shadow-aqua:0 18px 50px rgba(0,119,255,.30);
  --radius-sm:10px; --radius:16px; --radius-lg:22px; --radius-xl:30px;
  --container:1280px; --header-h:78px;
  --font-display:'Space Grotesk','Segoe UI',system-ui,sans-serif;
  --font-body:'Inter','Segoe UI',system-ui,-apple-system,sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
}
/* optional light theme (kept dark-first; toggle dims to "surface" mode) */
[data-theme="light"]{ --abyss:#0A0F1A; --deep:#0E1422; --deep-2:#121A2B; }

*,*::before,*::after{box-sizing:border-box} *{margin:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} *{animation:none!important;transition:none!important} }
body{ font-family:var(--font-body); color:var(--text); background:var(--abyss); line-height:1.65;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; overflow-x:hidden; }
img{max-width:100%;display:block} a{color:inherit;text-decoration:none} button{font:inherit;cursor:pointer} ul{list-style:none;padding:0}
:focus-visible{outline:2px solid var(--aqua);outline-offset:3px;border-radius:6px}
::selection{background:rgba(59,158,255,.25);color:#fff}

/* ambient background field */
body::before{ content:""; position:fixed; inset:0; z-index:-2; background:
  radial-gradient(1100px 700px at 80% -10%, rgba(0,119,255,.16), transparent 60%),
  radial-gradient(900px 700px at -10% 110%, rgba(59,158,255,.10), transparent 55%),
  var(--abyss); }
body::after{ content:""; position:fixed; inset:0; z-index:-1; pointer-events:none; opacity:.04;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* typography */
h1,h2,h3,h4{font-family:var(--font-display);font-weight:700;line-height:1.08;letter-spacing:-.02em;color:#fff}
h1{font-size:clamp(2.7rem,6vw,5rem)} h2{font-size:clamp(2rem,4vw,3.2rem)} h3{font-size:clamp(1.25rem,2vw,1.6rem)}
.eyebrow{font-family:var(--font-body);font-weight:600;font-size:.78rem;letter-spacing:.28em;text-transform:uppercase;color:var(--aqua-bright);display:inline-flex;align-items:center;gap:.7rem}
.eyebrow::before{content:"";width:30px;height:1px;background:var(--grad-aqua-h)}
.eyebrow--center::after{content:"";width:30px;height:1px;background:var(--grad-aqua-h)}
.lead{font-size:clamp(1.06rem,1.5vw,1.3rem);color:var(--text-soft)}
.muted{color:var(--text-mut)} .aqua{color:var(--aqua-bright)}

/* ---- inline prose links ------------------------------------------
   The global reset at the top of this file is `a{color:inherit;
   text-decoration:none}`, which is deliberate — every link on this site is
   styled by its component (.btn, .card__link, .site-footer a, .crumb a…).
   The gap was the link that belongs to no component: the one sitting inside a
   sentence. Those inherited their paragraph's colour and had no underline, so
   they were literally indistinguishable from the text around them. Measured at
   393px: 11 of them across 9 pages, every one a real route — six copies of
   "Compare every plan →" (the only bridge from services, tools, industries,
   hosting, seo and knowledge-base into pricing.html), academy's contact and
   portal links, and careers' "the contact form". Grey-on-grey, no underline,
   and on a phone there is no hover state to reveal them.

   Scoped to `main` so it cannot touch the header, the drawer or the footer,
   which style their own links; component classes are excluded by name so a
   button or a card link inside a paragraph keeps its own treatment. The
   underline is deliberately faint and offset — it has to read as a link
   without turning a paragraph of body copy into a ransom note. Left inline
   rather than padded to a 44px target: a block-level tap target inside a
   sentence breaks the sentence, and inline prose links are exempt from the
   target-size minimum for exactly that reason.
   ------------------------------------------------------------------- */
main p a:not(.btn):not(.card__link):not(.pill):not(.pill-soft):not(.tag),
main li a:not(.btn):not(.card__link):not(.pill):not(.pill-soft):not(.tag){
  color:var(--aqua-bright);
  font-weight:600;
  text-decoration:underline;
  text-decoration-color:rgba(59,158,255,.42);
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  transition:color .2s var(--ease),text-decoration-color .2s var(--ease);
}
main p a:not(.btn):not(.card__link):not(.pill):not(.pill-soft):not(.tag):hover,
main li a:not(.btn):not(.card__link):not(.pill):not(.pill-soft):not(.tag):hover{
  color:#8CCBFF;text-decoration-color:currentColor;
}
.gradient-text{background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}

/* layout */
.container{width:100%;max-width:var(--container);margin-inline:auto;padding-inline:clamp(20px,4vw,48px)}
.section{padding-block:clamp(70px,9vw,130px);position:relative}
.section--tight{padding-block:clamp(44px,6vw,80px)}
.center{text-align:center}
.section-head{max-width:760px;margin-bottom:60px} .section-head.center{margin-inline:auto;text-align:center}
.grid{display:grid;gap:26px}
.cols-2{grid-template-columns:repeat(2,1fr)}.cols-3{grid-template-columns:repeat(3,1fr)}.cols-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:980px){.cols-3,.cols-4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.cols-2,.cols-3,.cols-4{grid-template-columns:1fr}}

/* glass panel */
.glass{ background:var(--glass); backdrop-filter:blur(18px) saturate(140%); -webkit-backdrop-filter:blur(18px) saturate(140%);
  border:1px solid var(--glass-brd); border-radius:var(--radius-lg); }

/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.55rem;padding:.95rem 1.6rem;border-radius:999px;border:1px solid transparent;
  font-family:var(--font-body);font-weight:600;font-size:.96rem;letter-spacing:.01em;transition:transform .3s var(--ease),box-shadow .3s var(--ease),background .3s,color .3s,border-color .3s;will-change:transform}
.btn svg{width:1.15em;height:1.15em}
.btn{white-space:nowrap}
.nav__actions .btn,.nav__signin{flex:none;white-space:nowrap}
.btn--aqua{background:var(--grad-aqua);color:#04121C;box-shadow:var(--shadow-aqua)}
.btn--aqua:hover{transform:translateY(-3px);box-shadow:0 26px 60px rgba(0,119,255,.45)}
.btn--glass{background:var(--glass-2);color:#fff;border-color:var(--glass-brd);backdrop-filter:blur(12px)}
.btn--glass:hover{transform:translateY(-3px);border-color:var(--line-2);background:rgba(59,158,255,.10)}
.btn--ghost{background:transparent;color:var(--text);border-color:var(--line)}
.btn--ghost:hover{border-color:var(--aqua);color:var(--aqua-bright);transform:translateY(-3px)}
.btn--lg{padding:1.1rem 2rem;font-size:1.02rem} .btn--block{width:100%}
/* Dashboard button — refined outline with a water-lit hairline border */
.btn--outline{background:rgba(59,158,255,.04);color:var(--text);border:1px solid var(--line-2);position:relative}
.btn--outline svg{color:var(--aqua-bright)}
.btn--outline:hover{transform:translateY(-3px);border-color:var(--aqua-bright);background:rgba(59,158,255,.10);box-shadow:0 12px 34px rgba(0,119,255,.22)}
.btn--sm{padding:.7rem 1.1rem;font-size:.9rem}

/* header */
.site-header{position:sticky;top:0;z-index:60;height:var(--header-h);display:flex;align-items:center;
  background:rgba(5,7,13,.55);backdrop-filter:blur(18px) saturate(140%);-webkit-backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--line);transition:background .3s,box-shadow .3s}
.site-header.scrolled{background:rgba(5,7,13,.82);box-shadow:0 10px 40px rgba(0,0,0,.4)}
.nav{display:flex;align-items:center;justify-content:space-between;width:100%;gap:1.4rem}
.brand{display:flex;align-items:center;gap:.7rem}
.brand__icon{width:44px;height:44px;flex:none;filter:drop-shadow(0 0 12px rgba(0,119,255,.4))}
.brand__text{display:flex;flex-direction:column;line-height:1}
.brand__name{font-family:var(--font-display);font-weight:700;font-size:1.25rem;letter-spacing:.14em;color:#fff}
.brand__sub{font-size:.56rem;letter-spacing:.34em;text-transform:uppercase;color:var(--text-mut);margin-top:4px}
.nav__links{display:flex;align-items:center;gap:.1rem}
.nav__links a{font-size:.92rem;font-weight:500;padding:.55rem .8rem;border-radius:8px;color:var(--text-soft);transition:color .2s,background .2s}
.nav__links a:hover,.nav__links a.active{color:var(--aqua-bright);background:rgba(59,158,255,.08)}
.nav__actions{display:flex;align-items:center;gap:.6rem}
.nav__signin{font-size:.92rem;font-weight:600;color:var(--text-soft);padding:.55rem .5rem;transition:color .2s}
.nav__signin:hover{color:var(--aqua-bright)}
.has-dropdown{position:relative}
.dropdown{position:absolute;top:calc(100% + 10px);left:0;min-width:230px;background:var(--ink-panel);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:.5rem;opacity:0;visibility:hidden;transform:translateY(8px);transition:all .25s var(--ease)}
.has-dropdown:hover .dropdown,.has-dropdown:focus-within .dropdown{opacity:1;visibility:visible;transform:translateY(0)}
.dropdown a{display:block;padding:.6rem .8rem;border-radius:8px}
.theme-toggle,.menu-toggle{width:44px;height:44px;border-radius:10px;border:1px solid var(--line);background:var(--glass);color:#fff;display:grid;place-items:center;transition:.2s}
.theme-toggle:hover,.menu-toggle:hover{transform:translateY(-2px);border-color:var(--aqua)}
.theme-toggle svg,.menu-toggle svg{width:20px;height:20px}
.menu-toggle{display:none}
@media(max-width:560px){.nav__actions .btn--aqua{display:none}}
.icon-sun{display:none}[data-theme="light"] .icon-sun{display:block}[data-theme="light"] .icon-moon{display:none}
@media(max-width:1200px){.nav__links{display:none}.menu-toggle{display:grid}.nav__actions .btn--callnav{display:none}}
.drawer{position:fixed;inset:0;z-index:80;background:var(--abyss);transform:translateX(100%);transition:transform .4s var(--ease);display:flex;flex-direction:column;padding:24px;overflow-y:auto}
.drawer.open{transform:translateX(0)}
.drawer__top{display:flex;justify-content:space-between;align-items:center;margin-bottom:1.5rem}
.drawer nav{display:flex;flex-direction:column;gap:.1rem}
.drawer nav a{padding:.85rem .4rem;font-size:1.05rem;font-weight:500;border-bottom:1px solid var(--line)}
.drawer__group-label{font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--aqua-bright);margin-top:1.2rem;font-weight:600}
/* The drawer's two actions live outside <nav> so the phone layer can pin them
   below the scrolling list (mobile.css §2.7). This is the tablet/desktop base
   for that wrapper — the drawer opens up to 1200px wide, where it is still one
   long scroll and the actions simply follow the list. */
.drawer__cta{display:flex;flex-direction:column;gap:.6rem;margin-top:1.4rem}
.drawer__cta .btn{width:100%}
.drawer__brand{pointer-events:none}

/* hero */
.hero{position:relative;min-height:calc(100vh - var(--header-h));display:flex;align-items:center;overflow:hidden;padding-block:60px}
#oceanCanvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;display:block}
.hero__veil{position:absolute;inset:0;z-index:1;pointer-events:none;background:
  radial-gradient(60% 60% at 50% 38%, transparent, rgba(5,7,13,.55) 80%),
  linear-gradient(180deg, rgba(5,7,13,.4), transparent 30%, rgba(5,7,13,.85))}
.hero__inner{position:relative;z-index:2;max-width:880px;margin-inline:auto;text-align:center}
.hero h1{margin:.6rem 0 1.2rem}
.hero .lead{max-width:620px;margin-inline:auto}
.hero__cta{display:flex;flex-wrap:wrap;gap:.9rem;justify-content:center;margin-top:2rem}
.hero__trust{display:flex;flex-wrap:wrap;gap:1rem 1.8rem;justify-content:center;margin-top:2.4rem;color:var(--text-mut);font-size:.86rem}
.hero__trust span{display:flex;align-items:center;gap:.5rem} .hero__trust svg{width:18px;height:18px;color:var(--aqua)}
.scroll-cue{position:absolute;bottom:22px;left:50%;transform:translateX(-50%);z-index:2;color:var(--text-mut);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;display:flex;flex-direction:column;align-items:center;gap:.5rem}
.scroll-cue::after{content:"";width:1px;height:34px;background:linear-gradient(var(--aqua),transparent);animation:cue 1.8s ease-in-out infinite}
@keyframes cue{0%,100%{opacity:.3;transform:scaleY(.5)}50%{opacity:1;transform:scaleY(1)}}

/* ============================================================
   SIGNATURE — the "light through water" ribbon (iconic motif)
   Dark Water's answer to a billion-dollar hero gradient.
   Two blurred, slowly drifting bands read as luminous current
   rising from the abyss. GPU-cheap (transform/opacity), and it
   freezes flat under prefers-reduced-motion.
   ============================================================ */
.hero__aurora{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.hero__aurora::before,.hero__aurora::after{content:"";position:absolute;border-radius:50%;
  filter:blur(70px);opacity:.55;mix-blend-mode:screen;will-change:transform}
.hero__aurora::before{
  width:75vw;height:48vw;left:-8vw;top:-14vw;
  background:conic-gradient(from 210deg at 60% 45%,
    var(--ribbon-4) 0deg, var(--ribbon-3) 70deg, var(--ribbon-2) 140deg,
    var(--ribbon-1) 200deg, transparent 300deg, var(--ribbon-4) 360deg);
  animation:ribbon-a 26s var(--ease) infinite}
.hero__aurora::after{
  width:60vw;height:60vw;right:-14vw;bottom:-24vw;opacity:.4;
  background:radial-gradient(closest-side,var(--ribbon-2),var(--ribbon-3) 45%,transparent 72%);
  animation:ribbon-b 32s var(--ease) infinite}
/* a single crisp light-seam so it reads as a "current", not a blob */
.hero__aurora>i{position:absolute;left:50%;top:-10%;width:150%;height:130%;transform:translateX(-50%) rotate(-14deg);
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.22),rgba(0,119,255,.35),rgba(10,95,204,.15),transparent);
  filter:blur(30px);opacity:.6;mix-blend-mode:screen;animation:seam 18s var(--ease) infinite}
@keyframes ribbon-a{0%,100%{transform:translate3d(0,0,0) rotate(0deg) scale(1)}50%{transform:translate3d(6vw,3vw,0) rotate(16deg) scale(1.12)}}
@keyframes ribbon-b{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(-5vw,-3vw,0) scale(1.15)}}
@keyframes seam{0%,100%{transform:translateX(-50%) rotate(-14deg) translateY(0);opacity:.5}50%{transform:translateX(-46%) rotate(-9deg) translateY(-3%);opacity:.75}}
@media (prefers-reduced-motion:reduce){.hero__aurora::before,.hero__aurora::after,.hero__aurora>i{animation:none}}
@media (max-width:640px){.hero__aurora::before,.hero__aurora::after{filter:blur(50px);opacity:.42}}

/* marquee */
.marquee{border-block:1px solid var(--line);background:rgba(255,255,255,.02);padding:20px 0;overflow:hidden}
.marquee__row{display:flex;gap:3rem;align-items:center;white-space:nowrap;animation:scrollx 26s linear infinite;color:var(--text-mut)}
/* flex:0 0 auto is load-bearing, not tidiness. A ticker item is nowrap text in
   a flex row, and a flex item's default min-width:auto is the only thing that
   was stopping it collapsing. mobile.css sets `main * { min-width:0 }` on
   phones — the right call for every column on the page and fatal here: all
   sixteen spans measured 0px wide at 390px, spaced by the 3rem gap alone, so
   every service name printed on top of the next one. The strip read
   "pterpSEO DHostingnRgadOnvAsidWeb Development". A ticker item must never
   shrink at any width, so this is stated here rather than patched on a phone. */
.marquee__row span{font-family:var(--font-display);font-weight:500;letter-spacing:.04em;font-size:1rem;display:flex;align-items:center;gap:.6rem;flex:0 0 auto}
.marquee__row svg{width:16px;height:16px;color:var(--aqua)}
@keyframes scrollx{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* cards */
.card{position:relative;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius-lg);padding:30px;overflow:hidden;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease),border-color .35s;backdrop-filter:blur(14px)}
.card::before{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;background:linear-gradient(140deg,rgba(59,158,255,.4),transparent 40%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity .35s}
.card:hover{transform:translateY(-6px);box-shadow:var(--shadow);border-color:var(--line-2)}
.card:hover::before{opacity:1}
.card__icon{width:56px;height:56px;border-radius:14px;display:grid;place-items:center;background:rgba(0,119,255,.12);color:var(--aqua-bright);margin-bottom:18px;border:1px solid var(--line-2)}
.card__icon svg{width:28px;height:28px}
.card h3{margin-bottom:.5rem}.card p{color:var(--text-soft)}
.card__link{display:inline-flex;align-items:center;gap:.4rem;margin-top:1rem;color:var(--aqua-bright);font-weight:600;font-size:.9rem}
.card__link svg{width:16px;height:16px;transition:transform .2s}.card:hover .card__link svg{transform:translateX(4px)}
/* .price-tag was written as an absolutely-positioned corner badge
   (position:absolute;top:24px;right:24px). It has not actually been one since
   the ambient-light pass landed
   `.card>*:not(.ix__glow):not(.ix__edge){position:relative;z-index:3}`
   further down this file: that selector is (0,3,0) and this rule is (0,1,0),
   so the card children are forced back into normal flow — and the orphaned
   top/right offsets survive, because relative positioning still honours them.
   The result on every viewport was the price painted 24px DOWN, straight over
   the first two lines of the description it is supposed to sit above, and 24px
   LEFT, hanging out of the card's own 30px padding. Measured on tools.html at
   393px: price-tag top -6184 height 26, description top -6182 — a 24px
   overlap, on all three plan cards, at 393 and at 1440.

   The fix is flow, not a restored badge. All six usages (three plan cards in
   tools.html, three in industries.html) write the markup in reading order —
   heading, price, description — and a corner badge would collide with a
   heading like "DW Industry Pro" on a 393px screen anyway. So the price
   becomes a real line in that flow, sized up because it is the number the
   whole card exists to deliver. */
.price-tag{position:relative;top:auto;right:auto;display:block;margin:.1rem 0 .6rem;font-family:var(--font-display);font-weight:600;font-size:1.35rem;line-height:1.15;letter-spacing:-.01em;color:var(--aqua-bright)}

/* stats */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}@media(max-width:680px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{text-align:center;padding:1.4rem 1rem}
.stat b{font-family:var(--font-display);font-size:clamp(2.1rem,4vw,3.2rem);display:block;background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat span{color:var(--text-mut);font-weight:500;font-size:.92rem}

/* steps */
.steps{counter-reset:step}.step{display:flex;gap:1.2rem;align-items:flex-start}
.step__num{counter-increment:step;flex:none;width:52px;height:52px;border-radius:14px;background:rgba(0,119,255,.1);color:var(--aqua-bright);display:grid;place-items:center;font-family:var(--font-display);font-weight:700;border:1px solid var(--line-2)}
.step__num::before{content:"0" counter(step)}

/* feature rows */
.feature-row{display:flex;gap:1rem;align-items:flex-start}
.feature-row .chk{flex:none;width:28px;height:28px;border-radius:8px;background:rgba(59,158,255,.12);color:var(--aqua-bright);display:grid;place-items:center}
.feature-row .chk svg{width:16px;height:16px}.feature-row h4{margin-bottom:.2rem}.feature-row p{color:var(--text-soft);font-size:.95rem}

/* pricing */
.price-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;align-items:stretch}@media(max-width:900px){.price-grid{grid-template-columns:1fr}}
.plan{position:relative;background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius-lg);padding:32px;display:flex;flex-direction:column;backdrop-filter:blur(14px);transition:transform .3s var(--ease),box-shadow .3s}
.plan:hover{transform:translateY(-6px);box-shadow:var(--shadow)}
.plan--featured{border-color:var(--aqua);box-shadow:var(--shadow-aqua)}
.plan__badge{position:absolute;top:-13px;left:50%;transform:translateX(-50%);background:var(--grad-aqua);color:#04121C;font-weight:700;font-size:.74rem;letter-spacing:.06em;padding:.3rem 1rem;border-radius:999px;text-transform:uppercase}
.plan h3{margin-bottom:.3rem}.plan .price{font-family:var(--font-display);font-size:2.4rem;font-weight:700}.plan .price small{font-size:.95rem;color:var(--text-mut);font-weight:500}
.plan ul{display:flex;flex-direction:column;gap:.7rem;margin:1.4rem 0}.plan li{display:flex;gap:.6rem;align-items:flex-start;color:var(--text-soft)}
.plan li svg{width:18px;height:18px;color:var(--aqua-bright);flex:none;margin-top:.2rem}.plan .btn{margin-top:auto}

/* testimonials */
.quote-card{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius-lg);padding:30px;display:flex;flex-direction:column;gap:1rem;backdrop-filter:blur(14px)}
.quote-card p{color:var(--text-soft);font-size:1.02rem}.stars{color:var(--aqua-bright);letter-spacing:2px}
.who{display:flex;align-items:center;gap:.8rem;margin-top:auto}
.who .av{width:46px;height:46px;border-radius:50%;background:var(--grad-aqua);color:#04121C;display:grid;place-items:center;font-weight:700;font-family:var(--font-display)}
.who b{display:block}.who small{color:var(--text-mut)}

/* work tiles */
.work-tile{position:relative;border-radius:var(--radius-lg);overflow:hidden;border:1px solid var(--glass-brd);aspect-ratio:16/11;background:linear-gradient(160deg,#0c1830,#070b14);display:flex;align-items:flex-end;padding:24px;transition:transform .4s var(--ease),box-shadow .4s}
.work-tile:hover{transform:translateY(-6px);box-shadow:var(--shadow)}
.work-tile::before{content:"";position:absolute;inset:0;background:radial-gradient(120% 90% at 80% 0%, rgba(0,119,255,.22), transparent 55%)}
.work-tile__c{position:relative;z-index:1}
.work-tile .tag{font-size:.74rem;letter-spacing:.12em;text-transform:uppercase;color:var(--aqua-bright)}
.work-tile h3{margin-top:.3rem}

/* cta band */
.cta-band{position:relative;border-radius:var(--radius-xl);padding:clamp(40px,6vw,72px);text-align:center;overflow:hidden;border:1px solid var(--line-2);
  background:linear-gradient(160deg,#0b1830,#070b14)}
.cta-band::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 100% at 50% 0%, rgba(0,119,255,.28), transparent 60%);pointer-events:none}
.cta-band .lead{max-width:620px;margin:1rem auto 1.8rem}
.cta-band .btn-row{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;position:relative;z-index:1}

/* faq */
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{width:100%;text-align:left;background:none;border:none;padding:1.3rem 0;display:flex;justify-content:space-between;align-items:center;gap:1rem;font-family:var(--font-display);font-weight:600;font-size:1.1rem;color:#fff}
.faq-q .pm{flex:none;width:28px;height:28px;border-radius:8px;border:1px solid var(--line);display:grid;place-items:center;transition:.3s;color:var(--aqua-bright)}
.faq-item.open .pm{background:var(--aqua);color:#04121C;transform:rotate(45deg);border-color:var(--aqua)}
.faq-a{max-height:0;overflow:hidden;transition:max-height .35s var(--ease)}.faq-a p{padding-bottom:1.3rem;color:var(--text-soft)}

/* ---- native <details> disclosure ---------------------------------
   Every <summary> on knowledge-base.html is written with an inline
   `list-style:none`, which removes the browser's own triangle. Nothing
   replaced it. The result was eighteen article titles separated by hairlines
   with no affordance at all — on a desktop the cursor at least turns into a
   pointer, but on a phone there is no cursor, so the whole accordion read as a
   static list and the answers underneath were invisible.

   The chevron is drawn from two borders on a pseudo-element rather than an
   extra DOM node or an SVG, so it costs nothing and inherits the aqua accent.
   Closed it points down; open it rotates to point up. `::-webkit-details-marker`
   is suppressed as well because Safari uses that instead of `list-style`, and
   the inline rule does not reach it.

   Scoped to `main details>summary`. The portal reuses <details> in
   invoices.php, projects.php and proposal.php — none of those pages have a
   <main> element (verified), so they keep their own treatment untouched.
   Padding and the 44px minimum height are NOT set here: the mobile query at
   the foot of this file already supplies `summary{padding:.7rem 0;
   min-height:44px}`, and duplicating it would fight that rule.
   ------------------------------------------------------------------- */
main details>summary{position:relative;display:flex;align-items:center;justify-content:space-between;gap:.75rem;list-style:none;-webkit-tap-highlight-color:transparent;transition:color .2s var(--ease)}
main details>summary::-webkit-details-marker{display:none}
main details>summary::after{content:"";flex:none;width:8px;height:8px;margin:-4px 3px 0 0;border-right:2px solid var(--aqua-bright);border-bottom:2px solid var(--aqua-bright);transform:rotate(45deg);transition:transform .25s var(--ease),opacity .2s var(--ease);opacity:.7}
main details[open]>summary::after{transform:rotate(225deg);margin:3px 3px 0 0;opacity:1}
main details>summary:hover{color:var(--aqua-bright)}
main details>summary:hover::after{opacity:1}
main details>summary:focus-visible{outline:2px solid var(--aqua-bright);outline-offset:3px;border-radius:6px}

/* badges */
.badge-row{display:flex;flex-wrap:wrap;gap:1rem}
.tbadge{display:flex;align-items:center;gap:.6rem;padding:.7rem 1.1rem;border:1px solid var(--line);border-radius:999px;background:var(--glass);font-weight:500;font-size:.88rem;color:var(--text-soft)}
.tbadge svg{width:20px;height:20px;color:var(--aqua-bright)}
.pill-soft{display:inline-block;background:rgba(0,119,255,.12);color:var(--aqua-bright);padding:.3rem .8rem;border-radius:999px;font-weight:600;font-size:.78rem;border:1px solid var(--line-2)}

/* forms */
.form-card{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius-lg);padding:clamp(24px,4vw,40px);backdrop-filter:blur(14px)}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem}@media(max-width:600px){.form-grid{grid-template-columns:1fr}}
.field{margin-bottom:1.2rem}.field label{display:block;font-weight:600;font-size:.9rem;margin-bottom:.5rem}
.field input,.field select,.field textarea{width:100%;padding:.85rem 1rem;border-radius:10px;border:1px solid var(--line);background:rgba(255,255,255,.03);color:var(--text);font:inherit;transition:border-color .2s,box-shadow .2s}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--aqua);box-shadow:0 0 0 4px rgba(0,119,255,.16);outline:none}

/* The dropdown LIST, not the closed control.
 *
 * A <select> styled for a dark card inherits `color:var(--text)` — near-white.
 * The open option list, though, is painted by the OS, and on macOS and Windows
 * that popup is white. So every option rendered near-white on white and the menu
 * looked empty except for whichever row the pointer happened to be highlighting.
 * On portal/projects.php that made the Stage dropdown — Discovery, Design,
 * Build, Review, Launch — a blank white rectangle with one readable line in it.
 *
 * `color-scheme:dark` is the correct primary fix: it asks the platform for the
 * dark popup, which Chrome, Edge and Safari now honour, and it also fixes the
 * dropdown arrow and the scrollbar inside the list. The explicit option colours
 * are the floor beneath it, for engines that keep painting the popup light —
 * dark text on white is readable, which is all this needs to guarantee. Both are
 * required: neither alone covers every browser.
 *
 * Scoped to the bare element, not to `.field select`. The portal's own forms
 * (projects.php, admin.php, documents.php, invoices.php, requests.php,
 * campaigns.php, proposal-edit.php) do not use the `.field` wrapper at all —
 * they use `.pj-f` or nothing — so a `.field`-scoped rule would have fixed the
 * marketing contact form and left every dropdown in the admin console unreadable,
 * which is where the problem was actually reported. */
select{color-scheme:dark}
select option,select optgroup{background-color:#0D1422;color:#E8EEF6}
@supports not (color-scheme:dark){
  select option,select optgroup{background-color:#fff;color:#0B1220}
}

/* Checkboxes and radios — the one native control left on a dark UI.
 *
 * "Grant admin access" on portal/admin.php rendered as a stark white filled
 * square: the brightest object on the page, pulling the eye harder than the
 * blue "Create client" button beside it, because Chromium paints an unchecked
 * checkbox opaque white regardless of colour-scheme. Every other control on the
 * site is a dark glass field with a hairline border, so the native box read as
 * an unstyled leftover. The same square appears on store-admin.php (twice),
 * invoices.php and proposal.php.
 *
 * appearance:none and a drawn tick is what fixes it with no markup change, which
 * matters: proposal.php's box is part of a signing flow and store-admin's are
 * pre-checked from the database. The geometry deliberately matches the custom
 * control login.html already uses (.authf__rem s) — 5px radius, .22 border, .04
 * fill, brand fill when checked — so there is one checkbox on the site, not two.
 * .authf__rem's own rule lives later in this file and still wins, keeping its
 * <s>-based version untouched.
 *
 * This has to sit after .field input{width:100%} to beat it on a tie; a checkbox
 * inside a .field was otherwise a full-width bar.
 *
 * padding is the one declaration that needs !important, for the same reason the
 * phone layer's icon buttons do: a control sized by its box has no use for
 * padding, and five page-level <style> blocks each set a generic
 * "<scope> input { padding:.7rem .85rem }" that a checkbox has no way to opt out
 * of. A page <style> is later in the document than this file, so it wins every
 * tie — and 13.6px of horizontal padding cannot fit inside a 22px border box, so
 * the box grew to its padding instead: "Grant admin access" measured 29.2 x 24.4
 * and read as a squashed oval rather than a square. 22px matches the size those
 * same page rules already ask for and the size the phone layer sets, so there is
 * one checkbox geometry on the site rather than four.
 *
 * border-radius needs the same !important and for the same reason. Those page
 * rules and the phone layer's iOS-zoom rule all round a text field to 10-12px,
 * which is right for a 300px-wide input and is a perfect circle on a 22px box:
 * measured 10px on store-admin.php, 11px on invoices.php, 12px on admin.php. A
 * circular checkbox is not a cosmetic slip — a circle is the universal shape for
 * "pick exactly one of these", so "Featured" and "Active" sat in the same form
 * looking like radio buttons that would cancel each other out. Worse, they sat
 * next to each other in two states, so the one round and one square reading was
 * available at a glance. 6px keeps the square legible at 22px. */
input[type="checkbox"],input[type="radio"]{
  appearance:none;-webkit-appearance:none;box-sizing:border-box;
  width:22px;height:22px;flex:none;margin:0;padding:0 !important;position:relative;top:1px;
  border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.04);
  border-radius:6px !important;display:inline-grid;place-content:center;cursor:pointer;
  transition:background .18s,border-color .18s;
}
input[type="radio"]{border-radius:50% !important}
input[type="checkbox"]::after{content:"";width:10px;height:5px;
  border-left:2px solid #fff;border-bottom:2px solid #fff;margin-top:-2px;
  transform:rotate(-45deg) scale(0);transform-origin:center;
  transition:transform .18s var(--ease)}
input[type="checkbox"]:checked{background:var(--brand);border-color:var(--brand)}
input[type="checkbox"]:checked::after{transform:rotate(-45deg) scale(1)}
input[type="radio"]::after{content:"";width:7px;height:7px;border-radius:50%;background:#fff;
  transform:scale(0);transition:transform .18s var(--ease)}
input[type="radio"]:checked{background:var(--brand);border-color:var(--brand)}
input[type="radio"]:checked::after{transform:scale(1)}
input[type="checkbox"]:hover:not(:disabled),input[type="radio"]:hover:not(:disabled){border-color:rgba(255,255,255,.4)}
input[type="checkbox"]:focus-visible,input[type="radio"]:focus-visible{outline:2px solid var(--aqua);outline-offset:2px}
input[type="checkbox"]:disabled,input[type="radio"]:disabled{opacity:.45;cursor:not-allowed}

/* The file input's button — the last piece of OS chrome on the site.
 *
 * portal/documents.php styles the input's own box (dark glass, 11px radius) but
 * the button inside it is a shadow-DOM pseudo-element that inherits nothing, so
 * Chromium and Safari both paint their default: a light grey rounded rect with
 * near-black text, sitting on a black card twelve pixels from a styled select.
 * It was the brightest and cheapest-looking object on the page for the same
 * reason the white checkbox was — a native control never asked to match.
 *
 * Both spellings are needed and cannot be combined into one selector list: an
 * unrecognised pseudo-element invalidates the whole rule, so a browser that only
 * knows ::-webkit-file-upload-button would drop a rule that also mentions
 * ::file-selector-button, and vice versa. Two identical rules is the price.
 *
 * The negative margins pull the button back against the box's own padding so the
 * label text still reads as part of one field rather than as a button that
 * happens to be near some text. Placed here, beside the checkbox rule, because
 * this is the site's one file input today and any future upload control should
 * come out looking the same without anyone having to remember to style it. */
input[type="file"]::-webkit-file-upload-button{
  appearance:none;-webkit-appearance:none;
  margin:-.15rem .7rem -.15rem -.2rem;padding:.5rem .9rem;
  border:1px solid var(--line);border-radius:9px;
  background:rgba(255,255,255,.07);color:var(--text);
  font:inherit;font-size:.85rem;font-weight:600;letter-spacing:.01em;
  cursor:pointer;transition:background .18s,border-color .18s;
}
input[type="file"]::file-selector-button{
  appearance:none;-webkit-appearance:none;
  margin:-.15rem .7rem -.15rem -.2rem;padding:.5rem .9rem;
  border:1px solid var(--line);border-radius:9px;
  background:rgba(255,255,255,.07);color:var(--text);
  font:inherit;font-size:.85rem;font-weight:600;letter-spacing:.01em;
  cursor:pointer;transition:background .18s,border-color .18s;
}
input[type="file"]:hover::-webkit-file-upload-button{background:rgba(255,255,255,.12);border-color:var(--line-2)}
input[type="file"]:hover::file-selector-button{background:rgba(255,255,255,.12);border-color:var(--line-2)}

.success-banner{display:none;background:rgba(0,119,255,.1);color:var(--aqua-bright);border:1px solid var(--line-2);padding:1rem 1.2rem;border-radius:10px;margin-bottom:1.2rem;font-weight:600}
.success-banner.show{display:block;animation:fadeUp .5s}.form-note{font-size:.85rem;color:var(--text-mut)}

/* page hero */
.page-hero{position:relative;padding-block:clamp(60px,8vw,110px);border-bottom:1px solid var(--line);overflow:hidden}
.page-hero::before{content:"";position:absolute;inset:0;background:radial-gradient(70% 120% at 80% 0%, rgba(0,119,255,.18), transparent 55%)}
.page-hero .container{position:relative}
.crumb{font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mut);margin-bottom:.8rem}
.crumb a:hover{color:var(--aqua-bright)}

/* floating widgets */
.chat-fab{position:fixed;bottom:22px;right:22px;z-index:55;background:var(--grad-aqua);color:#04121C;height:56px;padding:0 1.2rem 0 .7rem;border-radius:999px;display:flex;align-items:center;gap:.6rem;box-shadow:var(--shadow-aqua);font-weight:600;border:none}
.chat-fab .av{width:38px;height:38px;border-radius:50%;background:rgba(4,18,28,.2);display:grid;place-items:center}
.chat-fab svg{width:20px;height:20px}
.chat-panel{position:fixed;bottom:90px;right:22px;z-index:56;width:min(370px,calc(100vw - 44px));height:520px;max-height:70vh;background:var(--ink-panel);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow);display:flex;flex-direction:column;overflow:hidden;transform:translateY(20px) scale(.96);opacity:0;visibility:hidden;transition:all .3s var(--ease);transform-origin:bottom right}
.chat-panel.open{transform:translateY(0) scale(1);opacity:1;visibility:visible}
.chat-head{background:linear-gradient(135deg,#0b1830,#070b14);color:#fff;padding:1rem 1.1rem;display:flex;align-items:center;gap:.7rem;border-bottom:1px solid var(--line)}
.chat-head .av{width:40px;height:40px;border-radius:50%;background:var(--grad-aqua);color:#04121C;display:grid;place-items:center}
.chat-head small{opacity:.75;display:block}
.chat-body{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.7rem}
.msg{max-width:84%;padding:.7rem .9rem;border-radius:12px;font-size:.94rem;line-height:1.45}
.msg.bot{background:var(--glass-2);border:1px solid var(--line);align-self:flex-start;border-bottom-left-radius:3px}
.msg.me{background:var(--grad-aqua);color:#04121C;align-self:flex-end;border-bottom-right-radius:3px;font-weight:500}
.chat-quick{display:flex;flex-wrap:wrap;gap:.4rem;padding:.6rem 1rem}
.chat-quick button{font-size:.8rem;padding:.4rem .7rem;border-radius:999px;border:1px solid var(--line);background:var(--glass);color:var(--text-soft)}
.chat-input{display:flex;gap:.5rem;padding:.7rem;border-top:1px solid var(--line)}
.chat-input input{flex:1;border:1px solid var(--line);border-radius:999px;padding:.6rem .9rem;background:rgba(255,255,255,.03);color:var(--text)}
.chat-input button{background:var(--grad-aqua);color:#04121C;border:none;width:42px;height:42px;border-radius:50%;display:grid;place-items:center}

/* footer */
.site-footer{background:#04060B;border-top:1px solid var(--line);padding-top:64px;margin-top:30px}
.footer-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.2fr;gap:40px;padding-bottom:48px}
@media(max-width:860px){.footer-grid{grid-template-columns:1fr 1fr}}@media(max-width:520px){.footer-grid{grid-template-columns:1fr}}
.site-footer h4{color:#fff;margin-bottom:1rem;font-size:1rem}
.site-footer a{color:var(--text-mut);padding:.3rem 0;display:inline-block;transition:color .2s}.site-footer a:hover{color:var(--aqua-bright)}
.footer-brand p{color:var(--text-mut);margin:1rem 0;max-width:330px}
.footer-bottom{border-top:1px solid var(--line);padding:22px 0;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;color:var(--text-mut);font-size:.85rem}
.social{display:flex;gap:.6rem}.social a{width:38px;height:38px;border-radius:10px;background:var(--glass);display:grid;place-items:center;color:var(--text-soft)}.social a:hover{background:var(--aqua);color:#04121C}.social svg{width:18px;height:18px}

/* app shell (portal/analytics/admin) */
.app-shell{display:grid;grid-template-columns:260px 1fr;min-height:100vh}
@media(max-width:900px){.app-shell{grid-template-columns:1fr}.app-side{display:none}}
.app-side{background:#04060B;border-right:1px solid var(--line);padding:24px 18px;position:sticky;top:0;height:100vh;overflow-y:auto}

/* Portal rail brand lockup — a customer's own business name, not ours.
   ------------------------------------------------------------------
   The site header keeps .brand__name on one line because the word there is
   always "DARK WATER". In the portal rail the word is whatever the customer
   called their company, and 260px of rail minus a 40px mark holds about
   sixteen characters at the old size — "EXAMPLE CLIENT CO" was already being
   cut off after the C.

   So in the rail, and only in the rail, the name wraps. Two lines maximum,
   because a third would start pushing the navigation down the screen; past
   that it ellipses, and the full name is on the link's title. The size step
   is set per name in layout.php, which is what keeps two lines enough.

   Scoped to .app-side on purpose: .brand__name is a marketing-site class as
   well, and nothing about the header or the footer changes here. */
.app-side .brand{align-items:flex-start;gap:.6rem;min-width:0}
.app-side .brand__icon{flex:0 0 auto}
.app-side .brand__text{min-width:0;flex:1 1 auto;white-space:normal}
.app-side .brand__name{
  white-space:normal;overflow-wrap:anywhere;text-wrap:balance;line-height:1.2;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
/* "Powered by Dark Water" is fixed text, so it gets one line and slightly
   tighter tracking to buy it — wrapped, it breaks after "DARK" and reads as
   two half-lines of noise under a name that may itself be two lines. */
.app-side .brand__sub{white-space:nowrap;letter-spacing:.2em;margin-top:6px;
  overflow:hidden;text-overflow:ellipsis}

.app-nav{margin-top:1.5rem;display:flex;flex-direction:column;gap:.2rem}
.app-nav a{display:flex;align-items:center;gap:.7rem;padding:.7rem .8rem;border-radius:10px;color:var(--text-soft);font-weight:500;font-size:.92rem}
.app-nav a.active,.app-nav a:hover{background:rgba(0,119,255,.12);color:var(--aqua-bright)}.app-nav svg{width:20px;height:20px}
.app-main{padding:clamp(20px,3vw,36px)}
.app-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:1.8rem;gap:1rem;flex-wrap:wrap}
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}@media(max-width:980px){.kpi-grid{grid-template-columns:repeat(2,1fr)}}@media(max-width:520px){.kpi-grid{grid-template-columns:1fr}}
.kpi{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius);padding:22px;backdrop-filter:blur(12px)}
.kpi .lbl{color:var(--text-mut);font-size:.82rem;font-weight:600;display:flex;align-items:center;gap:.5rem}.kpi .lbl svg{width:18px;height:18px;color:var(--aqua)}
.kpi .val{font-family:var(--font-display);font-size:2rem;font-weight:700;margin:.3rem 0}.kpi .chg{font-size:.82rem;font-weight:700}.chg.up{color:#3B9EFF}.chg.down{color:#F87171}
.panel{background:var(--glass);border:1px solid var(--glass-brd);border-radius:var(--radius);padding:24px;backdrop-filter:blur(12px)}
.panel h3{font-size:1.12rem;margin-bottom:1rem;display:flex;justify-content:space-between;align-items:center}
table.data{width:100%;border-collapse:collapse;font-size:.92rem}
table.data th{text-align:left;color:var(--text-mut);font-weight:600;padding:.7rem .6rem;border-bottom:1px solid var(--line);font-size:.78rem;letter-spacing:.04em;text-transform:uppercase}
table.data td{padding:.8rem .6rem;border-bottom:1px solid var(--line)}
/* A status pill is a single token — it must never break.
 *
 * On portal/projects.php the pill sits inline inside an <h3>, and the phone
 * layer sets overflow-wrap:anywhere on headings so long client names cannot
 * overflow their card. The pill inherited it, so in the ~40px of line box left
 * beside a three-line project title "Active" broke to "Ac / tiv / e" — and
 * because a pill is inline-block with a 999px radius, a 42x53 box renders as a
 * circle with letters stacked inside it. Three pills on that page, plus "In
 * progress" on requests.php breaking at its space.
 *
 * white-space:nowrap removes every soft-wrap opportunity, which makes the
 * inherited overflow-wrap moot as well; both are declared so the intent survives
 * someone later relaxing one of them. This belongs on the component rather than
 * in the phone layer because a status pill that wraps is wrong at any width. */
.pill{display:inline-block;padding:.25rem .7rem;border-radius:999px;font-size:.76rem;font-weight:700;
  white-space:nowrap;overflow-wrap:normal}
.pill.up2{background:rgba(0,119,255,.15);color:#3B9EFF}.pill.new{background:rgba(0,119,255,.15);color:#9CC9FF}.pill.pending{background:rgba(245,191,86,.15);color:#fbbf24}.pill.lost{background:rgba(248,113,113,.15);color:#f87171}
.bar-chart{display:flex;align-items:flex-end;gap:8px;height:120px}.bar-chart .bar{flex:1;background:var(--grad-aqua);border-radius:4px 4px 0 0;min-height:4px}
.legend{display:flex;flex-direction:column;gap:.5rem}.legend div{display:flex;align-items:center;gap:.5rem;font-size:.9rem}.legend .dot{width:12px;height:12px;border-radius:3px}

/* reveal */
.reveal{opacity:0;transform:translateY(28px);filter:blur(6px);transition:opacity .8s var(--ease),transform .8s var(--ease),filter .8s var(--ease)}
.reveal.in{opacity:1;transform:none;filter:blur(0)}
.reveal[data-delay="1"]{transition-delay:.08s}.reveal[data-delay="2"]{transition-delay:.16s}.reveal[data-delay="3"]{transition-delay:.24s}.reveal[data-delay="4"]{transition-delay:.32s}
@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* scroll progress + utils */
.cine-progress{position:fixed;top:0;left:0;height:2px;width:0;z-index:90;background:var(--grad-aqua-h);box-shadow:0 0 14px rgba(0,119,255,.7);transition:width .1s linear}
.mt-1{margin-top:.5rem}.mt-2{margin-top:1rem}.mt-3{margin-top:1.6rem}.mt-4{margin-top:2.4rem}.mb-0{margin-bottom:0}
.flex{display:flex;gap:1rem;align-items:center;flex-wrap:wrap}.between{justify-content:space-between}
.hr{height:1px;background:var(--line);border:none;margin:2rem 0}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--aqua);color:#04121C;padding:.6rem 1rem;z-index:100}.skip-link:focus{left:0}

/* --- responsive hardening --- */
.cc-grid>*{min-width:0}
table.data{min-width:0}
@media(max-width:620px){
  .panel{overflow-x:auto}
  table.data{font-size:.82rem}
  .app-top{align-items:flex-start}
}

.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}

/* --- footer polish: white btn, 2x logo, more breathing room --- */
.btn--white{background:#fff;color:#04121C;border-color:#fff}
.btn--white:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(255,255,255,.18);background:#eef6ff}
.site-footer{padding-top:88px}
.site-footer .footer-grid{gap:64px;padding-bottom:64px}
.site-footer .brand__icon{width:88px;height:88px}
.site-footer .brand__name{font-size:1.7rem}
.site-footer .brand__sub{font-size:.62rem;margin-top:6px}
.site-footer .footer-brand .brand{gap:1rem;margin-bottom:.4rem}
.site-footer h4{margin-bottom:1.3rem;font-size:1.05rem}
.site-footer a{padding:.45rem 0}
.site-footer .footer-bottom{padding:28px 0}
@media(max-width:860px){ .site-footer .footer-grid{gap:44px} }

/* --- footer refinements: readable white btn, uncramped + glowing logo --- */
.site-footer .footer-brand .brand{flex-direction:column;align-items:flex-start;gap:1.1rem;margin-bottom:.6rem}
.site-footer .brand__icon{filter:drop-shadow(0 0 26px rgba(0,119,255,.6)) drop-shadow(0 0 10px rgba(59,158,255,.4))}
.site-footer .brand__name{margin-top:.1rem;line-height:1.05}
.site-footer .btn--white{color:#06243A;font-weight:800;letter-spacing:.01em}
.site-footer .btn--white svg{stroke:#06243A}

/* --- hero paragraph: vibrant, glowing white --- */
.hero .lead{
  color:#F2F8FF;
  font-weight:500;
  font-size:clamp(1.16rem,1.7vw,1.44rem);
  line-height:1.6;
  text-shadow:0 0 20px rgba(59,158,255,.30), 0 0 6px rgba(0,119,255,.25), 0 1px 3px rgba(0,0,0,.55);
}

/* --- scarlet accent word --- */
.word-red{
  background:linear-gradient(135deg,#FF3A59,#E01030 55%,#B00C24);
  -webkit-background-clip:text; background-clip:text; color:transparent;
  filter:drop-shadow(0 0 22px rgba(255,45,75,.5));
}

/* ============================================================
   PREMIUM UPGRADE v2 — buttons & navigation
   Refined, editorial, high-end. Appended last to cascade over base.
   ============================================================ */

/* ---- Buttons: refined shape, depth, tactile hover, sheen ---- */
.btn{
  border-radius:13px;
  padding:.9rem 1.7rem;
  font-weight:600;
  letter-spacing:.015em;
  position:relative;
  overflow:hidden;
  transition:transform .35s var(--ease), box-shadow .35s var(--ease),
             background .35s var(--ease), color .25s, border-color .25s;
}
/* moving sheen sweep on hover (over all buttons) */
.btn::after{
  content:"";position:absolute;top:0;left:-130%;width:55%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.28),transparent);
  transform:skewX(-18deg);transition:left .65s var(--ease);pointer-events:none;
}
.btn:hover::after{left:150%}
.btn:active{transform:translateY(-1px) scale(.992)}

/* Primary — deeper gradient, defined edge, layered glow, top gloss */
.btn--aqua{
  background:linear-gradient(135deg,#7DF1DE 0%,#0077FF 46%,#0C87C7 100%);
  color:#03121C;font-weight:700;
  border:1px solid rgba(125,241,222,.5);
  box-shadow:0 10px 28px rgba(0,119,255,.34), inset 0 1px 0 rgba(255,255,255,.45);
}
.btn--aqua::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.22),transparent 42%);
}
.btn--aqua:hover{
  transform:translateY(-2px);
  box-shadow:0 20px 46px rgba(0,119,255,.5), 0 4px 14px rgba(59,158,255,.32),
             inset 0 1px 0 rgba(255,255,255,.55);
}

/* Secondary / glass (Client Login) — refined, gradient-bordered */
.btn--glass{
  background:linear-gradient(180deg,rgba(255,255,255,.085),rgba(255,255,255,.035));
  color:#EAF6FF;
  border:1px solid rgba(255,255,255,.15);
  box-shadow:0 6px 18px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.1);
}
.btn--glass:hover{
  transform:translateY(-2px);
  color:#fff;border-color:rgba(59,158,255,.5);
  background:linear-gradient(180deg,rgba(59,158,255,.13),rgba(0,119,255,.05));
  box-shadow:0 14px 32px rgba(0,0,0,.38), 0 0 0 1px rgba(59,158,255,.22),
             inset 0 1px 0 rgba(255,255,255,.14);
}
.btn--ghost{border-color:rgba(255,255,255,.16)}
.btn--ghost:hover{border-color:var(--aqua-bright);color:var(--aqua-bright)}
.btn--lg{padding:1.05rem 2.1rem;border-radius:15px}

/* ---- Header: more presence + accent hairline ---- */
.site-header{
  height:82px;
  background:linear-gradient(180deg,rgba(5,7,13,.74),rgba(5,7,13,.44));
  border-bottom:1px solid rgba(255,255,255,.06);
}
.site-header::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.4),rgba(0,119,255,.4),transparent);
  opacity:.55;
}
.site-header.scrolled{background:rgba(5,7,13,.9);box-shadow:0 12px 44px rgba(0,0,0,.5)}

/* ---- Nav links: kill the boxy fill, add animated underline ---- */
.nav__links{gap:.2rem}
.nav__links > a, .has-dropdown > a{
  position:relative;font-size:.9rem;font-weight:500;letter-spacing:.012em;
  padding:.62rem .9rem;border-radius:10px;color:var(--text-soft);
  background:transparent !important;
  transition:color .25s var(--ease);
}
.nav__links > a::after, .has-dropdown > a::after{
  content:"";position:absolute;left:.9rem;right:.9rem;bottom:.34rem;height:2px;border-radius:2px;
  background:var(--grad-aqua);transform:scaleX(0);transform-origin:left;opacity:0;
  transition:transform .3s var(--ease),opacity .3s var(--ease);
}
.nav__links > a:hover, .has-dropdown:hover > a, .nav__links > a.active{color:#fff}
.nav__links > a:hover::after, .has-dropdown:hover > a::after,
.nav__links > a.active::after{transform:scaleX(1);opacity:1}

/* Divider between nav and actions */
.nav__actions{gap:.7rem;padding-left:1.25rem;position:relative}
.nav__actions::before{
  content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:1px;height:26px;background:linear-gradient(180deg,transparent,rgba(255,255,255,.16),transparent);
}
.nav__actions .btn{padding:.7rem 1.3rem;font-size:.9rem;border-radius:12px}

/* ---- Dropdown: premium panel with accent-bar items ---- */
.dropdown{
  min-width:252px;padding:.55rem;border-radius:16px;
  background:linear-gradient(180deg,rgba(16,24,38,.98),rgba(10,16,28,.98));
  border:1px solid rgba(255,255,255,.1);
  box-shadow:0 30px 70px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05);
}
.dropdown a{position:relative;padding:.7rem .95rem;border-radius:10px;color:var(--text-soft);
  transition:background .2s,color .2s,padding .2s}
.dropdown a:hover{background:rgba(59,158,255,.1);color:#fff;padding-left:1.2rem}
.dropdown a::before{content:"";position:absolute;left:.55rem;top:50%;transform:translateY(-50%);
  width:3px;height:0;border-radius:3px;background:var(--grad-aqua);transition:height .2s var(--ease)}
.dropdown a:hover::before{height:55%}

/* Brand micro-refinement */
.brand__name{letter-spacing:.16em}
.brand:hover .brand__icon{filter:drop-shadow(0 0 16px rgba(59,158,255,.6))}

/* Respect reduced motion */
@media(prefers-reduced-motion:reduce){
  .btn,.btn::after,.nav__links > a::after,.has-dropdown > a::after,.dropdown a{transition:none !important}
  .btn:hover{transform:none}
}

/* keep dropdown labels + caret on one line; refine caret */
.nav__links{flex-wrap:nowrap}
.nav__links > a, .has-dropdown > a{white-space:nowrap}
.has-dropdown > a{display:inline-flex;align-items:center;gap:.34rem}
.has-dropdown > a{font-variant-numeric:normal}

/* ============================================================
   ENTERPRISE RESTRAINT v3 — "major tech", not consumer.
   Flattens buttons, cools + desaturates the palette, cuts bloom,
   drops the clashing red. Appended last so it wins the cascade.
   Reference feel: Stripe / Linear / Vercel infrastructure sites.
   ============================================================ */
:root{
  /* truer, colder graphite-black + refined neutrals */
  --void:#000103; --abyss:#04060A; --deep:#080B12; --deep-2:#0C1017; --ink-panel:#10141C;
  --slate:#141922; --slate-2:#1A212C; --hairline:rgba(255,255,255,.08);
  /* one controlled accent family — desaturated azure, mint pulled out */
  --aqua:#4FB4E6; --aqua-bright:#7FCBEE; --aqua-deep:#2A8FC4; --aqua-soft:#BFE0F2;
  --grad-aqua:linear-gradient(135deg,#6FC3EC 0%,#3EA6DE 52%,#1E77AC 100%);
  --grad-aqua-h:linear-gradient(90deg,#2A8FC4,#7FCBEE 50%,#2A8FC4);
  /* neutral elevation shadows — no colored bloom */
  --shadow:0 24px 60px rgba(0,0,0,.55), 0 6px 20px rgba(0,0,0,.4);
  --shadow-aqua:0 8px 22px rgba(0,0,0,.42);
  --line:rgba(255,255,255,.07); --line-2:rgba(127,203,238,.20);
  /* cooler ribbon, no green */
  --ribbon-1:#8FD3F4; --ribbon-2:#3EA6DE; --ribbon-3:#1E77AC; --ribbon-4:#0A3B57;
  --text:#E9EEF5; --text-soft:#A6B2C4; --text-mut:#6E7A8C;
}

/* Eyebrow: quieter, steel-tone, less candy */
.eyebrow{color:var(--aqua-bright);letter-spacing:.24em;font-size:.72rem}

/* Kill the clashing red — headline goes monochrome + one restrained accent */
.word-red{background:none;-webkit-background-clip:border-box;background-clip:border-box;
  color:var(--text);filter:none}
.hero h1,.gradient-text{text-shadow:none}
.gradient-text{background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---- Buttons: flat, precise, no gloss/sheen/bloom ---- */
.btn{border-radius:9px;letter-spacing:.005em;overflow:visible}
.btn::after{display:none!important}          /* remove moving sheen sweep */
.btn--lg{border-radius:10px}
.btn--aqua{
  background:linear-gradient(180deg,#49AEE2,#2E93CC);
  color:#04121C;font-weight:600;
  border:1px solid rgba(127,203,238,.35);
  box-shadow:0 2px 10px rgba(0,0,0,.35);
}
.btn--aqua::before{display:none!important}    /* remove top gloss */
.btn--aqua:hover{
  transform:translateY(-1px);
  background:linear-gradient(180deg,#5CBAEA,#3A9FD6);
  box-shadow:0 6px 18px rgba(0,0,0,.4);
}
.btn--glass{
  background:rgba(255,255,255,.045);color:#E9EEF5;
  border:1px solid var(--hairline);box-shadow:none;
}
.btn--glass:hover{
  transform:translateY(-1px);color:#fff;border-color:var(--line-2);
  background:rgba(127,203,238,.08);box-shadow:none;
}
.btn--outline{background:transparent;border:1px solid var(--hairline);box-shadow:none}
.btn--outline:hover{transform:translateY(-1px);border-color:var(--line-2);
  background:rgba(127,203,238,.06);box-shadow:none}
.btn--ghost{background:transparent;border-color:var(--hairline)}
.btn--ghost:hover{border-color:var(--aqua);color:var(--aqua-bright);transform:translateY(-1px)}

/* ---- Ambient: dial the cyan wash way down for a graphite feel ---- */
body::before{background:
  radial-gradient(1200px 800px at 82% -12%, rgba(30,119,172,.10), transparent 60%),
  radial-gradient(900px 720px at -12% 112%, rgba(20,90,130,.07), transparent 55%),
  var(--abyss)}

/* ---- Signature ribbon: a controlled light-field, not a glowing blob ---- */
.hero__aurora::before{opacity:.30;filter:blur(85px);
  background:conic-gradient(from 210deg at 62% 42%,
    var(--ribbon-4) 0deg, var(--ribbon-3) 80deg, var(--ribbon-2) 150deg,
    var(--ribbon-2) 200deg, transparent 300deg, var(--ribbon-4) 360deg)}
.hero__aurora::after{opacity:.22;filter:blur(90px);
  background:radial-gradient(closest-side,var(--ribbon-2),var(--ribbon-3) 45%,transparent 72%)}
.hero__aurora>i{opacity:.35;
  background:linear-gradient(90deg,transparent,rgba(127,203,238,.16),rgba(62,166,222,.24),rgba(30,119,172,.10),transparent)}

/* ---- Surfaces: solid graphite panels instead of glossy glass ---- */
.card{background:linear-gradient(180deg,var(--slate),var(--deep-2));border:1px solid var(--hairline);backdrop-filter:none}
.card__icon{background:rgba(79,180,230,.10);border:1px solid var(--hairline);color:var(--aqua-bright);border-radius:11px}

/* ---- Header: cleaner hairline, no glow ---- */
.brand__icon{filter:none}
.site-header{background:rgba(4,6,10,.72);border-bottom:1px solid var(--hairline)}
.site-header.scrolled{background:rgba(4,6,10,.9);box-shadow:0 1px 0 var(--hairline)}

/* ---- AI launcher: refined dark chip, not a bright candy pill ---- */
.chat-fab{background:rgba(16,20,28,.92);color:#E9EEF5;border:1px solid var(--hairline);
  box-shadow:0 8px 24px rgba(0,0,0,.45);font-weight:500;backdrop-filter:blur(10px)}
.chat-fab .av{background:var(--grad-aqua);color:#04121C}

/* ============================================================
   OFFICIAL BRAND v4 — DW mark + electric blue #0077FF
   Adopted from DW_LOGO_CONCEPTS/FINAL brand board.
   Overrides the aqua system site-wide. Appended last = wins.
   ============================================================ */
:root{
  --abyss:#0A0A0A; --deep:#0D0E11; --deep-2:#111214; --ink-panel:#14161C; --slate:#1C1F24; --slate-2:#2D3138;
  --brand:#0077FF; --brand-bright:#3B9EFF;
  --aqua:#0077FF; --aqua-bright:#3B9EFF; --aqua-deep:#0A80FF; --aqua-soft:#9CC9FF;
  --grad-aqua:linear-gradient(135deg,#3B9EFF 0%,#0077FF 58%,#0A5FCC 100%);
  --grad-aqua-h:linear-gradient(90deg,#0A80FF,#3B9EFF 50%,#0A80FF);
  --ribbon-1:#3B9EFF; --ribbon-2:#0077FF; --ribbon-3:#0A5FCC; --ribbon-4:#062E66;
  --text:#E6E6E6; --text-soft:#AEB4BD; --text-mut:#767C86;
  --line:rgba(255,255,255,.07); --line-2:rgba(0,119,255,.35); --hairline:rgba(255,255,255,.10);
  --shadow-aqua:0 8px 22px rgba(0,0,0,.42);
}
.eyebrow{color:var(--brand-bright)}
.gradient-text{background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.word-red{background:none!important;color:var(--text)!important;filter:none!important}

/* Primary button = solid electric blue, white text (no gloss/bloom) */
.btn--aqua{background:linear-gradient(180deg,#1F8BFF,#0077FF)!important;color:#fff!important;
  border:1px solid rgba(59,158,255,.45)!important;box-shadow:0 4px 16px rgba(0,119,255,.28)!important}
.btn--aqua::before{display:none!important}
.btn--aqua:hover{transform:translateY(-1px);background:linear-gradient(180deg,#3B9EFF,#0A80FF)!important;
  box-shadow:0 8px 24px rgba(0,119,255,.4)!important}
.btn--outline{background:transparent;border:1px solid var(--hairline)}
.btn--outline:hover{border-color:var(--line-2);background:rgba(0,119,255,.08)}
.btn--outline svg{color:var(--brand-bright)}

/* ambient wash → cool blue graphite */
body::before{background:
  radial-gradient(1200px 800px at 82% -12%, rgba(0,119,255,.10), transparent 60%),
  radial-gradient(900px 720px at -12% 112%, rgba(0,90,180,.06), transparent 55%),
  var(--abyss)}

/* card accents to blue */
.card__icon{background:rgba(0,119,255,.10);color:var(--brand-bright)}
.chat-fab .av{background:var(--grad-aqua);color:#fff}

/* ---- Futuristic WebGL hero field (used on homepage) ---- */
#fxCanvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;display:block}

/* ---- Robot 'living system' section ---- */
.scene-card{position:relative;overflow:hidden;height:520px;border-radius:20px;border:1px solid var(--hairline);
  background:radial-gradient(120% 140% at 15% 0%, #12141a 0%, #0a0b0f 55%, #070709 100%);box-shadow:var(--shadow)}
.scene-card::before{content:"";position:absolute;left:-10%;top:-30%;width:60%;height:80%;
  background:radial-gradient(closest-side, rgba(0,119,255,.16), transparent 70%);filter:blur(30px);pointer-events:none}
.scene-card .spotlight{position:absolute;width:520px;height:520px;left:-260px;top:-260px;pointer-events:none;border-radius:50%;
  filter:blur(40px);opacity:0;transition:opacity .3s ease;background:radial-gradient(circle at center, rgba(120,180,255,.22), rgba(0,119,255,.10) 40%, transparent 72%)}
.scene-card:hover .spotlight{opacity:1}
.scene-grid{position:relative;z-index:2;display:grid;grid-template-columns:1fr 1fr;height:100%}
.scene-copy{display:flex;flex-direction:column;justify-content:center;padding:clamp(24px,4vw,48px)}
.scene-copy h2{margin-bottom:1rem}
.scene-copy p{color:var(--text-soft);max-width:34ch;margin-bottom:1.6rem}
.scene-3d{position:relative}
.scene-3d spline-viewer{position:absolute;inset:0;width:100%;height:100%;display:block}
.scene-3d .loading{position:absolute;inset:0;display:grid;place-items:center;color:var(--text-mut);font-size:.85rem;text-align:center}
.scene-3d .loading .dot{width:34px;height:34px;border-radius:50%;border:2px solid var(--hairline);border-top-color:var(--brand);animation:spin 1s linear infinite;margin:0 auto .6rem}
@keyframes spin{to{transform:rotate(360deg)}}
@media(max-width:820px){.scene-card{height:auto}.scene-grid{grid-template-columns:1fr}.scene-3d{height:340px}.scene-copy{padding-top:36px}}
/* DW mark is a wide horizontal monogram — keep aspect in header/footer */
.brand__icon{width:auto!important;height:28px!important;filter:none!important}
.site-footer .brand__icon{height:24px!important}
/* Header brand: keep compact + on one line (tagline lives in footer) */
.brand{flex:0 0 auto}
.brand__name{white-space:nowrap}
.brand__text{white-space:nowrap}
.site-header .brand__sub{display:none}
.site-footer .brand__sub{display:block}

/* ============================================================
   BRAND PRESENCE v5 — logo everywhere + black-on-black
   Tone-on-tone embossed DW mark, per the brand board mockups.
   ============================================================ */
/* hero: small glowing mark above the eyebrow */
.hero__brandmark{height:44px;width:auto;display:block;margin:0 auto 1.3rem;
  filter:drop-shadow(0 0 20px rgba(0,119,255,.4))}

/* black-on-black brand band — embossed giant mark + four pillars */
.brand-band{position:relative;overflow:hidden;border:1px solid var(--hairline);border-radius:22px;
  background:linear-gradient(160deg,#101114 0%,#0A0B0D 55%,#070708 100%);
  padding:clamp(40px,6vw,84px)}
.brand-band__mark{position:absolute;right:-4%;top:50%;transform:translateY(-50%);height:135%;width:auto;
  pointer-events:none;user-select:none;
  filter:drop-shadow(0 1px 0 rgba(255,255,255,.045)) drop-shadow(0 -2px 8px rgba(0,0,0,.9))}
.brand-band__inner{position:relative;z-index:1;max-width:640px}
.brand-band h2{margin:.4rem 0 2rem}
.pillars{display:grid;grid-template-columns:repeat(2,1fr);gap:1.6rem 2.2rem}
.pillar b{font-family:var(--font-display);font-size:.82rem;letter-spacing:.22em;color:#fff;display:block;margin-bottom:.35rem}
.pillar b::before{content:"";display:inline-block;width:18px;height:2px;background:var(--brand);margin-right:.6rem;vertical-align:middle}
.pillar p{color:var(--text-mut);font-size:.92rem;line-height:1.6;margin:0}
@media(max-width:720px){.pillars{grid-template-columns:1fr}.brand-band__mark{opacity:.7;height:110%}}

/* footer: giant tonal watermark */
.site-footer{position:relative;overflow:hidden}
.footer-watermark{position:absolute;right:-2%;bottom:-26%;height:280px;width:auto;pointer-events:none;user-select:none;
  filter:drop-shadow(0 1px 0 rgba(255,255,255,.04))}
.site-footer>.container{position:relative;z-index:1}

/* robot-section loader: pulsing DW mark instead of a spinner */
.scene-3d .loading img{height:38px;width:auto;margin:0 auto .7rem;display:block;animation:markpulse 1.6s ease-in-out infinite}
@keyframes markpulse{0%,100%{opacity:.35;transform:scale(1)}50%{opacity:.9;transform:scale(1.06)}}
@media (prefers-reduced-motion:reduce){.scene-3d .loading img{animation:none;opacity:.7}}
/* keep full header (nav + both CTAs) inside the viewport on laptops */
@media(max-width:1560px){
  .nav__links a{padding:.5rem .55rem;font-size:.88rem}
  .nav{gap:.9rem}
  .brand__name{font-size:1.1rem;letter-spacing:.16em}
}

/* ============================================================
   TYPE v6 — Satoshi (official brand face) + true black-on-black
   ============================================================ */
:root{
  --font-display:'Satoshi','Space Grotesk','Segoe UI',system-ui,sans-serif;
  --font-body:'Satoshi','Inter','Segoe UI',system-ui,sans-serif;
}
h1{font-weight:900;letter-spacing:-.035em}
h2{font-weight:700;letter-spacing:-.03em}
.hero h1{font-weight:900}
.btn{font-weight:600}

/* black-on-black: kill the blue ambient wash — flat ink, light lives in accents */
body::before{background:
  radial-gradient(1100px 700px at 80% -10%, rgba(255,255,255,.015), transparent 60%),
  var(--abyss)}

/* global reactive cursor glow (desktop, motion-ok only) */
.cursor-glow{position:fixed;left:0;top:0;width:560px;height:560px;border-radius:50%;pointer-events:none;z-index:3;
  background:radial-gradient(circle at center, rgba(0,119,255,.10), rgba(0,119,255,.035) 42%, transparent 70%);
  mix-blend-mode:screen;will-change:transform;opacity:0;transition:opacity .4s}
body:hover .cursor-glow{opacity:1}
@media (pointer:coarse),(prefers-reduced-motion:reduce){.cursor-glow{display:none}}
/* Belt and braces for the portal. main.js already refuses to build the glow on
   a page with <body data-app>, but a cached copy of main.js on a machine that
   loaded the site last week would still build one, and a stale script is not a
   good enough reason to ship a moving light across a page of billing figures. */
body[data-app] .cursor-glow{display:none!important}
/* avoid scroll-cue colliding with the hero trust row on short viewports */
@media(max-height:980px){.scroll-cue{display:none}}

/* ============================================================
   HERO v7 — luxury black-water video surface
   Real black ripples; the page fades into it from pure dark.
   ============================================================ */
.hero__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  filter:brightness(.82) contrast(1.06) saturate(.85)}
.hero .hero__veil{background:
  radial-gradient(62% 55% at 50% 42%, transparent, rgba(6,7,9,.62) 88%),
  linear-gradient(180deg, rgba(6,7,9,.66), rgba(6,7,9,.12) 26%, rgba(6,7,9,.28) 70%, #0A0A0A)}
@media (prefers-reduced-motion:reduce){
  .hero__video{display:none}
  .hero{background:url("../video/hero-poster.jpg") center/cover no-repeat #0A0A0A}
}

/* ============================================================
   v8 — hero reverted to circle-wave field; water video now lives
   in the Brand Philosophy band (black-on-black cinematography).
   ============================================================ */
.hero__video{display:none}   /* retired from hero */
.brand-band__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  filter:brightness(.72) contrast(1.06) saturate(.8)}
.brand-band__veil{position:absolute;inset:0;z-index:0;
  background:linear-gradient(100deg, rgba(7,7,8,.92) 0%, rgba(7,7,8,.78) 42%, rgba(7,7,8,.25) 75%, rgba(7,7,8,.55) 100%)}
.brand-band__mark{z-index:1;opacity:.85;
  filter:drop-shadow(0 1px 0 rgba(255,255,255,.06)) drop-shadow(0 -2px 10px rgba(0,0,0,.95))}
.brand-band__inner{z-index:2}
@media (prefers-reduced-motion:reduce){
  .brand-band__video{display:none}
  .brand-band{background:url("../video/hero-poster.jpg") center/cover no-repeat #0A0B0D}
}

/* ============================================================
   THE BRAIN — DW-mark depth-scan section (below hero)
   ============================================================ */
.brain{position:relative;height:92vh;min-height:560px;overflow:hidden;background:#04060A;border-block:1px solid var(--hairline)}
#brainCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.brain__copy{position:absolute;left:0;right:0;bottom:clamp(36px,7vh,80px);z-index:2;text-align:center;padding:0 24px;pointer-events:none}
.brain__copy h2{margin:.5rem 0 .7rem}
.brain__copy .lead{max-width:52ch;margin-inline:auto;font-size:clamp(.98rem,1.4vw,1.15rem)}
@media(max-height:700px){.brain{height:110vh}}
/* brain: keep copy readable through the dot-wave peaks */
.brain::after{content:"";position:absolute;left:0;right:0;bottom:0;height:46%;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(8,9,12,.78) 62%,rgba(8,9,12,.92))}
.brain__copy{z-index:2}
/* Brain is now the hero — full viewport opening scene */
.brain{height:100svh;min-height:620px;border-top:none}
/* Brain variant II — full-bleed section, framed by hairlines */
.brain--alt{height:92vh;min-height:560px;border-block:1px solid var(--hairline)}
/* ripple is the hero again; brain drops to a full-bleed section */
.brain{height:92vh;border-block:1px solid var(--hairline)}
/* hero brandmark — commanding size */
.hero__brandmark{height:clamp(72px,9vw,124px);margin-bottom:1.6rem}
/* Brain canvases — BOTH instances fill their section (fixes Brain II cut-off) */
.brain canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Division icon line (from brand board "Usage" row) */
.divisions{display:flex;justify-content:center;gap:clamp(1.4rem,4.5vw,3.4rem);margin-top:2rem;flex-wrap:wrap}
.divisions span{display:flex;flex-direction:column;align-items:center;gap:.55rem;color:var(--text-mut);
  font-size:.68rem;letter-spacing:.24em;font-weight:600}
.divisions svg{width:24px;height:24px;color:var(--text-soft)}
/* App-mark row (brand board "Icon & App Marks") in the hero */
.appmarks{display:flex;gap:.9rem;justify-content:center;align-items:center;margin-top:2rem}
.am{width:52px;height:52px;border-radius:14px;display:grid;place-items:center;border:1px solid var(--hairline);
  transition:transform .25s var(--ease)}
.am:hover{transform:translateY(-3px)}
.am img{width:62%;height:auto;display:block}
.am--dark{background:#111214}
.am--light{background:#E6E6E6;border-color:transparent}
.am--blue{background:#0077FF;border-color:rgba(59,158,255,.5)}
.am--bare{background:transparent;border-color:transparent}
@media(max-width:560px){.am{width:44px;height:44px;border-radius:12px}.appmarks{gap:.7rem}}
/* Flagship product row — living icons (sacred mark, per-product atmosphere) */
.prodrow{display:flex;gap:1.1rem;justify-content:center;align-items:flex-start;margin-top:2.1rem;flex-wrap:wrap}
.ptile{position:relative;width:78px;display:grid;justify-items:center;cursor:pointer;
  transition:transform .22s var(--ease)}
.ptile:hover{transform:translateY(-4px)}
.ptile canvas{width:78px;height:78px;border-radius:18px;border:1px solid var(--hairline);display:block;
  box-shadow:0 8px 26px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.02)}
.ptile img{position:absolute;top:39px;left:50%;transform:translate(-50%,-50%);width:44%;height:auto;pointer-events:none}
.ptile i{font-style:normal;margin-top:.55rem;font-size:.6rem;letter-spacing:.22em;font-weight:600;color:var(--text-mut)}
.ptile:hover i{color:var(--text-soft)}
@media(max-width:640px){.ptile{width:60px}.ptile canvas{width:60px;height:60px;border-radius:14px}.ptile img{top:30px}.prodrow{gap:.8rem}}
/* ---- premium hero: text sits on glass, never floats ---- */
.hero__inner{background:rgba(9,11,15,.55);backdrop-filter:blur(16px) saturate(120%);
  -webkit-backdrop-filter:blur(16px) saturate(120%);border:1px solid var(--hairline);
  border-radius:26px;padding:clamp(26px,4vw,52px);max-width:960px}
.brain__copy{left:50%;right:auto;transform:translateX(-50%);width:min(780px,calc(100% - 40px));
  background:rgba(9,11,15,.55);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--hairline);border-radius:22px;padding:1.5rem 2rem 1.7rem}
/* ---- tile presentation modal ---- */
.ptile--big{width:170px}
.ptile--big canvas{width:170px;height:170px;border-radius:38px}
.ptile--big img{top:85px}
.pmodal{position:fixed;inset:0;z-index:95;display:grid;place-items:center;
  background:rgba(4,5,8,.72);backdrop-filter:blur(10px);opacity:0;transition:opacity .22s}
.pmodal.in{opacity:1}
.pmodal__card{position:relative;display:grid;justify-items:center;gap:.5rem;
  background:rgba(12,14,19,.88);border:1px solid var(--hairline);border-radius:26px;
  padding:2.2rem 2.6rem 2.4rem;width:min(360px,calc(100vw - 40px));text-align:center;
  transform:scale(.94) translateY(8px);transition:transform .28s var(--ease)}
.pmodal.in .pmodal__card{transform:scale(1) translateY(0)}
.pmodal__card h3{font-size:1.35rem;margin-top:.7rem}
.pmodal__card p{color:var(--text-soft);font-size:.92rem;margin-bottom:.7rem}
.pmodal__x{position:absolute;top:8px;right:14px;background:none;border:none;color:var(--text-mut);font-size:1.7rem;cursor:pointer;line-height:1}
.pmodal__x:hover{color:#fff}
/* text glass: ONLY the lead paragraph, not the whole hero */
.hero__inner{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;padding:0;max-width:880px}
.hero .lead{background:rgba(9,11,15,.55);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--hairline);border-radius:16px;padding:1.1rem 1.6rem;max-width:640px}
/* app marks v2 — larger, logo larger, glossy premium */
.appmarks{display:flex;gap:1.1rem;justify-content:center;align-items:center;margin-top:2.1rem}
.am{width:74px;height:74px;border-radius:19px;position:relative;overflow:hidden;display:grid;place-items:center;
  border:none;transition:transform .25s var(--ease);
  box-shadow:0 14px 34px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.20), inset 0 0 0 1px rgba(255,255,255,.06)}
.am:hover{transform:translateY(-4px)}
.am::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,.05) 40%,transparent 62%)}
.am img{width:72%;height:auto;position:relative;z-index:1}
.am--dark{background:linear-gradient(180deg,#181B21,#0B0D11)}
.am--light{background:linear-gradient(180deg,#FFFFFF,#DCE0E6)}
.am--blue{background:linear-gradient(180deg,#2B93FF,#0063DB)}
.am--bare{background:transparent;box-shadow:none}
.am--bare::after{display:none}
@media(max-width:560px){.am{width:58px;height:58px;border-radius:15px}.appmarks{gap:.8rem}}
/* ---- BIG-TECH lead: no box, no glow, quiet precision ---- */
.hero .lead{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;padding:0;
  text-shadow:none;color:var(--text-soft);font-weight:400;
  font-size:clamp(1rem,1.25vw,1.18rem);line-height:1.75;letter-spacing:.005em;max-width:56ch}
.hero .eyebrow{text-shadow:none}
/* hero: bigger mark, one-line lead */
.hero__brandmark{height:clamp(100px,12vw,172px);margin-bottom:1.7rem}
.hero .lead{font-size:clamp(1.05rem,1.5vw,1.3rem);font-weight:500;color:var(--text-soft);letter-spacing:.01em}
/* ---- CENTERPIECE: giant mark, icons orbiting around it ---- */
.hero__orbit{position:relative;width:min(440px,80vw);height:min(440px,80vw);margin:0 auto .6rem;
  display:grid;place-items:center}
.hero__orbit::before{content:"";position:absolute;inset:7%;border:1px solid rgba(255,255,255,.09);border-radius:50%}
.hero__orbit .hero__brandmark{height:clamp(130px,17vw,200px);margin:0;
  filter:drop-shadow(0 0 34px rgba(0,119,255,.45))}
.hero__orbit .appmarks{position:absolute;inset:0;margin:0;display:block}
.hero__orbit .am{position:absolute;transform:translate(-50%,-50%)}
.hero__orbit .am:hover{transform:translate(-50%,-50%) translateY(-4px)}
.hero__orbit .am:nth-child(1){left:50%;top:7%}
.hero__orbit .am:nth-child(2){left:90%;top:37%}
.hero__orbit .am:nth-child(3){left:74.5%;top:84%}
.hero__orbit .am:nth-child(4){left:25.5%;top:84%}
.hero__orbit .am:nth-child(5){left:10%;top:37%}
@media(max-width:560px){.hero__orbit{width:86vw;height:86vw}}
/* hero moving numbers */
.hero__stats{display:flex;gap:clamp(1.6rem,4vw,3.2rem);justify-content:center;margin-top:2rem;flex-wrap:wrap}
.hero__stats span{display:grid;justify-items:center;gap:.15rem;color:var(--text-mut);
  font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;font-weight:600}
.hero__stats b{font-family:var(--font-display);font-weight:700;font-size:clamp(1.5rem,2.6vw,2.2rem);
  background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
/* big tile in reveal card */
.am--big{width:128px;height:128px;border-radius:30px;margin-bottom:.4rem}
.am--big:hover{transform:none}
/* orbit tuning: mark clears the ring icons; glass 5th tile */
.hero__orbit{width:min(500px,84vw);height:min(500px,84vw)}
.hero__orbit .hero__brandmark{height:clamp(110px,13vw,158px)}
.am--glass{background:rgba(255,255,255,.07);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:0 14px 34px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.16), inset 0 0 0 1px rgba(255,255,255,.10)}
/* ============================================================
   OPENING v9 — C·Monolith hero / B·Ledger / Apple shelf / Lenis
   ============================================================ */
/* Monolith hero */
.hero__brandmark--mono{height:clamp(200px,26vw,340px);margin:1.4rem 0 2rem;
  filter:drop-shadow(0 0 70px rgba(0,119,255,.42))}
.hero__mono-title{font-size:clamp(2.1rem,4.2vw,3.5rem);font-weight:700;letter-spacing:.01em}
.hero__pillars{color:var(--text-mut);letter-spacing:.3em;font-size:.78rem;font-weight:700;
  text-transform:uppercase;margin:1.3rem 0 2.3rem}
.hero__enter{padding:1.1rem 3.6rem}
.hero__dock{margin-top:3rem;gap:.85rem}
.hero__dock .am{width:48px;height:48px;border-radius:12px}
/* Ledger */
.ledger{position:relative;padding:clamp(70px,9vw,120px) 0;border-top:1px solid var(--hairline);
  background:linear-gradient(180deg,#08090C,#0A0A0A)}
.ledger__grid{display:grid;grid-template-columns:1.05fr .95fr;gap:4vw;align-items:center}
.ledger .hero__orbit{margin:0;width:min(440px,90%);height:min(440px,42vw)}
.ledger .hero__orbit .hero__brandmark{height:clamp(110px,11vw,150px);margin:0;
  filter:drop-shadow(0 0 40px rgba(0,119,255,.45))}
.hero__stats--left{justify-content:flex-start;margin-top:2.4rem}
@media(max-width:900px){.ledger__grid{grid-template-columns:1fr}
  .ledger .hero__orbit{margin:2.2rem auto 0;height:min(440px,86vw)}}
/* Apple shelf */
.showcase{padding:clamp(56px,7vw,100px) 0;overflow:hidden}
.show-wrap{position:relative}
.show-track{display:flex;gap:22px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding:8px calc(50vw - min(48vw,560px)) 18px;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  scroll-behavior:smooth}
.show-track::-webkit-scrollbar{display:none}
.show-card{position:relative;flex:0 0 min(96vw,1120px);height:min(72vh,660px);border-radius:22px;
  overflow:hidden;background-size:cover;background-position:center;scroll-snap-align:center;
  border:1px solid var(--hairline);display:block;transition:transform .35s var(--ease)}
.show-card:hover{transform:translateY(-4px)}
.show-card::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(4,5,8,.20),transparent 34%,rgba(4,5,8,.74))}
.show-lockup{position:absolute;top:22px;left:26px;z-index:2;display:flex;align-items:center;gap:.6rem;
  font-family:var(--font-display);font-weight:700;letter-spacing:.05em;font-size:1.05rem;color:#fff}
.show-lockup img{height:20px;width:auto}
.show-copy{position:absolute;left:26px;right:26px;bottom:24px;z-index:2;display:flex;align-items:center;gap:1.1rem;flex-wrap:wrap}
.show-copy i{font-style:normal;color:#EDF1F6;font-weight:500;font-size:1rem}
.show-pill{background:#fff;color:#0A0A0A;border-radius:999px;padding:.62rem 1.3rem;font-weight:700;font-size:.9rem;
  transition:background .25s,color .25s}
.show-card:hover .show-pill{background:var(--brand);color:#fff}
.show-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:5;width:46px;height:46px;border-radius:50%;
  border:1px solid var(--hairline);background:rgba(12,14,19,.72);backdrop-filter:blur(8px);color:#fff;
  font-size:1.6rem;line-height:1;cursor:pointer;display:grid;place-items:center;transition:background .25s}
.show-prev{left:18px}.show-next{right:18px}
.show-nav:hover{background:rgba(0,119,255,.85)}
@media(max-width:640px){.show-nav{display:none}}
/* Woven by Light — silk knot of brand light + marketing copy */
.woven{position:relative;min-height:92vh;overflow:hidden;background:#050608;border-block:1px solid var(--hairline);
  display:grid;place-items:center;padding:clamp(60px,8vw,100px) 24px}
#wovenCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.woven__copy{position:relative;z-index:2;text-align:center;max-width:760px}
.woven__copy::before{content:"";position:absolute;inset:-18%;z-index:-1;
  background:radial-gradient(60% 60% at 50% 50%, rgba(5,6,8,.78), transparent 75%)}
.woven__copy h2{font-size:clamp(2.2rem,4.6vw,3.6rem);margin:.6rem 0 1rem}
.woven__copy .lead{color:var(--text-soft)}
.woven__copy .lead b{color:#fff}
.woven__chips{display:flex;gap:.6rem;justify-content:center;flex-wrap:wrap;margin-top:2rem}
.woven__chips a{font-size:.72rem;letter-spacing:.16em;font-weight:700;color:var(--text-soft);
  border:1px solid var(--hairline);border-radius:999px;padding:.5rem 1rem;transition:all .25s var(--ease)}
.woven__chips a:hover{color:#fff;border-color:var(--brand);background:rgba(0,119,255,.12);transform:translateY(-2px)}
/* ============================================================
   FOOTER v2 — premium brand, roomy buttons, site-wide CTA band
   ============================================================ */
.footer-cta{border-bottom:1px solid var(--hairline);padding:clamp(2rem,4vw,3.2rem) 0;
  background:radial-gradient(80% 140% at 50% 0%, rgba(0,119,255,.10), transparent 70%)}
.footer-cta__in{display:flex;align-items:center;justify-content:space-between;gap:1.6rem;flex-wrap:wrap}
.footer-cta h3{font-family:var(--font-display);font-weight:800;font-size:clamp(1.5rem,2.8vw,2.2rem);letter-spacing:-.02em}
.footer-cta p{color:var(--text-mut);margin-top:.35rem}
.footer-cta__btns{display:flex;gap:.9rem;flex-wrap:wrap}
/* monumental brand */
.site-footer .brand{align-items:flex-start}
.site-footer .brand__icon{width:auto!important;height:52px!important;filter:drop-shadow(0 0 22px rgba(0,119,255,.35))!important}
.site-footer .brand__name{font-size:1.6rem;letter-spacing:.2em}
.site-footer .brand__sub{font-size:.6rem;letter-spacing:.32em;margin-top:6px}
/* white button: room to breathe, never clipped */
.btn--white{padding:1.05rem 2.1rem;border-radius:11px;font-weight:700;line-height:1.2}
.site-footer .btn{white-space:nowrap;overflow:visible}
.site-footer .footer-grid{padding-top:clamp(2.2rem,4vw,3.4rem)}
/* Dreams — neon tubes around the mark */
.neon{position:relative;min-height:96vh;overflow:hidden;background:#030407;border-block:1px solid var(--hairline);
  display:grid;place-items:center;padding:clamp(60px,8vw,100px) 24px;cursor:crosshair}
#neonCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.neon__copy{position:relative;z-index:2;text-align:center;pointer-events:none;max-width:820px}
.neon__copy::before{content:"";position:absolute;inset:-16%;z-index:-1;
  background:radial-gradient(55% 55% at 50% 46%, rgba(3,4,7,.72), transparent 76%)}
.neon__mark{height:clamp(120px,15vw,190px);width:auto;margin:0 auto 1.6rem;display:block;
  filter:drop-shadow(0 0 44px rgba(0,119,255,.55))}
.neon__copy h2{font-size:clamp(2.4rem,5.4vw,4.4rem);font-weight:900;letter-spacing:-.03em;line-height:1.02}
.neon__copy .lead{margin-top:1rem;color:var(--text-soft)}
.neon__copy .btn{pointer-events:auto}
.neon__hint{display:block;margin-top:2.6rem;font-size:.68rem;letter-spacing:.26em;text-transform:uppercase;color:var(--text-mut)}
/* orbit breathing room — icons pushed clear of the mark */
.hero__orbit{width:min(560px,92vw);height:min(560px,88vw)}
.ledger .hero__orbit{width:min(540px,96%);height:min(540px,50vw)}
.hero__orbit::before{inset:4%}
.hero__orbit .am:nth-child(1){left:50%;top:2%}
.hero__orbit .am:nth-child(2){left:97%;top:35%}
.hero__orbit .am:nth-child(3){left:79%;top:93%}
.hero__orbit .am:nth-child(4){left:21%;top:93%}
.hero__orbit .am:nth-child(5){left:3%;top:35%}
/* hover product tip */
.ptip{position:fixed;z-index:98;pointer-events:none;background:rgba(12,14,19,.95);border:1px solid var(--hairline);
  border-radius:14px;padding:.8rem 1.1rem;max-width:240px;box-shadow:0 18px 44px rgba(0,0,0,.6);
  opacity:0;transform:translateY(6px);transition:opacity .18s,transform .18s}
.ptip.in{opacity:1;transform:translateY(0)}
.ptip b{display:block;font-family:var(--font-display);font-size:.95rem;color:#fff;margin-bottom:.25rem}
.ptip span{font-size:.82rem;color:var(--text-soft);line-height:1.5}
/* Brain copy: no background box — bold open typography instead */
.brain__copy{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;
  padding:0;width:min(820px,calc(100% - 40px))}
.brain__copy .lead{font-weight:600;color:#E9EEF5;font-size:clamp(1.02rem,1.5vw,1.22rem);
  text-shadow:0 2px 18px rgba(0,0,0,.85), 0 1px 3px rgba(0,0,0,.9)}
/* ============================================================
   HERO LIFE v10 — bigger dock, built-in-flight icons, living mark
   ============================================================ */
/* dock: larger + spaced */
.hero__dock{margin-top:3.2rem;gap:1.6rem}
.hero__dock .am{width:64px;height:64px;border-radius:16px}
/* icons fly in from the sides, assembling as they arrive */
@keyframes buildL{0%{opacity:0;transform:translateX(-110px) scale(.4) rotate(-8deg);filter:blur(12px) brightness(2.2)}
  60%{opacity:1;filter:blur(2px) brightness(1.35)}
  100%{opacity:1;transform:translateX(0) scale(1) rotate(0);filter:blur(0) brightness(1)}}
@keyframes buildR{0%{opacity:0;transform:translateX(110px) scale(.4) rotate(8deg);filter:blur(12px) brightness(2.2)}
  60%{opacity:1;filter:blur(2px) brightness(1.35)}
  100%{opacity:1;transform:translateX(0) scale(1) rotate(0);filter:blur(0) brightness(1)}}
@keyframes buildC{0%{opacity:0;transform:translateY(70px) scale(.4);filter:blur(12px) brightness(2.2)}
  100%{opacity:1;transform:translateY(0) scale(1);filter:blur(0) brightness(1)}}
.hero__dock .am{opacity:0}
.hero__dock .am:nth-child(1){animation:buildL .9s cubic-bezier(.2,.7,.2,1) 1.15s forwards}
.hero__dock .am:nth-child(2){animation:buildL .9s cubic-bezier(.2,.7,.2,1) 1.35s forwards}
.hero__dock .am:nth-child(3){animation:buildC .9s cubic-bezier(.2,.7,.2,1) 1.55s forwards}
.hero__dock .am:nth-child(4){animation:buildR .9s cubic-bezier(.2,.7,.2,1) 1.35s forwards}
.hero__dock .am:nth-child(5){animation:buildR .9s cubic-bezier(.2,.7,.2,1) 1.15s forwards}
/* the mark breathes white light — alive */
.markwrap{position:relative;display:inline-block;line-height:0}
.hero__brandmark--mono{animation:marklife 8s ease-in-out infinite}
@keyframes marklife{
  0%,100%{filter:drop-shadow(0 0 34px rgba(255,255,255,.22)) drop-shadow(0 0 80px rgba(0,119,255,.40)) brightness(1)}
  50%{filter:drop-shadow(0 0 64px rgba(255,255,255,.55)) drop-shadow(0 0 120px rgba(0,119,255,.52)) brightness(1.14)}}
/* light sweep INSIDE the mark silhouette */
.markwrap::after{content:"";position:absolute;inset:0;pointer-events:none;mix-blend-mode:screen;
  -webkit-mask:url("../logos/dw-icon.png") center/contain no-repeat;
          mask:url("../logos/dw-icon.png") center/contain no-repeat;
  background:linear-gradient(110deg,transparent 34%,rgba(255,255,255,.95) 50%,transparent 66%);
  background-size:260% 100%;background-repeat:no-repeat;
  animation:marksheen 10s ease-in-out infinite}
@keyframes marksheen{0%,18%{background-position:160% 0}72%,100%{background-position:-140% 0}}
@media (prefers-reduced-motion:reduce){
  .hero__dock .am{opacity:1;animation:none}
  .hero__brandmark--mono,.markwrap::after{animation:none}}
/* ============================================================
   HERO LIFE v11 — real visible light (satin base -> bright wave),
   deeper glow, and a full "built as you enter" choreography.
   ============================================================ */
/* center icon now drops from the TOP */
@keyframes buildC{0%{opacity:0;transform:translateY(-100px) scale(.4);filter:blur(12px) brightness(2.2)}
  60%{opacity:1;filter:blur(2px) brightness(1.35)}
  100%{opacity:1;transform:translateY(0) scale(1);filter:blur(0) brightness(1)}}
/* the mark: satin base so light can OUTSHINE it; deep slow breath */
.hero__brandmark--mono{animation:marklife2 10s ease-in-out infinite}
@keyframes marklife2{
  0%,100%{filter:drop-shadow(0 0 42px rgba(255,255,255,.30)) drop-shadow(0 0 95px rgba(0,119,255,.45)) brightness(.68)}
  50%{filter:drop-shadow(0 0 110px rgba(255,255,255,.95)) drop-shadow(0 0 190px rgba(59,158,255,.70)) brightness(.86)}}
/* sheen core: pure white band gliding INSIDE the silhouette — now truly brighter than the mark */
.markwrap::after{mix-blend-mode:normal;
  background:linear-gradient(105deg,transparent 44%,rgba(255,255,255,1) 50%,transparent 56%);
  background-size:280% 100%;background-repeat:no-repeat;
  animation:marksheen2 12s ease-in-out infinite}
/* bloom trail: the same wave, blurred, spilling light off the edges */
.markwrap::before{content:"";position:absolute;inset:-10%;pointer-events:none;mix-blend-mode:screen;
  -webkit-mask:url("../logos/dw-icon.png") center/contain no-repeat;
          mask:url("../logos/dw-icon.png") center/contain no-repeat;
  background:linear-gradient(105deg,transparent 40%,rgba(190,225,255,1) 50%,transparent 60%);
  background-size:280% 100%;background-repeat:no-repeat;
  filter:blur(22px);animation:marksheen2 12s ease-in-out infinite}
@keyframes marksheen2{0%,14%{background-position:175% 0}64%,100%{background-position:-155% 0}}
/* the hero assembles as you enter */
.hero .eyebrow{opacity:0;animation:bldDown .8s var(--ease) .15s forwards}
.markwrap{opacity:0;animation:bldMark 1.15s cubic-bezier(.2,.7,.2,1) .35s forwards}
.hero__mono-title{opacity:0;animation:bldUp .9s var(--ease) .85s forwards}
.hero__pillars{opacity:0;animation:bldUp .9s var(--ease) 1.0s forwards}
.hero__enter{opacity:0;animation:bldUp .9s var(--ease) 1.15s forwards}
@keyframes bldDown{from{opacity:0;transform:translateY(-26px)}to{opacity:1;transform:translateY(0)}}
@keyframes bldUp{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:translateY(0)}}
@keyframes bldMark{0%{opacity:0;transform:scale(.55);filter:blur(16px) brightness(2.6)}
  100%{opacity:1;transform:scale(1);filter:blur(0) brightness(1)}}
@media (prefers-reduced-motion:reduce){
  .hero .eyebrow,.markwrap,.hero__mono-title,.hero__pillars,.hero__enter{opacity:1;animation:none}
  .markwrap::before,.markwrap::after{animation:none;background:none}
  .hero__brandmark--mono{animation:none}}
/* ============================================================
   SHEEN v12 — bulletproof: second logo layer + GRADIENT mask
   (no URL masks — they can silently fail and hide everything)
   ============================================================ */
.markwrap::before,.markwrap::after{display:none!important}
.marksheen{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;
  filter:brightness(1.5) drop-shadow(0 0 26px rgba(255,255,255,.9)) drop-shadow(0 0 60px rgba(160,210,255,.7));
  -webkit-mask-image:linear-gradient(105deg,transparent 40%,#000 50%,transparent 60%);
          mask-image:linear-gradient(105deg,transparent 40%,#000 50%,transparent 60%);
  -webkit-mask-size:280% 100%;mask-size:280% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  animation:sheenmask 12s ease-in-out infinite}
@keyframes sheenmask{
  0%,14%{-webkit-mask-position:175% 0;mask-position:175% 0}
  64%,100%{-webkit-mask-position:-155% 0;mask-position:-155% 0}}
@media (prefers-reduced-motion:reduce){.marksheen{display:none}}
/* ============================================================
   MARK GLOW v13 (final) — full white logo; glow arrives,
   brightens it, and STAYS. No sweeps, no dimming.
   ============================================================ */
.marksheen{display:none!important}
.hero__brandmark--mono{
  animation:markGlowIn 3.4s ease-out .6s both;
}
@keyframes markGlowIn{
  0%{filter:drop-shadow(0 0 26px rgba(255,255,255,.38)) drop-shadow(0 0 60px rgba(0,119,255,.35)) brightness(1)}
  55%{filter:drop-shadow(0 0 80px rgba(255,255,255,.85)) drop-shadow(0 0 150px rgba(0,119,255,.6)) brightness(1.22)}
  100%{filter:drop-shadow(0 0 40px rgba(255,255,255,.55)) drop-shadow(0 0 100px rgba(0,119,255,.5)) brightness(1.08)}
}
@media (prefers-reduced-motion:reduce){
  .hero__brandmark--mono{animation:none;
    filter:drop-shadow(0 0 40px rgba(255,255,255,.55)) drop-shadow(0 0 100px rgba(0,119,255,.5)) brightness(1.08)}
}
/* ============================================================
   LEDGER v2 — built on scroll + orbiting icon carousel
   ============================================================ */
/* copy assembles line by line as you arrive */
.ledger .ledger__copy>*{opacity:0;transform:translateY(30px);
  transition:opacity .7s var(--ease),transform .7s var(--ease)}
.ledger .ledger__copy>*:nth-child(1){transition-delay:.05s}
.ledger .ledger__copy>*:nth-child(2){transition-delay:.15s}
.ledger .ledger__copy>*:nth-child(3){transition-delay:.25s}
.ledger .ledger__copy>*:nth-child(4){transition-delay:.35s}
.ledger .ledger__copy>*:nth-child(5){transition-delay:.45s}
.ledger.bld-in .ledger__copy>*{opacity:1;transform:none}
/* orbit scales in, then icons pop on one by one around the ring */
.ledger .hero__orbit{opacity:0;transform:scale(.85);transition:opacity .9s var(--ease) .2s,transform .9s var(--ease) .2s}
.ledger.bld-in .hero__orbit{opacity:1;transform:scale(1)}
.ledger .hero__orbit .am{opacity:0;transform:translate(-50%,-50%) scale(.25);transition:opacity .55s var(--ease),transform .55s var(--ease)}
.ledger .hero__orbit .am:nth-child(1){transition-delay:.55s}
.ledger .hero__orbit .am:nth-child(2){transition-delay:.68s}
.ledger .hero__orbit .am:nth-child(3){transition-delay:.81s}
.ledger .hero__orbit .am:nth-child(4){transition-delay:.94s}
.ledger .hero__orbit .am:nth-child(5){transition-delay:1.07s}
.ledger.bld-in .hero__orbit .am{opacity:1;transform:translate(-50%,-50%) scale(1)}
/* the carousel: icons revolve around the mark, staying upright */
.ledger.bld-in .appmarks{animation:orbitspin 46s linear infinite;animation-delay:1.9s}
.ledger.bld-in .appmarks .am{animation:orbitcounter 46s linear infinite;animation-delay:1.9s}
@keyframes orbitspin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes orbitcounter{from{transform:translate(-50%,-50%) rotate(0deg)}to{transform:translate(-50%,-50%) rotate(-360deg)}}
/* hover anywhere on the orbit pauses the carousel (read the cards) */
.ledger .hero__orbit:hover .appmarks,
.ledger .hero__orbit:hover .appmarks .am{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){
  .ledger .ledger__copy>*,.ledger .hero__orbit,.ledger .hero__orbit .am{opacity:1;transform:none;transition:none}
  .ledger .hero__orbit .am{transform:translate(-50%,-50%)}
  .ledger.bld-in .appmarks,.ledger.bld-in .appmarks .am{animation:none}}
/* ============================================================
   SCROLL-BUILD v2 — every section assembles; ledger from LEFT;
   dead space tightened.
   ============================================================ */
.bfx{opacity:0;transform:translateY(46px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
.bfx-fade{opacity:0;transition:opacity .95s var(--ease)}
.bfx-in{opacity:1!important}
.bfx.bfx-in{transform:none}/* fade-only elements keep their own layout transforms (e.g. centered overlays) */
/* ledger copy: builds from the LEFT now */
.ledger .ledger__copy>*{transform:translateX(-72px)}
/* (section sizing left exactly as originally designed — the "dead space"
   was invisible injected content, fixed by the rescue observer in scrollbuild.js) */
@media (prefers-reduced-motion:reduce){.bfx,.bfx-fade,.ledger .ledger__copy>*{opacity:1;transform:none;transition:none}}
/* ============================================================
   SHOWCASE v2 — Apple two-tier shelf: large flagships on top,
   full product line as small tiles beneath.
   ============================================================ */
.show-wrap--sm{margin-top:22px}
.show-card--sm{flex:0 0 min(86vw,520px);height:min(40vh,320px);border-radius:20px}
.show-card--sm .show-lockup{top:18px;left:20px;font-size:.92rem}
.show-card--sm .show-lockup img{height:17px}
.show-card--sm .show-copy{left:20px;right:20px;bottom:18px;gap:.8rem}
.show-card--sm .show-copy i{font-size:.9rem}
.show-card--sm .show-pill{padding:.5rem 1.05rem;font-size:.82rem}
/* premium gradient plates (brand only: navy depths, black gloss, electric, ice) */
.sc-navy{background:radial-gradient(120% 140% at 18% 0%,#0E2C55 0%,#081A33 46%,#050B14 100%)}
.sc-black{background:radial-gradient(130% 150% at 80% -10%,#1C2430 0%,#0D1117 48%,#050607 100%)}
.sc-blue{background:radial-gradient(130% 150% at 22% -8%,#3D9BFF 0%,#0077FF 46%,#013A7C 100%)}
.sc-steel{background:radial-gradient(130% 150% at 75% 0%,#2A3442 0%,#141A22 52%,#07090C 100%)}
.sc-light{background:radial-gradient(130% 150% at 25% -10%,#FFFFFF 0%,#EAF0F7 55%,#C9D6E6 100%)}
/* the big watermark mark, apple-tile style */
.show-mark{position:absolute;right:-6%;bottom:-14%;width:58%;opacity:.1;z-index:1;pointer-events:none;
  filter:drop-shadow(0 8px 30px rgba(0,0,0,.35));transition:opacity .5s var(--ease),transform .5s var(--ease)}
.show-card--sm:hover .show-mark{opacity:.17;transform:scale(1.04)}
.sc-light .show-mark{opacity:.08}
.show-card--sm::after{background:linear-gradient(180deg,rgba(0,0,0,0) 55%,rgba(0,0,0,.34) 100%)}
.sc-light::after{background:none}
.show-lockup--dark{color:#0A0F16}
.i-dark{color:#22303F!important}
.show-pill--dark{background:#0A0F16;color:#fff}
.show-card--sm:hover .show-pill--dark{background:#fff;color:#0A0F16}
@media(max-width:640px){.show-card--sm{flex-basis:84vw;height:230px}}
/* ============================================================
   QUAD v1 — apple.com-style 2x2 promo grid. Centered type on
   top, product visual below; alternating dark/ice plates.
   ============================================================ */
.quad{padding:12px}
.quad__grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;max-width:1560px;margin:0 auto}
.quad__tile{position:relative;display:block;min-height:clamp(420px,56vh,620px);border-radius:18px;
  overflow:hidden;text-align:center;border:1px solid var(--hairline);
  transition:transform .4s var(--ease)}
.quad__tile:hover{transform:scale(1.008)}
.quad__copy{position:relative;z-index:2;padding:clamp(34px,4.5vw,58px) 24px 0}
.quad__tile h3{font-family:var(--font-display);font-weight:700;letter-spacing:-.02em;
  font-size:clamp(1.9rem,3.2vw,2.9rem);margin:0 0 .35rem;color:#F4F7FB}
.quad__tile p{margin:0 0 1.1rem;color:#C7D0DB;font-size:clamp(.98rem,1.3vw,1.15rem);font-weight:500}
.quad__btns{display:flex;gap:.7rem;justify-content:center}
.qbtn{font-style:normal;font-weight:600;font-size:.92rem;border-radius:999px;padding:.6rem 1.35rem;
  transition:all .25s var(--ease)}
.qbtn--fill{background:var(--brand);color:#fff}
.qbtn--line{border:1px solid var(--brand);color:var(--brand)}
.quad__tile:hover .qbtn--fill{background:#2B8DFF}
.quad__tile:hover .qbtn--line{background:var(--brand);color:#fff}
/* dark photo plates — image anchored low, fading up into black */
.quad__tile--photo{background:#020304}
.quad__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 72%;
  opacity:.92;-webkit-mask-image:linear-gradient(180deg,transparent 4%,#000 40%);
  mask-image:linear-gradient(180deg,transparent 4%,#000 40%)}
.quad__tile--photo::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(2,3,4,.88) 0%,rgba(2,3,4,.25) 42%,rgba(2,3,4,0) 70%)}
.quad__tile--photo .quad__copy{z-index:3}
/* ice plates — dark type, glossy product icon as the hero visual */
.quad__tile--light{background:linear-gradient(180deg,#FAFCFF 0%,#EDF2F8 58%,#DCE5F0 100%)}
.quad__tile--light h3{color:#0B0F14}
.quad__tile--light p{color:#3D4956}
.quad__icon{position:absolute;left:50%;bottom:clamp(48px,9vh,96px);transform:translateX(-50%);
  width:clamp(120px,14vw,168px);height:clamp(120px,14vw,168px);border-radius:26%;
  display:grid;place-items:center;box-shadow:0 24px 60px rgba(6,20,40,.35),0 6px 18px rgba(6,20,40,.22)}
.quad__icon img{width:66%;height:auto}
.quad__tile--light:hover .quad__icon{transform:translateX(-50%) translateY(-6px);transition:transform .4s var(--ease)}
@media(max-width:860px){.quad__grid{grid-template-columns:1fr}.quad__tile{min-height:440px}}
/* ============================================================
   PROOF DECK v1 — analytics-as-proof inside Woven. Glass
   dashboard: live sparkline + KPIs + bars + one clear CTA.
   ============================================================ */
.woven__chips a{display:inline-flex;align-items:center;gap:.55rem}
.chip-ic{display:grid;place-items:center;width:24px;height:24px;border-radius:7px;flex:0 0 24px}
.chip-ic img{width:16px;height:auto}
.chip-ic--dark{background:linear-gradient(145deg,#20262E,#0B0E12);border:1px solid rgba(255,255,255,.08)}
.chip-ic--blue{background:linear-gradient(145deg,#2B8DFF,#0058C4)}
.chip-ic--light{background:linear-gradient(145deg,#FFFFFF,#D8E1EC)}
/* ---- .chip-row / .chip -------------------------------------
   The eight service toggles in the tools.html Instant Proposal builder.
   These classes were referenced by the builder's JS and defined NOWHERE:
   `<button class="chip">` was rendering as a raw browser default control —
   white fill, black text, native bevel — eight of them stacked on a black
   page, and `.chip.active` styled nothing at all, so a visitor could not see
   which services they had selected. The one interactive tool on the site that
   quotes a number was unusable and looked broken on every viewport, not just
   on a phone.

   flex-wrap, not a horizontal scroller: eight labels of this length would need
   a sideways drag on a 393px screen to reach "Conversion Optimization", and a
   selection control you have to scroll to is a selection control people
   under-use. Wrapping costs a few rows of height on a page that is already
   15,000px long. .chip-row is therefore removed from the generic overflow-x
   list in mobile.css — it is not a scroller.
   ------------------------------------------------------------ */
.chip-row{display:flex;flex-wrap:wrap;gap:10px}
.chip{
  appearance:none;-webkit-appearance:none;
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.6rem .95rem;min-height:44px;
  font:600 .9rem/1.2 var(--font-sans, system-ui, sans-serif);
  letter-spacing:.01em;text-align:left;
  color:var(--text-soft);
  background:rgba(255,255,255,.035);
  border:1px solid var(--line);border-radius:999px;
  cursor:pointer;transition:background .22s var(--ease),border-color .22s var(--ease),color .22s var(--ease),transform .22s var(--ease);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
/* The marker is drawn in CSS rather than in the JS string so the selected
   state cannot drift out of sync with the class that produces it. */
.chip::before{
  content:"";flex:none;width:16px;height:16px;border-radius:5px;
  border:1px solid var(--line);background:rgba(255,255,255,.04);
  transition:background .22s var(--ease),border-color .22s var(--ease);
}
.chip:hover{border-color:rgba(59,158,255,.45);color:#eaf6ff}
.chip:focus-visible{outline:2px solid var(--aqua-bright);outline-offset:2px}
.chip.active{
  color:#eaf6ff;
  background:rgba(59,158,255,.13);
  border-color:rgba(59,158,255,.55);
}
.chip.active::before{
  background:var(--aqua-bright);border-color:var(--aqua-bright);
  /* Tick drawn as a mask so it inherits the fill and needs no extra element. */
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/72% no-repeat, linear-gradient(#000,#000);
  -webkit-mask-composite:xor;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/72% no-repeat, linear-gradient(#000,#000);
  mask-composite:exclude;
}
.chip:active{transform:scale(.97)}
.proof{position:relative;z-index:3;margin:2.6rem auto 0;max-width:980px;display:grid;
  grid-template-columns:1.35fr .85fr;gap:18px;text-align:left;
  background:rgba(7,10,15,.62);backdrop-filter:blur(18px) saturate(120%);
  -webkit-backdrop-filter:blur(18px) saturate(120%);
  border:1px solid var(--hairline);border-radius:22px;padding:20px}
.proof__chart{display:flex;flex-direction:column;min-height:250px;border-radius:14px;
  background:rgba(255,255,255,.025);border:1px solid rgba(255,255,255,.05);padding:14px 16px}
.proof__chart-head{display:flex;align-items:center;gap:.8rem;margin-bottom:.5rem}
.proof__chart-head b{font-family:var(--font-display);font-size:.95rem;color:#EDF2F8;font-weight:600}
.proof__live{display:inline-flex;align-items:center;gap:.4rem;font-size:.68rem;font-weight:700;
  letter-spacing:.14em;color:#7FD0FF}
.proof__live i{width:7px;height:7px;border-radius:50%;background:#00E58A;
  box-shadow:0 0 10px rgba(0,229,138,.9);animation:livepulse 1.6s ease-in-out infinite}
@keyframes livepulse{0%,100%{opacity:1}50%{opacity:.35}}
.proof__delta{margin-left:auto;font-size:.82rem;font-weight:700;color:#00E58A}
#proofChart{flex:1;width:100%;min-height:170px}
.proof__side{display:flex;flex-direction:column;gap:14px}
.proof__kpis{display:grid;gap:10px}
.proof__kpis>div{display:flex;align-items:baseline;gap:.7rem;background:rgba(255,255,255,.025);
  border:1px solid rgba(255,255,255,.05);border-radius:12px;padding:.65rem .9rem}
.proof__kpis b{font-family:var(--font-display);font-size:clamp(1.15rem,1.7vw,1.45rem);color:var(--brand-2,#2B8DFF);font-weight:700;white-space:nowrap}
.proof__kpis span{font-size:.8rem;color:var(--text-soft)}
.proof__bars{flex:1;display:flex;align-items:flex-end;gap:6px;min-height:64px;padding:0 2px}
.proof__bars i{flex:1;height:var(--h);min-height:6px;border-radius:4px 4px 2px 2px;
  background:linear-gradient(180deg,#2B8DFF,#0058C4);opacity:.85;transform:scaleY(0);transform-origin:bottom;
  transition:transform .7s var(--ease)}
.proof__bars i:nth-child(odd){background:linear-gradient(180deg,#3D9BFF,#0077FF)}
.bfx-in .proof__bars i, .proof--in .proof__bars i{transform:scaleY(1)}
.proof__bars i:nth-child(2){transition-delay:.06s}.proof__bars i:nth-child(3){transition-delay:.12s}
.proof__bars i:nth-child(4){transition-delay:.18s}.proof__bars i:nth-child(5){transition-delay:.24s}
.proof__bars i:nth-child(6){transition-delay:.3s}.proof__bars i:nth-child(7){transition-delay:.36s}
.proof__bars i:nth-child(8){transition-delay:.42s}.proof__bars i:nth-child(9){transition-delay:.48s}
.proof__bars i:nth-child(10){transition-delay:.54s}
@media(max-width:820px){.proof{grid-template-columns:1fr}.proof__chart{min-height:210px}}
/* ============================================================
   DASHSHOT v1 — the portal dashboard as a framed product shot.
   ============================================================ */
.dashshot{display:block;border-radius:14px;overflow:hidden;border:1px solid rgba(255,255,255,.1);
  background:#0A0E14;box-shadow:0 30px 80px rgba(0,30,80,.5),0 0 0 1px rgba(0,119,255,.12),
  0 0 90px rgba(0,119,255,.14);transition:transform .45s var(--ease),box-shadow .45s var(--ease)}
.dashshot:hover{transform:translateY(-6px);
  box-shadow:0 40px 100px rgba(0,30,80,.6),0 0 0 1px rgba(0,119,255,.3),0 0 120px rgba(0,119,255,.22)}
.dashshot__bar{display:flex;align-items:center;gap:6px;padding:9px 12px;
  background:#0D1117;border-bottom:1px solid rgba(255,255,255,.06)}
.dashshot__bar i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.14)}
.dashshot__bar i:first-child{background:#FF5F57}.dashshot__bar i:nth-child(2){background:#FEBC2E}.dashshot__bar i:nth-child(3){background:#28C840}
.dashshot__bar b{margin:0 auto;font-size:.72rem;font-weight:600;color:#8B99A8;letter-spacing:.04em;
  background:rgba(255,255,255,.05);border-radius:6px;padding:.22rem 1rem}
.dashshot img{display:block;width:100%;height:auto}
/* PROOF DECK relocated: full-width fifth tile inside the quad grid */
.quad__grid .proof{grid-column:1/-1;margin:0;max-width:none;text-align:left;
  background:#0D1219;backdrop-filter:none;-webkit-backdrop-filter:none;
  border:1px solid rgba(255,255,255,.06);border-radius:18px}
/* ============================================================
   PHOTO SYSTEM v1 — real Dark Water imagery across the shelf,
   quad and the closing CTA. Text always sits on a scrim.
   ============================================================ */
.sc-photo{background-color:#050709;background-size:cover;background-position:center}
.sc-photo::after{background:linear-gradient(180deg,rgba(2,3,4,.42) 0%,rgba(2,3,4,0) 34%,rgba(2,3,4,0) 52%,rgba(2,3,4,.58) 100%)}
.sc-photo:hover{transform:translateY(-4px)}
/* closing CTA — storm ocean film behind the pitch */
.cta-band--video{position:relative;overflow:hidden}
.cta-band__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.cta-band__veil{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(4,6,10,.72) 0%,rgba(4,6,10,.5) 45%,rgba(4,6,10,.78) 100%)}
.cta-band--video>h2,.cta-band--video>p,.cta-band--video>.btn-row{position:relative;z-index:2}
.cta-band--video h2{text-shadow:0 2px 24px rgba(0,0,0,.8)}
.cta-band--video .lead{color:#DCE4EE;text-shadow:0 1px 14px rgba(0,0,0,.85)}
@media (prefers-reduced-motion:reduce){.cta-band__video{display:none}
  .cta-band--video{background:url('../video/cta-poster.jpg') center/cover}}
/* ============================================================
   WFEAT v1 — featured case study (real ship screenshots).
   ============================================================ */
.wfeat{display:grid;grid-template-columns:1.62fr 1fr;gap:14px;margin-bottom:14px}
.wfeat__main{position:relative;display:block;border-radius:18px;overflow:hidden;
  border:1px solid var(--hairline);transition:transform .4s var(--ease),box-shadow .4s var(--ease)}
.wfeat__main:hover{transform:translateY(-5px);box-shadow:0 30px 70px rgba(0,20,50,.45)}
.wfeat__main img{display:block;width:100%;height:100%;object-fit:cover}
.wfeat__main::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(3,4,6,0) 38%,rgba(3,4,6,.86) 100%)}
.wfeat__copy{position:absolute;left:26px;right:26px;bottom:22px;z-index:2}
.wfeat__tag{font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:#7FD0FF;font-weight:700}
.wfeat__copy h3{font-family:var(--font-display);font-size:clamp(1.5rem,2.4vw,2.1rem);margin:.35rem 0 .4rem;color:#fff}
.wfeat__copy p{color:#C9D2DD;max-width:52ch;font-size:.95rem;margin:0 0 .95rem}
.wfeat__side{display:grid;grid-template-rows:1fr 1fr;gap:14px}
.wfeat__side a{display:block;border-radius:16px;overflow:hidden;border:1px solid var(--hairline);
  transition:transform .35s var(--ease)}
.wfeat__side a:hover{transform:translateY(-4px)}
.wfeat__side img{display:block;width:100%;height:100%;object-fit:cover}
@media(max-width:860px){.wfeat{grid-template-columns:1fr}
  .wfeat__side{grid-template-rows:none;grid-template-columns:1fr 1fr}}
/* ============================================================
   POLISH v1 — film endings, wordless scroll cue, back-to-top.
   ============================================================ */
video[data-once]{transition:opacity 1.6s var(--ease)}
video[data-once].vdone{opacity:0}
/* back to top — bottom-left (chat fab owns bottom-right) */
.totop{position:fixed;left:22px;bottom:22px;z-index:60;width:46px;height:46px;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;
  background:rgba(10,14,20,.7);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--hairline);color:#DCE6F2;
  opacity:0;transform:translateY(14px);pointer-events:none;
  transition:opacity .35s var(--ease),transform .35s var(--ease),background .25s,border-color .25s}
.totop svg{width:18px;height:18px}
.totop--in{opacity:1;transform:none;pointer-events:auto}
.totop:hover{background:var(--brand);border-color:var(--brand);color:#fff}
@media(max-width:640px){.totop{left:14px;bottom:14px;width:42px;height:42px}}
/* real-client work tiles */
.work-tile--photo{background-size:cover;background-position:center top}
.work-tile--photo::before{background:linear-gradient(180deg,rgba(4,6,9,.06) 26%,rgba(4,6,9,.9) 100%)}
.work-tile--cta{background:radial-gradient(130% 150% at 22% -8%,#1B72D9 0%,#0058C4 46%,#032B5C 100%)}
.work-tile--cta::before{background:none}
.work-tile--cta .tag{color:#CFE6FF}
.work-tile--cta:hover{box-shadow:0 24px 60px rgba(0,80,190,.45)}
/* ============================================================
   BREATHING v1 — a touch more air between major sections so
   one screen never stacks multiple sections. Subtle by design.
   ============================================================ */
main > section + section{margin-top:clamp(28px,4.5vh,64px)}
main > section.hero + section{margin-top:0}/* ledger stays tight under the hero */
/* ============================================================
   ROBOT CREST — DW mark riding on the robot's chest plate.
   Percent-anchored to the scene so it tracks across sizes;
   soft glow + idle bob to blend with the scene's motion.
   ============================================================ */
.scene-3d{position:relative}
/* v2 (07-27): the mark was reading as a sticker — too small and sitting low
   on the belly rather than centered on the chest plate. Chest plate spans
   roughly 44%–74% of the scene height, so its centre is ~54%, not 57%.

   v3 (07-28): it STILL read as a sticker, and position was not the reason.
   Four things were making it float in front of the robot instead of sitting on
   it, and all four are fixed here.

   1. IT APPEARED BEFORE THE ROBOT DID. The mark was painted at parse time and
      hovered over the "Loading interactive scene..." message with nothing behind
      it. Nothing else reads as cheap so fast as a logo glowing in an empty box.
      It now starts at opacity 0 and the scene's load event adds .is-on.

   2. IT BOBBED ON ITS OWN. An 8px vertical drift that the robot does not share
      is a direct statement that the two are separate layers — the eye reads
      relative motion before it reads anything else. The bob is gone. What
      replaces it is a slow change in BRIGHTNESS, which is what a powered
      emblem set into a chest plate would actually do, and which cannot
      detach because nothing moves.

   3. IT WAS OPAQUE INK. A solid white shape over the body hides the body.
      mix-blend-mode:screen makes the mark emit light instead of covering
      material: the carbon weave and the shading of the chest read straight
      through it, so it belongs to the surface it is lying on. This is the
      single biggest change of the four.

   4. IT HAD A FLOATING HALO. Three stacked drop-shadows, one of them a 22px
      blue bloom, put a soft aura in the air in FRONT of the robot. Light from
      an emblem set into a plate spills a short way across that plate and stops.
      One tight 9px spill remains; the wide bloom and the black cast shadow —
      a cast shadow only makes sense for something hovering above a surface —
      are both gone.

   The perspective tilt is the finishing touch: the chest plate is angled back
   at the top and turned very slightly to the viewer's left, so the crest is
   given the same tilt rather than facing the camera square-on. */
.robot-crest{position:absolute;left:50%;top:54%;width:clamp(56px,13%,104px);height:auto;
  z-index:3;pointer-events:none;
  transform:translate(-50%,-50%) perspective(240px) rotateX(9deg) rotateY(-4deg);
  mix-blend-mode:screen;
  filter:drop-shadow(0 0 9px rgba(90,175,255,.55));
  opacity:0;transition:opacity 1.1s var(--ease) .25s}
.robot-crest.is-on{opacity:.92;animation:crestglow 5.5s ease-in-out 1.4s infinite}
/* brightness only — never position. See note 2 above. */
@keyframes crestglow{0%,100%{opacity:.82;filter:drop-shadow(0 0 7px rgba(90,175,255,.42))}
                     50%{opacity:1;filter:drop-shadow(0 0 13px rgba(120,195,255,.72))}}
@media(max-width:820px){.robot-crest{width:clamp(46px,15%,84px)}}
@media (prefers-reduced-motion:reduce){
  .robot-crest{transition:none}
  .robot-crest.is-on{animation:none;opacity:.9}
}
/* ============================================================
   DESIGN VAULT v1 — 90 living design directions, openable live.
   ============================================================ */
.vault-chips{display:flex;flex-wrap:wrap;gap:.55rem;margin-bottom:26px}
.vault-chip{background:rgba(255,255,255,.04);border:1px solid var(--hairline);color:var(--text-soft);
  border-radius:999px;padding:.5rem 1.1rem;font-size:.85rem;font-weight:600;cursor:pointer;
  transition:all .25s var(--ease)}
.vault-chip:hover{border-color:rgba(0,119,255,.5);color:#fff}
.vault-chip.on{background:var(--brand);border-color:var(--brand);color:#fff}
.vault-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
.vault-card{position:relative;display:block;border-radius:14px;overflow:hidden;
  border:1px solid var(--hairline);background:#0A0E14;transition:transform .35s var(--ease),border-color .3s,box-shadow .35s}
.vault-card:hover{transform:translateY(-5px);border-color:rgba(0,119,255,.55);box-shadow:0 20px 50px rgba(0,40,110,.35)}
.vault-card img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;background:#000}
/* The caption strip is title, category and two action pills. As one flex row
   it only works if all four fit, and in a 3-up vault grid they never do: at
   1440 the card gives the strip 250px of content, and title + category + the
   two pills come to more than that on 82 of the 90 cards. Flex resolved the
   overflow by shrinking the pills below their own text, so "Live" wrapped onto
   two lines inside a 99px-radius box — which renders as a circle, not a
   button — and "Free" spilled past the card's right edge. Titles of three
   words wrapped to three lines while the pills stayed centred on the first,
   so the strip read as debris rather than a caption.

   Two rows instead of one. Title takes the free space and the category sizes
   to its own text on the first; the pills get the full width of the second,
   where 250px is far more than the ~130px they need. min-width:0 lets the
   title wrap inside its track rather than forcing the track wider, and the
   pills stop shrinking and stop wrapping, which is what makes them lozenges
   again. This applies at every width — the phone had the same failure for the
   same reason, so it does not need a rule of its own. */
.vault-card__c{display:grid;grid-template-columns:1fr auto;align-items:baseline;
  column-gap:.6rem;row-gap:.7rem;padding:.85rem 1rem 1rem}
.vault-card__c b{min-width:0}
.vault-card__c b{font-family:var(--font-display);font-size:.98rem;color:#fff;font-weight:600}
.vault-card__c i{font-style:normal;font-size:.74rem;color:var(--text-mut);letter-spacing:.06em;text-transform:uppercase}
.vault-open{margin-left:auto;font-size:.78rem;font-weight:700;color:#4EA3FF;opacity:0;transition:opacity .25s}
.vault-card:hover .vault-open{opacity:1}
/* homepage vault band */
.vaultband{position:relative;overflow:hidden;border-radius:22px;border:1px solid var(--hairline);
  background:linear-gradient(120deg,#081120 0%,#050810 60%,#03050A 100%);padding:clamp(30px,4vw,52px)}
.vaultband__row{display:flex;gap:12px;margin-top:1.6rem;overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.vaultband__strip{display:flex;gap:12px;animation:vaultslide 46s linear infinite;flex:0 0 auto}
.vaultband:hover .vaultband__strip{animation-play-state:paused}
.vaultband__strip img{width:190px;aspect-ratio:16/10;object-fit:cover;border-radius:10px;border:1px solid rgba(255,255,255,.09)}
@keyframes vaultslide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.vaultband__strip{animation:none}}
/* vault card actions: live + free download */
.vault-acts{grid-column:1 / -1;margin-left:0;display:flex;gap:.45rem}
.va{white-space:nowrap;flex:none;
  font-size:.74rem;font-weight:700;border-radius:99px;padding:.3rem .75rem;text-decoration:none;
  transition:all .22s var(--ease)}
.va--live{color:#4EA3FF;border:1px solid rgba(0,119,255,.4)}
.va--live:hover{background:rgba(0,119,255,.15)}
.va--dl{background:var(--brand);color:#fff}
.va--dl:hover{background:#2B8DFF}
.vault-card__view{display:block}
.vault-open{display:none}
/* ============================================================
   FOOTER BUTTONS v3 — roomy, premium padding (per reference:
   generous inner space, soft 14px radius, never text-to-edge).
   ============================================================ */
.footer-cta__btns .btn{padding:1.05rem 2.5rem;border-radius:14px;font-size:1.02rem;font-weight:700;line-height:1}
.footer-cta__btns{gap:1.1rem}
.site-footer .btn--white{padding:1rem 2.3rem;border-radius:14px;font-size:1rem}
@media(max-width:640px){.footer-cta__btns .btn{padding:.95rem 1.9rem}}

/* ============ MANIFEST / PRODUCT OFFER v1 — premium, few words, sells ============ */
.mani__head{text-align:center;max-width:900px;margin:0 auto}
.mani__h{margin-top:.9rem;font-size:clamp(1.9rem,3.5vw,3.05rem);line-height:1.08;letter-spacing:-.025em}
.mani__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,22px);margin-top:clamp(30px,4vw,54px)}
.mprod{position:relative;display:flex;flex-direction:column;overflow:hidden;border-radius:22px;
  background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.018));
  border:1px solid rgba(255,255,255,.085);text-decoration:none;color:#fff;
  transition:transform .5s cubic-bezier(.2,.7,.2,1),border-color .4s,box-shadow .5s}
.mprod:hover{transform:translateY(-6px);border-color:rgba(43,141,255,.42);box-shadow:0 26px 70px rgba(0,0,0,.55),0 0 0 1px rgba(43,141,255,.12) inset}
.mprod__shot{display:block;position:relative;aspect-ratio:4/3;overflow:hidden;background:#07090c}
.mprod__shot img{width:100%;height:100%;object-fit:cover;transform:scale(1.02);transition:transform .8s cubic-bezier(.2,.7,.2,1);filter:saturate(1.02) contrast(1.03)}
.mprod:hover .mprod__shot img{transform:scale(1.075)}
.mprod__shot:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(4,6,9,0) 42%,rgba(4,6,9,.72) 100%)}
.mprod__body{display:block;padding:clamp(18px,2vw,26px) clamp(18px,2vw,28px) clamp(20px,2.2vw,28px)}
.mprod__lock{display:inline-flex;align-items:center;gap:8px;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.mprod__lock img{width:15px;height:15px;opacity:.9}
.mprod__t{display:block;margin-top:.65rem;font-size:clamp(1.15rem,1.5vw,1.5rem);font-weight:750;letter-spacing:-.02em;line-height:1.15}
.mprod__p{display:block;margin-top:.45rem;font-size:.96rem;color:rgba(255,255,255,.56);font-variant-numeric:tabular-nums}
.mprod__go{display:inline-flex;align-items:center;gap:.35rem;margin-top:1.05rem;font-size:.92rem;font-weight:650;color:#4A9BFF}
.mprod__go i{font-style:normal;transition:transform .35s}
.mprod:hover .mprod__go i{transform:translateX(4px)}
.mani__foot{display:flex;align-items:center;justify-content:center;gap:1.4rem;flex-wrap:wrap;margin-top:clamp(26px,3vw,40px)}
.mani__link{display:inline-flex;align-items:center;gap:.35rem;color:rgba(255,255,255,.72);text-decoration:none;font-weight:600;font-size:1rem}
.mani__link:hover{color:#4A9BFF}
.mani__link i{font-style:normal}
@media(max-width:980px){.mani__grid{grid-template-columns:1fr 1fr}.mani__grid .mprod:last-child{grid-column:1/-1}.mani__grid .mprod:last-child .mprod__shot{aspect-ratio:21/9}}
@media(max-width:620px){.mani__grid{grid-template-columns:1fr}.mani__grid .mprod:last-child .mprod__shot{aspect-ratio:4/3}}
/* MANIFEST v1.1 — real dashboard shot reads brighter, lighter scrim */
.mprod__shot:after{background:linear-gradient(180deg,rgba(4,6,9,0) 48%,rgba(4,6,9,.55) 100%)}
.mprod__shot img{filter:saturate(1.05) contrast(1.05) brightness(1.06)}

/* ============ MANIFEST v2 — living app icons, real tiers, more premium ============ */
.mani__grid{gap:clamp(16px,1.8vw,26px)}
.mprod{border-radius:26px;background:linear-gradient(180deg,rgba(255,255,255,.062),rgba(255,255,255,.014));
  border:1px solid rgba(255,255,255,.075);box-shadow:0 1px 0 rgba(255,255,255,.06) inset,0 18px 46px rgba(0,0,0,.34)}
.mprod:before{content:"";position:absolute;left:14%;right:14%;top:0;height:1px;z-index:3;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.42),transparent);opacity:.7}
.mprod:hover{transform:translateY(-8px);border-color:rgba(43,141,255,.34);
  box-shadow:0 34px 84px rgba(0,0,0,.6),0 0 0 1px rgba(43,141,255,.14) inset}
.mprod__shot{aspect-ratio:16/11}
.mprod__shot:after{background:linear-gradient(180deg,rgba(4,6,9,0) 40%,rgba(4,6,9,.86) 100%)}
.mprod__body{position:relative;padding:0 clamp(20px,2.1vw,30px) clamp(22px,2.3vw,30px)}

/* living app icon straddling the photo edge */
.ptile--prod{position:relative;z-index:4;width:74px;margin-top:-37px;margin-bottom:1.05rem;cursor:inherit;pointer-events:none}
.ptile--prod canvas{width:74px;height:74px;border-radius:20px;
  box-shadow:0 14px 34px rgba(0,0,0,.62),0 0 0 1px rgba(255,255,255,.10) inset}
.ptile--prod img{top:37px;width:42%}
.mprod:hover .ptile--prod{transform:translateY(-3px)}
.ptile--prod{transition:transform .5s cubic-bezier(.2,.7,.2,1)}

.mprod__tier{display:block;font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.5);font-weight:650}
.mprod__t{display:block;margin-top:.5rem;font-size:clamp(1.2rem,1.5vw,1.55rem);font-weight:760;letter-spacing:-.022em;line-height:1.14}
.mprod__row{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  margin-top:1.15rem;padding-top:.95rem;border-top:1px solid rgba(255,255,255,.085)}
.mprod__row em{font-style:normal;font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.42)}
.mprod__row b{font-size:1.28rem;font-weight:720;letter-spacing:-.02em;color:#fff;font-variant-numeric:tabular-nums}
.mprod__go{margin-top:1rem}

/* featured tier */
.mprod--feat{border-color:rgba(43,141,255,.32);
  background:linear-gradient(180deg,rgba(43,141,255,.10),rgba(255,255,255,.014) 46%)}
.mprod--feat .mprod__row b{color:#8FC3FF}
.mprod__badge{position:absolute;z-index:5;top:16px;right:16px;padding:.42rem .82rem;border-radius:999px;
  font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:#fff;
  background:rgba(10,14,20,.62);backdrop-filter:blur(10px);border:1px solid rgba(43,141,255,.5);
  box-shadow:0 6px 20px rgba(0,0,0,.45)}
.mani__note{text-align:center;margin-top:clamp(20px,2.4vw,30px);font-size:.94rem;color:rgba(255,255,255,.46)}
.mani__foot{margin-top:clamp(18px,2vw,26px)}
@media(max-width:980px){.mani__grid .mprod:last-child .mprod__shot{aspect-ratio:21/9}}
@media(max-width:620px){.mani__grid .mprod:last-child .mprod__shot{aspect-ratio:16/11}}

/* MANIFEST v2.1 — aligned price rows, inline tier badge, larger icons */
.mprod{display:flex;flex-direction:column}
.mprod__body{display:flex;flex-direction:column;flex:1 1 auto}
.mprod__t{min-height:2.3em}
.mprod__row{margin-top:auto}
.ptile--prod{width:84px;margin-top:-42px;margin-bottom:1.15rem}
.ptile--prod canvas{width:84px;height:84px;border-radius:22px}
.ptile--prod img{top:42px}
.mprod__tier{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.mprod__badge{position:static;top:auto;right:auto;padding:.3rem .62rem;font-size:.6rem;letter-spacing:.14em;
  border-radius:999px;background:rgba(43,141,255,.16);border:1px solid rgba(43,141,255,.45);color:#9CC8FF;box-shadow:none;backdrop-filter:none}
@media(max-width:620px){.mprod__t{min-height:0}}

/* ============================================================
   MANIFEST LIGHT v3 — the hero's logo-print, INVERTED.
   Paper-white field printed with blue DW marks, cursor-alive
   (light-fx.js → canvas#lightField). Section flips to light type.
   ============================================================ */
.mani--light{isolation:isolate;background:#F4F7FB;overflow:hidden}
.mani__field{position:absolute;inset:0;z-index:0;pointer-events:none}
.mani__field canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* seat the white band against the dark sections above/below */
.mani--light:before,.mani--light:after{content:"";position:absolute;left:0;right:0;height:clamp(40px,5vw,74px);z-index:1;pointer-events:none}
.mani--light:before{top:0;height:clamp(22px,2.4vw,38px);
  background:linear-gradient(180deg,rgba(6,8,12,.34),rgba(6,8,12,.06) 62%,transparent);
  box-shadow:0 1px 0 rgba(255,255,255,.30)}
.mani--light:after{bottom:0;height:clamp(22px,2.4vw,38px);
  background:linear-gradient(0deg,rgba(6,8,12,.30),rgba(6,8,12,.05) 62%,transparent)}
.mani--light .container{position:relative;z-index:2}

/* --- type on paper --- */
.mani--light .eyebrow{color:#0064D8}
.mani--light .mani__h{color:#0A1220;text-shadow:none}
.mani--light .gradient-text{background:linear-gradient(135deg,#0A80FF 0%,#0064D8 56%,#0A3F8C 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.mani--light .mani__note{color:rgba(16,26,42,.52)}
.mani--light .mani__link{color:rgba(12,22,38,.72)}
.mani--light .mani__link:hover{color:#0077FF}

/* --- cards: white paper stock, ink hairlines, soft lifted shadow --- */
.mani--light .mprod{background:linear-gradient(180deg,#FFF,#FBFDFF);
  border:1px solid rgba(12,32,64,.10);
  box-shadow:0 1px 0 rgba(255,255,255,.9) inset,0 2px 6px rgba(10,26,52,.06),0 18px 44px rgba(10,26,52,.11)}
.mani--light .mprod:before{background:linear-gradient(90deg,transparent,rgba(0,119,255,.30),transparent);opacity:.9}
.mani--light .mprod:hover{border-color:rgba(0,119,255,.34);
  box-shadow:0 1px 0 rgba(255,255,255,.9) inset,0 4px 10px rgba(10,26,52,.07),0 34px 74px rgba(10,40,88,.20),0 0 0 1px rgba(0,119,255,.10) inset}
.mani--light .mprod__shot{background:#0A0C10}
.mani--light .mprod__shot:after{background:linear-gradient(180deg,rgba(4,6,9,0) 52%,rgba(4,6,9,.42) 100%)}
.mani--light .mprod__tier{color:rgba(16,30,52,.52)}
.mani--light .mprod__t{color:#0A1220}
.mani--light .mprod__row{border-top:1px solid rgba(12,32,64,.10)}
.mani--light .mprod__row em{color:rgba(16,30,52,.45)}
.mani--light .mprod__row b{color:#0A1220}
.mani--light .mprod__go{color:#0077FF}
.mani--light .ptile--prod canvas{box-shadow:0 12px 30px rgba(10,26,52,.26),0 2px 6px rgba(10,26,52,.14),0 0 0 1px rgba(12,32,64,.10) inset}

/* featured card = faint blue wash + stronger blue frame */
.mani--light .mprod--feat{background:linear-gradient(180deg,#F1F7FF,#FDFEFF 52%);border-color:rgba(0,119,255,.28)}
.mani--light .mprod--feat .mprod__row b{color:#0064D8}
.mani--light .mprod__badge{background:rgba(0,119,255,.10);border:1px solid rgba(0,119,255,.34);color:#0064D8}

/* ============================================================
   INTERACT LAYER v1 — the lower site comes alive under the cursor
   Paired with assets/js/interact.js. Everything here is driven by
   custom properties the script writes: --mx/--my (pointer inside the
   element), --ip (0|1 presence), --rx/--ry (tilt), --bx/--by (magnet).
   ============================================================ */

/* ---- card surfaces: tilt + spotlight + gradient edge ---- */
.ix.ix{
  --lift:-6px;
  transform:perspective(1000px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg))
            translateY(calc(var(--ip,0) * var(--lift)));
  transform-style:preserve-3d;
  transition:transform .22s cubic-bezier(.2,.7,.2,1),box-shadow .4s,border-color .4s;
  will-change:transform;
}
.ix.ix.cta-band,.ix.ix.vaultband,.ix.ix.faq-item,.ix.ix.stat{--lift:0px}
.ix.ix.stat{--lift:-3px}
.ix__glow,.ix__edge{
  position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  opacity:var(--ip,0);transition:opacity .35s ease;z-index:2;
}
.ix__glow{
  mix-blend-mode:screen;
  background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),
    rgba(74,155,255,.20),rgba(0,119,255,.07) 42%,transparent 66%);
}
.ix__edge{
  padding:1px;
  background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%),
    rgba(140,200,255,.62),rgba(59,158,255,.16) 46%,transparent 70%);
  -webkit-mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
          mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
  -webkit-mask-composite:xor;mask-composite:exclude;
}
/* keep card content above the light */
.card>*:not(.ix__glow):not(.ix__edge),.step>*:not(.ix__glow):not(.ix__edge),
.quote-card>*:not(.ix__glow):not(.ix__edge),.stat>*:not(.ix__glow):not(.ix__edge){position:relative;z-index:3}

/* white paper section: the light becomes ink, not glare */
.mani--light .ix__glow{mix-blend-mode:multiply;
  background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),
    rgba(196,218,248,.55),rgba(226,236,252,.30) 44%,transparent 68%)}
.mani--light .ix__edge{background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%),
    rgba(0,119,255,.55),rgba(0,119,255,.14) 46%,transparent 70%)}

/* photo work tiles drift their image against the pointer.
   NOTE: keep background-size:cover — a percentage size sets height to auto,
   which breaks the framing (and can tile) on any image whose ratio doesn't
   happen to match. cover already leaves horizontal slack to drift inside. */
.ix.work-tile--photo{background-repeat:no-repeat;background-size:cover;
  background-position:calc(50% + var(--pxl,0px)) top;
  transition:background-position .35s ease-out,transform .22s cubic-bezier(.2,.7,.2,1)}

/* ---- magnetic buttons + links ---- */
.btn,.mani__link,.card__link,.show-pill{will-change:transform}
.ix-mag{transform:translate3d(var(--bx,0px),var(--by,0px),0)!important;
  transition:transform .16s cubic-bezier(.2,.7,.2,1)!important}
.btn.ix-mag{transition:transform .16s cubic-bezier(.2,.7,.2,1),background .3s,box-shadow .3s!important}

/* ---- the ambient wash ----
   The ONLY thing that follows the pointer now, and it is not cursor
   decoration: it is a 760px blurred light with no edge, so it reads as the
   section being lit from where you are looking rather than as a second
   cursor. The ring (#ixRing), the dot (#ixDot) and the click pulse
   (.ix-pulse) that used to live here are deliberately deleted — a drawn ring
   always lags the real cursor, and two cursors, one of them behind the
   other, is the cheapest look on the web. Do not reintroduce them; see the
   head of assets/js/interact.js. */
#ixWash{position:fixed;left:0;top:0;width:760px;height:760px;border-radius:50%;
  pointer-events:none;z-index:1;opacity:0;mix-blend-mode:screen;filter:blur(6px);
  background:radial-gradient(circle,rgba(0,119,255,.17),rgba(0,119,255,.06) 44%,transparent 68%)}

/* ---- marquees respond to attention ---- */
.marquee__row,.vaultband__strip{transition:animation-duration .4s}
.marquee:hover .marquee__row{animation-duration:78s}
.vaultband:hover .vaultband__strip{animation-duration:70s}

/* ---- respect the user ---- */
@media (hover:none),(pointer:coarse){#ixWash{display:none!important}}
@media (prefers-reduced-motion:reduce){
  #ixWash{display:none!important}
  .ix.ix{transform:none!important}
}

/* MANIFEST LIGHT v3.1 — printed type sits on a soft paper halo so the
   logo print never fights the headline; content stays first-read. */
.mani--light .mani__head{position:relative;z-index:2}
.mani--light .mani__head:before{content:"";position:absolute;z-index:-1;pointer-events:none;
  left:-10%;right:-10%;top:-46%;bottom:-30%;
  background:radial-gradient(58% 62% at 50% 50%,rgba(255,255,255,.94),rgba(255,255,255,.62) 52%,rgba(255,255,255,0) 78%)}
.mani--light .mani__note,.mani--light .mani__foot{position:relative;z-index:2}
.mani--light .mani__note:before{content:"";position:absolute;z-index:-1;pointer-events:none;
  left:50%;transform:translateX(-50%);width:min(760px,96%);top:-70%;bottom:-70%;
  background:radial-gradient(52% 60% at 50% 50%,rgba(255,255,255,.92),rgba(255,255,255,0) 76%)}

/* ============================================================
   WORK TILE LEGIBILITY v1  (2026-07-27)
   The photo tiles carry a caption over a live website screenshot —
   the old scrim topped out at .9 only at the very bottom edge, so the
   client's own headline bled through ours. Deeper, earlier gradient.
   ============================================================ */
.work-tile--photo::before{background:linear-gradient(180deg,
  rgba(4,6,9,0) 0%,rgba(4,6,9,.26) 17%,rgba(4,6,9,.86) 40%,
  rgba(3,5,8,.97) 62%,rgba(3,5,8,.99) 100%)}
/* the featured tile carries three lines of copy + a button — its old ramp
   started at 38% and only reached .86, so the client's own headline and
   buttons cut through ours. */
.wfeat__main::after{background:linear-gradient(180deg,
  rgba(3,4,6,0) 0%,rgba(3,4,6,.18) 30%,rgba(3,4,6,.72) 52%,
  rgba(2,3,5,.94) 74%,rgba(2,3,5,.99) 100%)}
.wfeat__copy h3,.wfeat__copy p{text-shadow:0 1px 16px rgba(2,4,7,.65)}
.work-tile--photo .work-tile__c{text-shadow:0 1px 14px rgba(2,4,7,.6)}

/* ============================================================
   PRICING / CLOSE  v1  (2026-07-27)  — section.prc#pricing
   Sits between the testimonials and the FAQ: proof, then price,
   then objection handling, then the CTA. Palette is blue-family
   only; the big soft ellipse is the same #0A80FF the hero uses.
   ============================================================ */
.prc{position:relative;isolation:isolate;overflow:hidden;padding-top:clamp(72px,8vw,124px)}
.prc__bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
/* the soft ellipse — a hugely blurred ring, so the light reads as a
   halo behind the header rather than a flat radial wash */
.prc__ring{position:absolute;left:-42%;right:-42%;top:-34vh;height:104vh;border-radius:50%;
  border:clamp(90px,13vw,190px) solid rgba(10,128,255,.30);
  filter:blur(88px);-webkit-filter:blur(88px)}
.prc__grid{position:absolute;left:0;right:0;top:0;height:min(560px,58%);
  background-image:linear-gradient(90deg,rgba(160,205,255,.11) 1px,transparent 1px),
                   linear-gradient(180deg,rgba(160,205,255,.07) 1px,transparent 1px);
  background-size:74px 84px;
  -webkit-mask-image:radial-gradient(56% 62% at 50% 34%,#000,transparent 76%);
          mask-image:radial-gradient(56% 62% at 50% 34%,#000,transparent 76%)}
.prc__dust{position:absolute;inset:0;width:100%;height:100%;display:block;
  -webkit-mask-image:radial-gradient(62% 66% at 50% 30%,#000,transparent 82%);
          mask-image:radial-gradient(62% 66% at 50% 30%,#000,transparent 82%)}
.prc__in{position:relative;z-index:2}

/* ---- header ---- */
.prc__head{text-align:center;max-width:760px;margin:0 auto clamp(34px,4vw,54px)}
.prc__seal{display:grid;place-items:center;width:60px;height:60px;margin:0 auto 20px;
  border-radius:17px;background:linear-gradient(180deg,rgba(12,24,44,.9),rgba(6,10,18,.9));
  border:1px solid rgba(0,119,255,.34);
  box-shadow:0 0 0 1px rgba(255,255,255,.04) inset,0 14px 40px rgba(0,60,160,.42),
             0 0 44px rgba(0,119,255,.22)}
.prc__seal img{width:30px;height:auto;display:block;filter:drop-shadow(0 2px 8px rgba(0,90,220,.6))}
.prc__h{font-family:var(--font-display);line-height:1.03;letter-spacing:-.02em;
  font-size:clamp(2.05rem,4.4vw,3.5rem);margin:.5rem 0 .9rem;color:#fff}
.prc__sub{color:rgba(210,224,240,.74);font-size:clamp(.98rem,1.15vw,1.08rem);
  max-width:620px;margin:0 auto;line-height:1.6}

/* ---- the switch ---- */
.prc__switch{position:relative;display:inline-grid;grid-auto-flow:column;
  grid-auto-columns:1fr;margin-top:26px;padding:5px;border-radius:999px;
  background:rgba(8,12,20,.72);border:1px solid rgba(120,170,235,.22);
  box-shadow:0 10px 30px rgba(2,10,26,.5),0 1px 0 rgba(255,255,255,.05) inset;
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
.prc__thumb{position:absolute;top:5px;bottom:5px;left:5px;width:calc(50% - 5px);
  border-radius:999px;background:linear-gradient(180deg,#2C90FF,#0058C4);
  border:1px solid rgba(140,200,255,.5);
  box-shadow:0 6px 20px rgba(0,80,200,.55),0 0 0 1px rgba(255,255,255,.10) inset;
  transition:transform .42s cubic-bezier(.34,1.42,.42,1)}
.prc__tab{position:relative;z-index:1;appearance:none;background:none;border:0;cursor:pointer;
  font:inherit;font-weight:700;font-size:.94rem;letter-spacing:.01em;
  padding:11px clamp(18px,2.4vw,30px);border-radius:999px;
  color:rgba(196,214,236,.72);transition:color .3s}
.prc__tab.is-on{color:#fff}
.prc__tab:focus-visible{outline:2px solid rgba(120,190,255,.8);outline-offset:3px}

/* ---- cards ---- */
.prc__grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.5vw,20px);
  max-width:1120px;margin:0 auto}
.pcard{position:relative;display:flex;flex-direction:column;padding:26px 24px 28px;
  border-radius:20px;
  background:linear-gradient(180deg,rgba(14,19,29,.94),rgba(8,11,18,.94));
  border:1px solid rgba(120,160,215,.16);
  box-shadow:0 1px 0 rgba(255,255,255,.045) inset,0 26px 60px rgba(2,10,26,.5);
  transition:transform .4s var(--ease),box-shadow .4s,border-color .4s}
.pcard--pop{z-index:2;
  background:linear-gradient(180deg,rgba(11,26,50,.96),rgba(7,13,26,.96));
  border-color:rgba(0,119,255,.42);
  box-shadow:0 1px 0 rgba(255,255,255,.07) inset,0 0 0 1px rgba(0,119,255,.14) inset,
             0 34px 90px rgba(0,52,150,.5),0 0 120px rgba(0,90,240,.20)}
.pcard__badge{position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  padding:4px 13px;border-radius:999px;font-size:.66rem;font-weight:800;
  letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
  color:#EAF4FF;background:linear-gradient(180deg,#2C90FF,#0058C4);
  border:1px solid rgba(150,205,255,.5);box-shadow:0 6px 18px rgba(0,70,180,.5)}
.pcard .ptile--prod{position:relative;z-index:4;width:54px;margin:0 0 18px;flex:none;
  align-self:flex-start;pointer-events:none}
.pcard .ptile--prod canvas{width:54px;height:54px;border-radius:15px;
  box-shadow:0 10px 26px rgba(2,10,26,.55),0 0 0 1px rgba(120,170,235,.20) inset}
.pcard .ptile--prod img{top:27px;width:44%}
.pcard--pop .ptile--prod canvas{box-shadow:0 12px 30px rgba(0,40,110,.6),0 0 0 1px rgba(0,140,255,.34) inset,0 0 26px rgba(0,110,240,.30)}
.pcard__body{opacity:0;transform:translateY(-12px);filter:blur(8px);
  transition:opacity .5s ease,transform .5s cubic-bezier(.2,.7,.2,1),filter .5s ease}
.pcard__body--go{opacity:1;transform:none;filter:blur(0)}
.pcard__t{font-family:var(--font-display);font-size:1.42rem;letter-spacing:-.01em;
  margin:0 0 .5rem;color:#fff}
.pcard__price{display:flex;align-items:baseline;gap:1px;margin:0 0 .55rem;color:#fff}
.pcard__cur{font-size:1.5rem;font-weight:700;transform:translateY(-.34em);opacity:.9}
.pcard__n{font-family:var(--font-display);font-size:clamp(2.1rem,3vw,2.6rem);
  font-weight:800;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.pcard__plus{font-size:1.4rem;font-weight:700;opacity:.6;margin-right:5px}
.pcard__unit{font-size:.9rem;color:rgba(198,214,234,.6);font-weight:600}
.pcard__d{color:rgba(198,212,230,.66);font-size:.92rem;line-height:1.55;margin:0 0 1.2rem;min-height:2.9em}
.pcard__cta{margin-bottom:1.35rem}
.pcard__inc{padding-top:1.15rem;border-top:1px solid rgba(120,160,215,.16)}
.pcard__inc h4{font-size:.9rem;font-weight:700;color:#EAF2FC;margin:0 0 .8rem}
.pcard__inc ul{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.pcard__inc li{display:flex;align-items:flex-start;gap:10px;
  font-size:.895rem;color:rgba(200,214,232,.78);line-height:1.45}
.pcard__inc li i{flex:none;width:9px;height:9px;margin-top:.42em;border-radius:50%;
  background:radial-gradient(circle at 32% 30%,#7FC0FF,#0A6BE0);
  box-shadow:0 0 8px rgba(0,110,240,.5)}
.pcard--pop .pcard__inc li i{background:radial-gradient(circle at 32% 30%,#AFD8FF,#0077FF);
  box-shadow:0 0 12px rgba(0,130,255,.75)}

/* ---- footer note ---- */
.prc__foot{text-align:center;color:rgba(190,206,226,.6);font-size:.92rem;
  margin:clamp(28px,3.2vw,42px) auto 0;max-width:660px;line-height:1.65}
.prc__foot b{color:#DCE9F8}
.prc__foot a{color:#4FA1FF;font-weight:600;white-space:nowrap}
.prc__foot a:hover{color:#8CC5FF}

@media(max-width:940px){
  .prc__grid3{grid-template-columns:1fr;max-width:520px}
  .pcard__d{min-height:0}
}
@media(max-width:420px){
  .prc__tab{padding:11px 15px;font-size:.86rem}
}
@media (prefers-reduced-motion:reduce){
  .prc__thumb{transition:none}
  .pcard__body{opacity:1;transform:none;filter:none;transition:none}
}
/* ============================================================
   QUAD REVERT v2 (2026-07-27)
   User: "this section looked better smaller like it was before,
   not the whole width, revert back this section with 4 squares to
   original sizes." QUAD FULL-BLEED v1 is removed — the grid goes
   back to the 1560px cap, the 12px gutter, and the original
   clamp(420px,56vh,620px) tile height from the base rules at
   line ~1206. Nothing is overridden here on purpose; this block
   exists only to record the reversal so v1 does not come back.
   ============================================================ */

/* ============================================================
   HERO LOCKUP v14 (2026-07-27)
   User: "add more glow to the logo / make logo a little larger /
   remove blue dark water above the logo / make [the] gray text
   bolder and slightly larger to read better under the logo."
   ============================================================ */
/* 1. the blue DARK WATER eyebrow above the mark comes out. The mark IS the
   wordmark here — saying it twice weakened both. Hidden rather than deleted
   so the build-in choreography below it keeps its timing. */
.hero .hero__inner > .eyebrow--center{display:none}
/* 2. bigger mark. 26vw -> 30vw with the floor and ceiling moved to match,
   so it grows on every screen, not just mid-range ones. */
.hero__brandmark--mono{height:clamp(232px,30vw,392px);margin:.6rem 0 2rem}
/* 3. more glow. Same three-stage arrival, but the white core roughly doubles
   in spread and the blue halo pushes out past the mark's own footprint so the
   light reads as coming off the logo, not sitting behind it. */
.hero__brandmark--mono{animation:markGlowIn14 3.6s ease-out .5s both}
@keyframes markGlowIn14{
  0%{filter:drop-shadow(0 0 34px rgba(255,255,255,.42)) drop-shadow(0 0 80px rgba(0,119,255,.40)) brightness(1)}
  55%{filter:drop-shadow(0 0 120px rgba(255,255,255,1)) drop-shadow(0 0 210px rgba(0,119,255,.78)) drop-shadow(0 0 40px rgba(150,205,255,.85)) brightness(1.3)}
  100%{filter:drop-shadow(0 0 62px rgba(255,255,255,.78)) drop-shadow(0 0 150px rgba(0,119,255,.66)) drop-shadow(0 0 26px rgba(150,205,255,.6)) brightness(1.14)}
}
@media (prefers-reduced-motion:reduce){
  .hero__brandmark--mono{animation:none;
    filter:drop-shadow(0 0 62px rgba(255,255,255,.78)) drop-shadow(0 0 150px rgba(0,119,255,.66)) drop-shadow(0 0 26px rgba(150,205,255,.6)) brightness(1.14)}
}
/* 4. INSIGHT · AUTOMATION · GROWTH. Inter only ships to 700 in our font link,
   so "bolder" means switching this line to Satoshi 900 (already imported) —
   a real heavier cut instead of a faux-bold. Size up from .78rem, tracking
   pulled in slightly so the wider letters don't sprawl, and the grey lifted
   from #7C89A1 to a legible #A8B8CF against the near-black field. */
.hero__pillars{font-family:'Satoshi',var(--font-body);font-weight:900;
  font-size:clamp(.94rem,1.05vw,1.16rem);letter-spacing:.24em;color:#A8B8CF;
  margin:1.5rem 0 2.4rem}

/* ============================================================
   MARK LIGHT PASS v15 (2026-07-27)
   User: "the glow was there already, it needed to move THROUGH the logo
   and tone down the brightness a little," then "the glow comes from the
   logo AFTER the life coming into the logo — not the glow starting in
   the background."
   ------------------------------------------------------------
   The thing that made v14 wrong: the mark art is pure #fff, and you
   cannot make white brighter. Any "traveling highlight" laid over a
   fully-lit white logo is invisible — which is why v14 only ever read
   as a static halo. So the base mark drops to a satin brightness and
   the pass carries the actual light. Same lesson as v11; it got lost
   when v13 flattened everything to one steady glow.

   Why stacked <img> and not a pseudo-element: a URL mask
   (mask:url(dw-icon.png)) fails silently in some engines and takes the
   whole layer with it — that killed the v12 sheen. Two extra copies of
   the logo with a GRADIENT mask cannot fail that way.
   ============================================================ */
/* 1. satin base, and NO halo until the light arrives. The mark lands as
   plain white-on-black; the glow does not exist yet. It blooms outward
   from the strokes as the pass crosses, then stays (arrives-and-stays
   still holds). Peak brightness is well under v14 — toned down. */
.hero__brandmark--mono{animation:markGlowIn15 3.8s ease-out 2.5s both}
@keyframes markGlowIn15{
  0%{filter:brightness(.78)}
  14%{filter:drop-shadow(0 0 12px rgba(255,255,255,.14)) brightness(.80)}
  52%{filter:drop-shadow(0 0 58px rgba(255,255,255,.54)) drop-shadow(0 0 124px rgba(0,119,255,.52)) brightness(.92)}
  100%{filter:drop-shadow(0 0 42px rgba(255,255,255,.44)) drop-shadow(0 0 104px rgba(0,119,255,.48)) brightness(.86)}
}
@media (prefers-reduced-motion:reduce){
  .hero__brandmark--mono{animation:none;
    filter:drop-shadow(0 0 42px rgba(255,255,255,.44)) drop-shadow(0 0 104px rgba(0,119,255,.48)) brightness(.86)}
}
/* 2. the pass. Same logo stacked exactly on top (the wrap is sized by the
   base image, so inset:0 + contain registers 1:1), with a narrow diagonal
   window sliding across it. Only the slice inside the window shows, so the
   light travels THROUGH the strokes instead of over a rectangle. The light
   is carried by drop-shadows, not brightness — on white art, emitted glow
   is the only channel that actually reads. */
.markpass{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  pointer-events:none;z-index:2;opacity:0;
  filter:brightness(1.5)
         drop-shadow(0 0 8px rgba(255,255,255,1))
         drop-shadow(0 0 22px rgba(255,255,255,.9))
         drop-shadow(0 0 48px rgba(198,228,255,.95))
         drop-shadow(0 0 90px rgba(0,119,255,.65));
  -webkit-mask-image:linear-gradient(102deg,transparent 39%,#000 50%,transparent 61%);
          mask-image:linear-gradient(102deg,transparent 39%,#000 50%,transparent 61%);
  -webkit-mask-size:300% 100%;mask-size:300% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  animation:markpass15 8s cubic-bezier(.5,0,.5,1) 2.2s infinite,
            passFade 1s ease-out 2.4s forwards}
/* the bloom copy runs a wider, blurred window so the light spills off the
   edges of the strokes instead of stopping at them */
.markpass--bloom{z-index:1;
  filter:blur(17px) brightness(1.55) saturate(.8);
  -webkit-mask-image:linear-gradient(102deg,transparent 32%,#000 50%,transparent 68%);
          mask-image:linear-gradient(102deg,transparent 32%,#000 50%,transparent 68%);
  animation:markpass15 8s cubic-bezier(.5,0,.5,1) 2.2s infinite,
            passFadeBloom 1s ease-out 2.4s forwards}
/* one unhurried crossing, then a long rest — a light that passes through,
   not a strobe */
/* NOTE for future me: mask-position percentages are NOT pixel offsets — X%
   aligns X% of the mask box with X% of the element. With mask-size:300%,
   the entire usable travel is 0%..100%, and the band only crosses the logo
   between roughly 8% and 92%. v15.0 animated 168% -> -150%, so ~74% of the
   duration was spent with the band off-logo and the light appeared for
   barely a second. These numbers are the crossing window and nothing else. */
@keyframes markpass15{
  0%,14%{-webkit-mask-position:104% 0;mask-position:104% 0}
  66%,100%{-webkit-mask-position:-4% 0;mask-position:-4% 0}}
@keyframes passFade{to{opacity:1}}
@keyframes passFadeBloom{to{opacity:.9}}
@media (prefers-reduced-motion:reduce){.markpass{display:none}}

/* ============================================================
   GROWTH-OS DASHBOARD BAND v16 (2026-07-27)
   The band used to be one lone browser mockup floating in a big
   empty card. Now it's a stack: the portal shot plus three live
   panels (revenue area chart, channel bars, conversion ring), a
   rotating headline question, count-up KPIs and a metrics ticker.
   All motion is CSS; the charts draw themselves off .reveal.in so
   nothing animates until the section is actually on screen.
   ============================================================ */
.dashband{padding:clamp(38px,5vw,64px) clamp(34px,5vw,64px) 0;overflow:hidden}
.dashband .lead{max-width:56ch;margin-left:0;margin-right:0}
.dashband__grid{display:grid;grid-template-columns:1.08fr 1fr;gap:clamp(28px,4vw,56px);
  align-items:center;position:relative;z-index:1}
.dashband__copy{min-width:0}

/* slow diagonal light passing over the whole band */
.dashband__sweep{position:absolute;top:-40%;left:-60%;width:46%;height:180%;z-index:0;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(59,158,255,.10) 45%,rgba(255,255,255,.05) 52%,transparent);
  transform:skewX(-14deg);animation:dashSweep 11s ease-in-out infinite}
@keyframes dashSweep{0%,8%{left:-60%}70%,100%{left:130%}}

/* the rotating question — words as the movement */
.qroll{position:relative;height:1.4em;margin:.35rem 0 .1rem;
  font-family:var(--font-display);font-weight:700;line-height:1.34;
  font-size:clamp(1.2rem,1.85vw,1.85rem)}
/* width:max-content matters — background-clip:text only paints inside the
   element box, so a nowrap line wider than the box loses its last letters. */
.qroll span{position:absolute;left:0;top:0;width:max-content;white-space:nowrap;opacity:0;
  animation:qroll 17s cubic-bezier(.22,1,.36,1) infinite}
.qroll span:nth-child(2){animation-delay:4.25s}
.qroll span:nth-child(3){animation-delay:8.5s}
.qroll span:nth-child(4){animation-delay:12.75s}
@keyframes qroll{
  0%{opacity:0;transform:translateY(16px);filter:blur(7px)}
  3%,22%{opacity:1;transform:none;filter:blur(0)}
  27%,100%{opacity:0;transform:translateY(-16px);filter:blur(7px)}}

/* count-up KPI strip */
.dkpirow{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(10px,1.6vw,22px);margin:1.6rem 0 .2rem}
.dkpi{position:relative;padding-left:14px}
.dkpi::before{content:"";position:absolute;left:0;top:4px;bottom:4px;width:2px;border-radius:2px;
  background:var(--grad-aqua);opacity:.75}
.dkpi b{display:block;font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.05rem,1.5vw,1.42rem);color:#fff;letter-spacing:-.01em;line-height:1.1}
.dkpi span{display:block;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-mut);margin-top:.24rem}

/* the stack */
.dashband .flex{gap:.7rem}
.dashband .flex .btn{padding:.86rem 1.25rem;font-size:.92rem}
.dashstack{position:relative;min-width:0}
.dashstack .dashshot{transform:perspective(1400px) rotateY(-5deg) rotateX(2deg);
  box-shadow:0 34px 70px rgba(0,0,0,.62),0 0 0 1px rgba(255,255,255,.05);
  transition:transform .6s var(--ease),box-shadow .6s var(--ease)}
.dashstack .dashshot:hover{transform:perspective(1400px) rotateY(0) rotateX(0) translateY(-6px)}

.dcard{position:absolute;z-index:3;border-radius:14px;padding:12px 14px;
  background:linear-gradient(165deg,rgba(20,24,32,.94),rgba(10,13,19,.92));
  border:1px solid rgba(255,255,255,.11);
  box-shadow:0 22px 50px rgba(0,0,0,.6),0 0 0 1px rgba(0,119,255,.10) inset;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.dcard__head{display:flex;justify-content:space-between;align-items:center;
  font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--text-mut)}
.dcard__head em{font-style:normal;color:var(--brand-bright)}
.dcard__val{font-family:var(--font-display);font-weight:700;color:#fff;
  font-size:clamp(.95rem,1.3vw,1.18rem);margin:.34rem 0 .1rem;letter-spacing:-.01em}
.dcard__val b{font-size:.7rem;font-weight:700;color:#3B9EFF;margin-left:.3rem;letter-spacing:0}
.live{display:inline-flex;align-items:center;gap:5px}
.live i{width:6px;height:6px;border-radius:50%;background:#3B9EFF;
  box-shadow:0 0 0 0 rgba(59,158,255,.7);animation:livePulse 2s ease-out infinite}
@keyframes livePulse{0%{box-shadow:0 0 0 0 rgba(59,158,255,.65)}
  70%,100%{box-shadow:0 0 0 8px rgba(59,158,255,0)}}

.dcard--rev{top:15%;right:-18px;width:58%;animation:dfloatA 9s ease-in-out infinite}
.dcard--ch{bottom:-10px;left:-24px;width:47%;animation:dfloatB 11s ease-in-out infinite}
.dcard--conv{top:46%;left:-30px;display:flex;align-items:center;gap:10px;padding:10px 15px 10px 11px;
  animation:dfloatA 13s ease-in-out infinite}
.dcard--conv b{display:block;font-family:var(--font-display);font-weight:700;color:#fff;font-size:1.02rem;line-height:1.1}
.dcard--conv span{display:block;font-size:.63rem;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mut)}
@keyframes dfloatA{0%,100%{transform:translateY(0)}50%{transform:translateY(-11px)}}
@keyframes dfloatB{0%,100%{transform:translateY(0)}50%{transform:translateY(9px)}}

/* revenue area chart — draws itself when the band reveals */
.area{display:block;width:100%;height:58px;margin-top:4px;overflow:visible}
.area__fill{opacity:0;transition:opacity .9s ease .7s}
.area__line{stroke-dasharray:100;stroke-dashoffset:100;transition:stroke-dashoffset 1.9s cubic-bezier(.4,0,.2,1) .25s}
.area__dot{fill:#fff;opacity:0;transition:opacity .4s ease 2s;
  filter:drop-shadow(0 0 6px rgba(59,158,255,.95))}
.dashband.in .area__fill{opacity:1}
.dashband.in .area__line{stroke-dashoffset:0}
.dashband.in .area__dot{opacity:1;animation:dotPulse 2.4s ease-in-out 2.2s infinite}
@keyframes dotPulse{0%,100%{r:3.4}50%{r:4.6}}

/* channel bars — grow on reveal, then breathe */
.bars{display:flex;align-items:flex-end;gap:7px;height:66px;margin-top:10px}
.bars i{position:relative;flex:1;height:var(--h);border-radius:4px 4px 2px 2px;
  background:linear-gradient(180deg,#3B9EFF,#0057C4);transform:scaleY(0);transform-origin:bottom;
  transition:transform .85s cubic-bezier(.34,1.2,.4,1)}
.bars i:nth-child(2){transition-delay:.08s}.bars i:nth-child(3){transition-delay:.16s}
.bars i:nth-child(4){transition-delay:.24s}.bars i:nth-child(5){transition-delay:.32s}
.bars i:nth-child(6){transition-delay:.4s}
.bars i b{position:absolute;left:0;right:0;bottom:-15px;text-align:center;
  font-size:.54rem;letter-spacing:.08em;color:var(--text-mut);font-weight:600}
.bars i:nth-child(4){background:linear-gradient(180deg,#7BB8FF,#0A80FF);
  box-shadow:0 0 18px rgba(0,119,255,.55)}
.dashband.in .bars i{transform:scaleY(1)}
.dcard--ch{padding-bottom:26px}

/* conversion ring — scoped to .dashband: command-center.html defines its own
   .ring (a large conic gauge) and the unscoped rule was rotating its label 90deg */
.dashband .ring{width:44px;height:44px;flex:none;transform:rotate(-90deg)}
.dashband .ring__bg{fill:none;stroke:rgba(255,255,255,.10);stroke-width:4}
.dashband .ring__fg{fill:none;stroke:#3B9EFF;stroke-width:4;stroke-linecap:round;
  stroke-dasharray:100;stroke-dashoffset:100;transition:stroke-dashoffset 1.6s cubic-bezier(.4,0,.2,1) .5s;
  filter:drop-shadow(0 0 5px rgba(59,158,255,.7))}
.dashband.in .ring__fg{stroke-dashoffset:22}

/* metrics ticker along the bottom edge */
.dashticker{position:relative;z-index:1;margin:clamp(26px,3.5vw,44px) calc(-1 * clamp(34px,5vw,64px)) 0;
  border-top:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.02);
  overflow:hidden;padding:13px 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.dashticker__t{display:flex;width:max-content;animation:dashTick 38s linear infinite}
.dashticker__t span{display:inline-flex;align-items:center;gap:8px;padding:0 26px;white-space:nowrap;
  font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--text-mut);
  border-right:1px solid rgba(255,255,255,.06)}
.dashticker__t b{color:#fff;font-family:var(--font-display);font-weight:700;letter-spacing:0;font-size:.86rem}
@keyframes dashTick{from{transform:translateX(0)}to{transform:translateX(-50%)}}

@media (max-width:960px){
  .dashband__grid{grid-template-columns:1fr;gap:34px}
  .dashstack{padding:26px 0 10px}
  .dashstack .dashshot{transform:none}
  .dcard--rev{right:-8px;width:64%}
  .dcard--ch{left:-8px;width:52%;bottom:-4px}
  .dcard--conv{left:auto;right:8%;top:-8px}
}
@media (max-width:620px){
  .dcard--conv{display:none}
  .dcard--rev{width:72%;right:-4px;top:-6px}
  .dcard--ch{width:60%;left:-4px;bottom:-6px}
  .qroll{height:2.7em;white-space:normal}
  .qroll span{white-space:normal}
}
@media (prefers-reduced-motion:reduce){
  .dashband__sweep,.dcard--rev,.dcard--ch,.dcard--conv,.dashticker__t{animation:none}
  .qroll span{animation:none;opacity:0}
  .qroll span:first-child{opacity:1}
  .live i{animation:none}
  .dashband.in .area__dot{animation:none}
}

/* ============================================================================
   THE CLOSE v17 (2026-07-27) — final CTA, full-bleed "sign up" finale
   Video: assets/video/cta-growth.mp4 (graded blue, ping-pong seamless loop)
   ============================================================================ */
.closer-sec{padding:0;margin-top:clamp(46px,6vw,96px)}
.closer{position:relative;overflow:hidden;isolation:isolate;background:#04070C;
  padding:clamp(66px,8.5vw,128px) 0 clamp(56px,7vw,100px);
  border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2)}
.closer__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  opacity:.66;transform:scale(1.06);animation:closerDrift 30s ease-in-out infinite}
@keyframes closerDrift{0%,100%{transform:scale(1.06) translate3d(0,0,0)}
  50%{transform:scale(1.13) translate3d(-1.2%,-1%,0)}}
.closer__veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(120% 88% at 50% 6%, rgba(0,119,255,.30), transparent 62%),
    radial-gradient(92% 70% at 50% 100%, rgba(6,46,102,.55), transparent 72%),
    linear-gradient(180deg, rgba(4,7,12,.94) 0%, rgba(4,7,12,.58) 32%,
                            rgba(4,7,12,.74) 68%, rgba(4,7,12,.97) 100%)}
.closer__rays{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.closer__rays i{position:absolute;top:-30%;height:170%;width:min(250px,22vw);
  background:linear-gradient(180deg,rgba(59,158,255,.24),transparent 74%);
  filter:blur(28px);transform:skewX(-11deg);animation:closerRay 15s ease-in-out infinite}
.closer__rays i:nth-child(1){left:7%}
.closer__rays i:nth-child(2){left:45%;animation-delay:-4.8s;animation-duration:19s}
.closer__rays i:nth-child(3){left:77%;animation-delay:-9.4s;animation-duration:17s}
@keyframes closerRay{0%,100%{opacity:.14;transform:skewX(-11deg) translateY(-6%)}
  50%{opacity:.5;transform:skewX(-11deg) translateY(6%)}}
.closer__scan{position:absolute;left:0;right:0;bottom:0;height:1px;z-index:2;pointer-events:none;
  background:linear-gradient(90deg,transparent,#3B9EFF,transparent);
  animation:closerScan 10s ease-in-out infinite}
@keyframes closerScan{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
.closer__inner{position:relative;z-index:3;text-align:center}

/* staged entrance — all gated on .reveal.in so nothing plays off-screen */
.closer__badge,.closer__l1,.closer__l2,.closer__lead,
.closer .cstep,.closer__cta,.closer__fine,.closer__trust{
  opacity:0;transform:translateY(26px);filter:blur(9px);
  transition:opacity .9s var(--ease),transform .9s var(--ease),filter .9s var(--ease)}
.closer.in .closer__badge,.closer.in .closer__l1,.closer.in .closer__l2,.closer.in .closer__lead,
.closer.in .cstep,.closer.in .closer__cta,.closer.in .closer__fine,.closer.in .closer__trust{
  opacity:1;transform:none;filter:blur(0)}
.closer.in .closer__l1{transition-delay:.10s}
.closer.in .closer__l2{transition-delay:.22s}
.closer.in .closer__lead{transition-delay:.36s}
.closer.in .cstep:nth-child(1){transition-delay:.50s}
.closer.in .cstep:nth-child(2){transition-delay:.60s}
.closer.in .cstep:nth-child(3){transition-delay:.70s}
.closer.in .closer__cta{transition-delay:.84s}
.closer.in .closer__fine{transition-delay:.94s}
.closer.in .closer__trust{transition-delay:1.02s}

.closer__badge{display:inline-flex;align-items:center;gap:.58rem;
  padding:.46rem .98rem;border-radius:999px;
  background:rgba(0,119,255,.13);border:1px solid rgba(59,158,255,.34);color:#CFE4FF;
  font-size:.71rem;letter-spacing:.13em;text-transform:uppercase;font-weight:600;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.closer__badge i{width:7px;height:7px;border-radius:50%;background:#3B9EFF;
  box-shadow:0 0 0 0 rgba(59,158,255,.75);animation:livePulse 2.1s ease-out infinite}

.closer__h{margin:1.15rem 0 0;font-family:var(--font-display);font-weight:700;
  letter-spacing:-.03em;line-height:1.05;font-size:clamp(2.1rem,5.2vw,4.3rem)}
.closer__h span{display:block}
.closer__l1{color:#fff;text-shadow:0 4px 32px rgba(0,0,0,.78)}
.closer__l2{filter:drop-shadow(0 0 26px rgba(0,119,255,.45))}
.closer.in .closer__l2{filter:blur(0) drop-shadow(0 0 26px rgba(0,119,255,.45))}
.closer__lead{max-width:690px;margin:1.2rem auto 0;color:#D6DEE9;
  font-size:clamp(1rem,1.2vw,1.12rem);line-height:1.66;text-shadow:0 1px 16px rgba(0,0,0,.85)}

.closer__steps{list-style:none;margin:clamp(30px,4vw,54px) auto 0;padding:0;max-width:1010px;
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,26px);
  position:relative;text-align:left}
.closer__steps::before{content:"";position:absolute;z-index:0;top:37px;left:14%;right:14%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.55),transparent);
  transform:scaleX(0);transform-origin:left;transition:transform 1.5s var(--ease) .55s}
.closer.in .closer__steps::before{transform:scaleX(1)}
.cstep{position:relative;z-index:1;padding:20px 20px 22px;border-radius:16px;
  background:linear-gradient(165deg,rgba(16,21,30,.74),rgba(8,11,17,.62));
  border:1px solid rgba(255,255,255,.09);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 20px 46px rgba(0,0,0,.48),0 0 0 1px rgba(0,119,255,.08) inset;
  transition:transform .5s var(--ease),border-color .5s var(--ease),box-shadow .5s var(--ease),
             opacity .9s var(--ease),filter .9s var(--ease)}
.cstep:hover{transform:translateY(-6px);border-color:rgba(59,158,255,.34);
  box-shadow:0 28px 60px rgba(0,0,0,.55),0 0 0 1px rgba(0,119,255,.22) inset}
.cstep__n{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:11px;font-family:var(--font-display);font-weight:700;font-size:.88rem;color:#fff;
  background:var(--grad-aqua);box-shadow:0 8px 20px rgba(0,119,255,.42)}
.cstep h3{margin:.8rem 0 .32rem;font-size:1.03rem;color:#fff;letter-spacing:-.012em}
.cstep p{margin:0;font-size:.88rem;line-height:1.56;color:var(--text-soft)}

.closer__cta{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;
  margin:clamp(28px,3.6vw,46px) 0 0}
.closer__go{position:relative;overflow:hidden;display:inline-flex;align-items:center;gap:.6rem;
  animation:closerBreathe 3.6s ease-in-out infinite}
.closer__go svg{width:18px;height:18px;transition:transform .45s var(--ease)}
.closer__go:hover svg{transform:translateX(5px)}
.closer__go::after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:42%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.42),transparent);
  transform:skewX(-18deg);animation:closerShine 4.6s ease-in-out infinite;pointer-events:none}
@keyframes closerShine{0%,58%{left:-60%}92%,100%{left:132%}}
@keyframes closerBreathe{0%,100%{box-shadow:0 14px 40px rgba(0,119,255,.34)}
  50%{box-shadow:0 16px 56px rgba(0,119,255,.62)}}

.closer__fine{margin:1.15rem auto 0;max-width:740px;font-size:.86rem;color:var(--text-soft)}
.closer__fine b{color:#fff;font-weight:600}
.closer__fine a{color:var(--brand-bright);text-decoration:none}
.closer__fine a:hover{text-decoration:underline}
.closer__trust{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:.55rem 1.7rem;
  margin:clamp(22px,3vw,36px) 0 0;padding:0;
  font-size:.71rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mut)}
.closer__trust li{position:relative;padding-left:16px}
.closer__trust li::before{content:"";position:absolute;left:0;top:50%;margin-top:-3px;
  width:6px;height:6px;border-radius:50%;background:var(--brand-bright);opacity:.85;
  box-shadow:0 0 8px rgba(59,158,255,.85)}

@media (max-width:860px){
  .closer__steps{grid-template-columns:1fr;max-width:520px}
  .closer__steps::before{display:none}
  .closer__cta .btn{width:100%;max-width:340px}
  .closer__cta{flex-direction:column;align-items:center}
}
@media (max-width:560px){
  .closer__trust{gap:.5rem 1.1rem;font-size:.66rem}
  .closer__video{opacity:.5}
}
@media (prefers-reduced-motion:reduce){
  .closer__video{display:none}
  .closer{background:#04070C url('../video/cta-growth-poster.jpg') center/cover}
  .closer__video,.closer__rays i,.closer__scan,.closer__go,.closer__go::after,.closer__badge i{animation:none!important}
  .closer__badge,.closer__l1,.closer__l2,.closer__lead,.closer .cstep,
  .closer__cta,.closer__fine,.closer__trust{opacity:1;transform:none;filter:none;transition:none}
  .closer__steps::before{transform:scaleX(1)}
}

/* ============================================================
   PAGE EXPERIENCE v18 (2026-07-27)
   Pairs with the v18 IIFE at the end of main.js. Gives every
   inner page the homepage's depth: cinematic hero, ambient
   aura, staged entrance, and THE CLOSE at the bottom.
   Also corrects the legacy .page-hero::before glow, which used
   rgba(0,119,255,..) — cyan, off-palette. Blue family only.
   ============================================================ */

/* --- legacy hero glow: cyan -> brand blue --- */
.page-hero::before{
  background:radial-gradient(70% 120% at 80% 0%, rgba(0,119,255,.16), transparent 55%);
}

/* --- 3. ambient page aura (non-home pages) --- */
.pgaura{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background-image:linear-gradient(rgba(59,158,255,.030) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(59,158,255,.030) 1px,transparent 1px);
  background-size:78px 78px}
.pgaura i{position:absolute;display:block;border-radius:50%;filter:blur(80px);opacity:1}
.pgaura i:nth-child(1){width:70vw;height:70vw;left:-18vw;top:-20vw;
  background:radial-gradient(circle,rgba(0,119,255,.34),rgba(0,119,255,.10) 46%,transparent 70%);
  animation:pgFloatA 34s ease-in-out infinite}
.pgaura i:nth-child(2){width:58vw;height:58vw;right:-16vw;top:34vh;
  background:radial-gradient(circle,rgba(10,128,255,.28),rgba(10,95,204,.08) 48%,transparent 72%);
  animation:pgFloatB 42s ease-in-out infinite}
.pgaura i:nth-child(3){width:52vw;height:52vw;left:18vw;bottom:-22vw;
  background:radial-gradient(circle,rgba(6,46,102,.70),rgba(6,46,102,.18) 50%,transparent 74%);
  animation:pgFloatA 50s ease-in-out infinite reverse}
@keyframes pgFloatA{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(4vw,3vh,0) scale(1.12)}}
@keyframes pgFloatB{0%,100%{transform:translate3d(0,0,0) scale(1.06)}50%{transform:translate3d(-5vw,-4vh,0) scale(1)}}
#main,#footer,main{position:relative;z-index:1}
/* #header must outrank #main. Both are position:relative siblings, so at equal
   z-index the later element in the DOM (#main) paints on top — which silently
   buried every nav dropdown behind the hero the moment it extended past the
   header bar. The bar itself stayed visible because it sits above the hero's
   top edge, which is what made this look like "hover is broken" rather than a
   paint-order bug. 70 clears #main and the in-header drawer's z-index:80 still
   resolves correctly inside this stacking context. */
#header{position:relative;z-index:70}

/* --- 1. cinematic page hero --- */
.page-hero--cine{
  position:relative;isolation:isolate;overflow:hidden;background:#04070C;
  padding-block:clamp(88px,11vw,168px);
  border-bottom:1px solid var(--line-2)}
.page-hero--cine::before{display:none}
.phfx{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.phfx__v{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.12);
  transition:opacity 1.6s var(--ease),transform 2.6s var(--ease)}
.page-hero--cine.lit .phfx__v{opacity:.34;transform:scale(1.04)}
.phfx__grid{position:absolute;inset:0;opacity:0;transition:opacity 1.8s var(--ease) .25s;
  background-image:linear-gradient(rgba(59,158,255,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(59,158,255,.055) 1px,transparent 1px);
  background-size:62px 62px;
  -webkit-mask-image:radial-gradient(80% 76% at 62% 22%,#000 0%,transparent 74%);
          mask-image:radial-gradient(80% 76% at 62% 22%,#000 0%,transparent 74%)}
.page-hero--cine.lit .phfx__grid{opacity:1}
.phfx__veil{position:absolute;inset:0;
  background:
    radial-gradient(96% 110% at 78% 0%, rgba(0,119,255,.26), transparent 58%),
    radial-gradient(72% 90% at 8% 100%, rgba(6,46,102,.50), transparent 70%),
    linear-gradient(180deg, rgba(4,7,12,.86) 0%, rgba(4,7,12,.46) 42%, rgba(5,7,13,.95) 100%)}
.phfx__rays{position:absolute;inset:0;overflow:hidden}
.phfx__rays i{position:absolute;top:-34%;height:172%;width:min(210px,20vw);
  background:linear-gradient(180deg,rgba(59,158,255,.20),transparent 72%);
  filter:blur(30px);transform:skewX(-12deg);opacity:0;
  animation:phRay 17s ease-in-out infinite}
.page-hero--cine.lit .phfx__rays i{opacity:1}
.phfx__rays i:nth-child(1){left:12%}
.phfx__rays i:nth-child(2){left:52%;animation-delay:-5.5s;animation-duration:21s}
.phfx__rays i:nth-child(3){left:82%;animation-delay:-11s;animation-duration:19s}
@keyframes phRay{0%,100%{opacity:.12;transform:skewX(-12deg) translateY(-5%)}
  50%{opacity:.44;transform:skewX(-12deg) translateY(5%)}}
.phfx__edge{position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.75),transparent);
  transform:scaleX(0);transform-origin:center;transition:transform 1.7s var(--ease) .35s}
.page-hero--cine.lit .phfx__edge{transform:scaleX(1)}
.page-hero--cine .container{position:relative;z-index:2}
.page-hero--cine h1{font-size:clamp(2.3rem,5.4vw,4.2rem);line-height:1.04;letter-spacing:-.035em;
  text-shadow:0 6px 40px rgba(0,0,0,.72)}
.page-hero--cine .lead{color:#D6DEE9;text-shadow:0 1px 18px rgba(0,0,0,.8)}
.page-hero--cine .crumb a{color:var(--brand-bright)}

/* --- 2. staged hero entrance --- */
.phin .phin__i{opacity:0;transform:translateY(24px);filter:blur(8px);
  transition:opacity .95s var(--ease),transform .95s var(--ease),filter .95s var(--ease)}
.page-hero--cine.lit .phin .phin__i{opacity:1;transform:none;filter:blur(0)}

@media (max-width:640px){
  .page-hero--cine{padding-block:clamp(66px,16vw,110px)}
  .page-hero--cine.lit .phfx__v{opacity:.26}
  .pgaura i{filter:blur(70px);opacity:.42}
}
@media (prefers-reduced-motion:reduce){
  .pgaura i{animation:none!important}
  .phfx__rays i{animation:none!important;opacity:.16}
  .phfx__v{display:none}
  .page-hero--cine.lit .phfx__grid,.page-hero--cine .phfx__grid{opacity:1;transition:none}
  .page-hero--cine .phfx__edge{transform:scaleX(1);transition:none}
  .phin .phin__i{opacity:1;transform:none;filter:none;transition:none}
}

/* ============================================================
   LIVE PRODUCT PANEL v19 (2026-07-27)
   Styles for the panel the v19 IIFE swaps in wherever an inner
   page shipped an empty icon-only .card placeholder.
   ============================================================ */
.card--pviz{padding:0!important;overflow:hidden;background:linear-gradient(168deg,rgba(14,19,28,.90),rgba(7,10,16,.86));
  border:1px solid rgba(255,255,255,.10);border-radius:18px;
  box-shadow:0 28px 70px rgba(0,0,0,.55),0 0 0 1px rgba(0,119,255,.10) inset;
  transition:transform .55s var(--ease),border-color .55s var(--ease),box-shadow .55s var(--ease)}
.card--pviz:hover{transform:translateY(-6px);border-color:rgba(59,158,255,.34);
  box-shadow:0 36px 84px rgba(0,0,0,.62),0 0 0 1px rgba(0,119,255,.24) inset}
.pviz{position:relative;isolation:isolate}
.pviz__chrome{display:flex;align-items:center;gap:.5rem;padding:.7rem .95rem;
  border-bottom:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.025)}
.pviz__chrome i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.16)}
.pviz__chrome i:first-child{background:rgba(59,158,255,.75)}
.pviz__chrome span{margin-left:.35rem;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-mut);font-weight:600}
.pviz__live{margin-left:auto;display:inline-flex;align-items:center;gap:.4rem;font-style:normal;
  font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;color:#9CC9FF}
.pviz__live s{width:6px;height:6px;border-radius:50%;background:#3B9EFF;text-decoration:none;
  box-shadow:0 0 0 0 rgba(59,158,255,.7);animation:livePulse 2.1s ease-out infinite}
.pviz__body{position:relative;padding:clamp(16px,2vw,22px)}
.pviz__mark{position:absolute;right:clamp(14px,2vw,20px);top:clamp(12px,1.6vw,18px);
  width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  background:rgba(0,119,255,.14);border:1px solid rgba(59,158,255,.28);color:#9CC9FF}
.pviz__mark svg{width:20px;height:20px}
.pviz__kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem;padding-right:46px}
.pviz__k b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;
  font-size:clamp(1.25rem,2.1vw,1.7rem);
  background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent}
.pviz__k span{display:block;margin-top:.18rem;font-size:.66rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-mut);line-height:1.35}
.pviz__chartwrap{position:relative;margin:clamp(14px,2vw,20px) 0 0;height:clamp(84px,11vw,104px);
  border-radius:12px;overflow:hidden;background:rgba(0,0,0,.28);
  border:1px solid rgba(255,255,255,.06)}
.pviz__chartwrap::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.045) 1px,transparent 1px);
  background-size:100% 24px}
.pviz__chart{position:absolute;inset:0;width:100%;height:100%}
.pviz__line{stroke-dasharray:100;stroke-dashoffset:100;
  filter:drop-shadow(0 0 6px rgba(59,158,255,.55));
  transition:stroke-dashoffset 2.1s cubic-bezier(.22,.61,.36,1) .25s}
.pviz__area{opacity:0;transition:opacity 1.1s var(--ease) 1.1s}
.pviz--go .pviz__line{stroke-dashoffset:0}
.pviz--go .pviz__area{opacity:1}
.pviz__sweep{position:absolute;top:0;bottom:0;width:34%;left:-40%;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.16),transparent)}
.pviz--go .pviz__sweep{animation:pvizSweep 5.4s ease-in-out 1.6s infinite}
@keyframes pvizSweep{0%{left:-40%}62%,100%{left:120%}}
.pviz__rows{list-style:none;margin:clamp(14px,2vw,18px) 0 0;padding:0;display:grid;gap:.62rem}
.pviz__row{display:grid;grid-template-columns:minmax(96px,34%) 1fr auto;align-items:center;gap:.7rem}
.pviz__row span{font-size:.74rem;color:var(--text-soft)}
.pviz__row i{display:block;height:6px;border-radius:99px;background:rgba(255,255,255,.08);overflow:hidden}
.pviz__row i b{display:block;height:100%;width:0;border-radius:99px;background:var(--grad-aqua);
  box-shadow:0 0 12px rgba(0,119,255,.55);
  transition:width 1.5s cubic-bezier(.22,.61,.36,1) var(--d,.35s)}
.pviz--go .pviz__row i b{width:var(--w,60%)}
.pviz__row em{font-style:normal;font-size:.72rem;font-weight:600;color:#CFE4FF;min-width:30px;text-align:right}
.pviz__sheen{position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(120% 80% at 78% -10%,rgba(0,119,255,.18),transparent 60%)}
@media (max-width:560px){
  .pviz__kpis{grid-template-columns:1fr 1fr;gap:.8rem;padding-right:44px}
  .pviz__k:last-child{grid-column:1/-1}
  .pviz__row{grid-template-columns:minmax(80px,40%) 1fr auto}
}
@media (prefers-reduced-motion:reduce){
  .pviz__line{stroke-dashoffset:0;transition:none}
  .pviz__area{opacity:1;transition:none}
  .pviz__row i b{width:var(--w,60%);transition:none}
  .pviz__sweep,.pviz__live s{animation:none!important;display:none}
}

/* ============================================================
   SIGN-IN / AUTH EXPERIENCE v21 (2026-07-27)
   User: "make sure dashboard will work) create the login page)"
   A cinematic split sign-in that carries the homepage grade into
   the portal door. Shared by:
     - /login.html          (site front door + demo dashboard key)
     - /portal/login.php    (the live, CSRF-protected sign-in)
   ============================================================ */

/* focus ring was still the legacy cyan — bring it to brand blue */
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--aqua);box-shadow:0 0 0 4px rgba(0,119,255,.18)}

.authbody{min-height:100vh;background:#04070C;overflow-x:hidden}
.auth{display:grid;grid-template-columns:1.06fr 1fr;min-height:100vh}

/* ---------- left: the brand stage ---------- */
.auth__stage{position:relative;isolation:isolate;overflow:hidden;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(28px,4vw,58px);background:#04070C;border-right:1px solid var(--line)}
/* ---- the drawn stage ------------------------------------------------------
   Replaces the hero-water.mp4 background. Every part of it is vector or plain
   CSS, so it is sharp at any pixel density instead of being a soft compressed
   video stretched over a full-height panel.

   The whole thing sits at z-index -3, beneath .auth__veil (-2), which is what
   keeps the headline and the trust list legible over it. Do not raise it.

   LAYOUT. The stage is a tall narrow column and the text owns its left half:
   the lockup at the top, the headline and paragraph through the middle, the
   trust chips along the bottom. So the art lives in the RIGHT half only, in two
   stacked pieces — the product above, the suite below it — and every position
   below is chosen to clear a specific piece of text. The first version put one
   very wide panel across the whole stage and it collided with the lockup at the
   top and was sliced through the middle of its own chart at the right edge,
   which read as a rendering bug rather than as a deliberate bleed.

   The bleed is still there, it is just soft now: .authviz carries a mask that
   dissolves its last few percent, so anything reaching the stage boundary fades
   out instead of being guillotined against a hard vertical line.

   THE MASK HAS TO REACH ZERO, AND IT HAS TO START EARLY. The first attempt
   ramped from solid at 90% to alpha .08 at 100%, and on the render the chart
   was still visibly sliced: .08 of a bright bar against a #04070C stage is not
   invisible, it is a faint bar with a hard vertical edge, and the eye reads
   that as a clipping bug rather than as depth. Ten percent of a 740px column
   is also only 74px, which is narrower than a single card in the panel, so
   there was no room for a gradient to read as a gradient. It now ends fully
   transparent, and .authviz__app is pulled in to 52% wide so what lands in
   the dissolve is the panel's outer margin rather than the tallest bars of
   its chart.

   THE MASK IS PER-BREAKPOINT, BECAUSE WHAT REACHES THE EDGE IS PER-BREAKPOINT.
   The mask lives on .authviz, so it falls on the icon grid as well as on the
   panel, and the grid is the thing that cannot survive it: a 2x3 grid whose
   right column is at a lower alpha than its left column does not read as
   depth, it reads as half a grid failing to draw. Two successive attempts
   proved that empirically. Starting the dissolve at 80% (592px on a 740px
   stage) cut between the grid's two columns — left at 554-622, right at
   638-707 — and took the right one to a quarter alpha. Moving it to 84%
   (622px) left the left column solid but still ramped the right one from .86
   down to .25 across its own width, and the render was visibly lopsided.

   So above 980px the dissolve is a 4% EDGE GUARD, not a composition device.
   Once .authviz__app was narrowed to left:46% + width:52%, it ends at 98% of
   the stage and never touches the boundary — there is no longer a guillotine
   to hide, and a long ramp was solving a problem that no longer existed while
   creating a new one. 96% sits exactly on the grid's own right edge (right:4%),
   so the grid is untouched and the last 30px still catches anything that grows.
   If .authviz__icons ever moves off right:4%, move this with it.

   BELOW 980px THE OPPOSITE IS TRUE. The panel goes to left:44% + width:80% and
   deliberately runs off the edge, and the icon grid is hidden, so nothing is
   left for a long ramp to damage: it opens up to 62%. Below 560px the panel is
   gone and the grid is pushed to right:-10% on purpose, so it fades from 74%.

   PERFORMANCE. One perspective, two transformed subtrees, no filters that
   force repaint, no animation after the entrance settles. It costs less than
   decoding a single frame of the video it replaced. */
.authviz{position:absolute;inset:0;z-index:-3;overflow:hidden;pointer-events:none;
  perspective:1700px;perspective-origin:62% 40%;
  -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 96%,rgba(0,0,0,0) 100%);
          mask-image:linear-gradient(90deg,#000 0%,#000 96%,rgba(0,0,0,0) 100%)}

/* top:4% clears nothing on its own — what keeps this off the lockup is left:46%,
   which starts the panel to the RIGHT of where "Dark Water / CLIENT PORTAL"
   ends. Do not widen it leftward without re-checking that. */
.authviz__app{position:absolute;top:4%;left:46%;width:min(640px,52%);aspect-ratio:16/10.2;
  border-radius:16px;overflow:hidden;transform-origin:0 40%;
  border:1px solid rgba(147,197,253,.30);
  background:linear-gradient(158deg,#0E1B2E 0%,#080F1C 62%,#04070C 100%);
  box-shadow:0 70px 150px -46px rgba(0,0,0,.95), 0 0 120px -30px rgba(0,119,255,.70);
  opacity:0;transform:rotateY(-22deg) rotateX(8deg) rotateZ(-2deg) translateX(28px);
  animation:authVizIn 2.4s var(--ease) .2s forwards}
@keyframes authVizIn{to{opacity:1;transform:rotateY(-19deg) rotateX(7deg) rotateZ(-2deg) translateX(0)}}

/* Everything inside the panel is one notch brighter than it first shipped. The
   art sits under a scrim AND behind a 3D rotation that foreshortens it, so
   alphas that look correct when you read the rule in isolation land visibly
   muddier on screen than the number suggests. Judge these from the render. */
.authviz__chrome{display:flex;align-items:center;gap:6px;height:26px;padding:0 12px;
  border-bottom:1px solid rgba(147,197,253,.16);background:rgba(255,255,255,.045)}
.authviz__chrome i{width:7px;height:7px;border-radius:50%;background:rgba(147,197,253,.38)}

.authviz__body{display:grid;grid-template-columns:26% 1fr;height:calc(100% - 26px)}
.authviz__side{padding:14px 12px;border-right:1px solid rgba(147,197,253,.16);
  background:rgba(4,8,16,.5);display:flex;flex-direction:column;gap:7px}
.authviz__brand{display:block;margin-bottom:8px}
/* height only — never both dimensions on the wide mark */
.authviz__brand img{width:auto;height:15px;display:block;opacity:1}
.authviz__side b{font-size:9.5px;font-weight:500;letter-spacing:.01em;color:rgba(201,213,228,.62);
  padding:4px 7px;border-radius:5px;white-space:nowrap}
.authviz__side b.is-on{color:#EAF2FF;background:rgba(0,119,255,.34);
  box-shadow:inset 0 0 0 1px rgba(59,158,255,.42)}

.authviz__main{padding:16px 16px 0;display:flex;flex-direction:column;gap:11px;overflow:hidden}
/* Blank geometry on purpose — see the note in login.php. A background image is
   not a licence to invent numbers. */
.authviz__title{height:9px;width:38%;border-radius:4px;background:rgba(234,242,255,.32)}
.authviz__cards{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.authviz__cards s{display:block;height:46px;border-radius:8px;text-decoration:none;
  border:1px solid rgba(147,197,253,.18);
  background:linear-gradient(160deg,rgba(255,255,255,.075),rgba(255,255,255,.02))}
.authviz__cards s:nth-child(1){box-shadow:inset 0 -18px 22px -18px rgba(0,119,255,.75)}
.authviz__cards s:nth-child(2){box-shadow:inset 0 -18px 22px -18px rgba(0,201,122,.65)}
.authviz__cards s:nth-child(3){box-shadow:inset 0 -18px 22px -18px rgba(212,175,55,.55)}

.authviz__chart{display:flex;align-items:flex-end;gap:5px;height:82px;padding:9px 10px;
  border-radius:9px;border:1px solid rgba(147,197,253,.18);
  background:linear-gradient(180deg,rgba(0,119,255,.12),transparent 78%)}
.authviz__chart u{flex:1;border-radius:3px 3px 1px 1px;text-decoration:none;
  background:linear-gradient(180deg,#5BAEFF,rgba(0,119,255,.42))}
/* A deterministic skyline. Hand-set rather than generated so the silhouette is
   a designed shape and not a random one that happens to look wrong. */
.authviz__chart u:nth-child(1){height:34%}
.authviz__chart u:nth-child(2){height:48%}
.authviz__chart u:nth-child(3){height:41%}
.authviz__chart u:nth-child(4){height:62%}
.authviz__chart u:nth-child(5){height:55%}
.authviz__chart u:nth-child(6){height:74%}
.authviz__chart u:nth-child(7){height:66%}
.authviz__chart u:nth-child(8){height:88%}
.authviz__chart u:nth-child(9){height:79%}
.authviz__chart u:nth-child(10){height:95%}
.authviz__chart u:nth-child(11){height:86%}
.authviz__chart u:nth-child(12){height:100%}

.authviz__list{display:flex;flex-direction:column;gap:7px}
.authviz__list s{display:block;height:18px;border-radius:6px;text-decoration:none;
  border:1px solid rgba(147,197,253,.14);background:rgba(255,255,255,.055)}

/* The official app icons — the six flagship products, the same .ostile component
   the marketing site uses, so there is one definition and one look everywhere.

   TWO COLUMNS, NOT THREE. A 3-wide cluster is 250px across and there is no
   250px-wide strip of this stage that is free of text: it either sits under the
   paragraph or under the trust chips. A 2x3 stack is 160px wide and fits in the
   channel between where the copy wraps and the right edge, which is the only
   empty column the layout actually has. Placed just under the panel it also
   reads correctly: the product, then the suite it belongs to. */
.authviz__icons{position:absolute;right:4%;top:40%;display:grid;
  grid-template-columns:repeat(2,clamp(48px,5vw,72px));gap:clamp(11px,1.2vw,16px);
  transform:rotateY(-19deg) rotateX(7deg) rotateZ(-2deg)}
.authviz__icons .ostile{width:100%;opacity:0;
  animation:authIconIn .9s var(--ease) forwards;
  box-shadow:0 22px 44px -18px rgba(0,0,0,.9), 0 0 34px -14px var(--acc,#0077FF)}
@keyframes authIconIn{from{opacity:0;transform:translateY(16px) scale(.9)}
                      to{opacity:1;transform:none}}
.authviz__icons .ostile:nth-child(1){animation-delay:.55s}
.authviz__icons .ostile:nth-child(2){animation-delay:.64s}
.authviz__icons .ostile:nth-child(3){animation-delay:.73s}
.authviz__icons .ostile:nth-child(4){animation-delay:.82s}
.authviz__icons .ostile:nth-child(5){animation-delay:.91s}
.authviz__icons .ostile:nth-child(6){animation-delay:1s}

@media (prefers-reduced-motion:reduce){
  .authviz__app,.authviz__icons .ostile{animation:none;opacity:.9;transform:none}
  .authviz__app{transform:rotateY(-19deg) rotateX(7deg) rotateZ(-2deg)}
}
/* THE SCRIM IS DIRECTIONAL, NOT A FLAT WASH.
   It was tuned against a bright video, so it darkened the entire panel evenly:
   .78 alpha at the top, .94 at the bottom. Drawn art is already dark and
   self-luminous, and that wash flattened it into mud — the dashboard was barely
   readable and the app icons looked like smudges.
   The scrim's only job is text legibility, and all the text is on the LEFT. So
   the horizontal ramp does the work: near-opaque under the copy column, almost
   clear over the art on the right. The vertical pass is kept but thinned, and
   it only protects the two bands that actually hold text — the lockup at the
   top and the trust chips at the bottom. */
.auth__veil{position:absolute;inset:0;z-index:-2;
  background:
    radial-gradient(92% 100% at 76% 2%, rgba(0,119,255,.24), transparent 58%),
    radial-gradient(70% 90% at 2% 96%, rgba(6,46,102,.58), transparent 72%),
    linear-gradient(100deg, rgba(4,7,12,.93) 0%, rgba(4,7,12,.74) 32%,
                            rgba(4,7,12,.28) 62%, rgba(4,7,12,.06) 100%),
    linear-gradient(180deg, rgba(4,7,12,.40) 0%, transparent 22%,
                            transparent 68%, rgba(4,7,12,.78) 100%)}
.auth__grid{position:absolute;inset:0;z-index:-2;opacity:0;animation:authFadeIn 1.9s var(--ease) .3s forwards;
  background-image:linear-gradient(rgba(59,158,255,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(59,158,255,.055) 1px,transparent 1px);
  background-size:62px 62px;
  -webkit-mask-image:radial-gradient(84% 78% at 58% 26%,#000 0%,transparent 76%);
          mask-image:radial-gradient(84% 78% at 58% 26%,#000 0%,transparent 76%)}
@keyframes authFadeIn{to{opacity:1}}
.auth__rays{position:absolute;inset:0;z-index:-2;overflow:hidden}
.auth__rays i{position:absolute;top:-34%;height:172%;width:min(220px,24vw);
  background:linear-gradient(180deg,rgba(59,158,255,.22),transparent 72%);
  filter:blur(32px);transform:skewX(-12deg);animation:phRay 18s ease-in-out infinite}
.auth__rays i:nth-child(1){left:8%}
.auth__rays i:nth-child(2){left:46%;animation-delay:-6s;animation-duration:22s}
.auth__rays i:nth-child(3){left:78%;animation-delay:-12s;animation-duration:20s}

.auth__lock{display:inline-flex;align-items:center;gap:.7rem;position:relative}
/* dw-icon.png is 1115x540 — a WIDE mark. This rule was `width:40px;height:40px`,
   which crushed a 2.06:1 logo into a 1:1 box; that is the squashed lockup on the
   sign-in page. Constrain the height and let the width follow, exactly as
   .brand__icon does in the site header. */
.auth__lock img{width:auto;height:32px;display:block}
.auth__lock b{font-family:var(--font-display);font-weight:700;letter-spacing:-.02em;font-size:1.05rem}
.auth__lock span{display:block;font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--text-mut);font-weight:600;margin-top:.1rem}

.auth__mid{position:relative;padding:clamp(26px,4vw,48px) 0}
.auth__mid h2{font-family:var(--font-display);font-weight:700;letter-spacing:-.035em;line-height:1.05;
  font-size:clamp(2rem,3.4vw,3.05rem);max-width:14ch;text-shadow:0 6px 40px rgba(0,0,0,.7)}
.auth__mid p{margin-top:1rem;max-width:46ch;color:#C9D5E4;font-size:clamp(.96rem,1.1vw,1.06rem)}

.auth__kpis{display:grid;grid-template-columns:repeat(3,auto);gap:clamp(18px,3vw,44px);
  margin-top:clamp(22px,3vw,38px);justify-content:start}
.auth__kpis div b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;
  font-size:clamp(1.5rem,2.4vw,2.05rem);
  background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent}
.auth__kpis div span{display:block;margin-top:.2rem;font-size:.64rem;letter-spacing:.11em;
  text-transform:uppercase;color:var(--text-mut);font-weight:600}

.auth__trust{position:relative;display:flex;flex-wrap:wrap;gap:.5rem .55rem}
.auth__trust li{display:inline-flex;align-items:center;gap:.42rem;padding:.42rem .74rem;border-radius:99px;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.10);
  font-size:.72rem;color:var(--text-soft);letter-spacing:.02em}
.auth__trust li svg{width:13px;height:13px;color:var(--brand-bright);flex:none}

/* ---------- right: the panel ---------- */
.auth__panel{position:relative;display:grid;place-items:center;
  padding:clamp(28px,4vw,58px) clamp(20px,3vw,44px);background:#05080F}
.auth__panel::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(90% 60% at 50% -6%,rgba(0,119,255,.16),transparent 62%)}
.authcard{position:relative;width:100%;max-width:430px}
.authcard__in{position:relative;border-radius:20px;padding:clamp(24px,2.6vw,34px);
  background:linear-gradient(168deg,rgba(14,19,28,.94),rgba(7,10,16,.90));
  border:1px solid rgba(255,255,255,.10);
  box-shadow:0 32px 90px rgba(0,0,0,.62),0 0 0 1px rgba(0,119,255,.10) inset;
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.authcard__in::after{content:"";position:absolute;left:0;right:0;top:0;height:1px;border-radius:20px 20px 0 0;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.75),transparent)}
.authcard__badge{display:inline-flex;align-items:center;gap:.45rem;padding:.34rem .72rem;border-radius:99px;
  background:rgba(0,119,255,.12);border:1px solid rgba(59,158,255,.30);
  font-size:.63rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:#9CC9FF}
.authcard__badge i{width:6px;height:6px;border-radius:50%;background:var(--brand-bright);
  box-shadow:0 0 0 0 rgba(59,158,255,.7);animation:livePulse 2.1s ease-out infinite}
.authcard h1{margin-top:.85rem;font-family:var(--font-display);font-weight:700;letter-spacing:-.032em;
  font-size:clamp(1.5rem,2.2vw,1.9rem);line-height:1.1}
.authcard__sub{margin-top:.5rem;color:var(--text-soft);font-size:.93rem}

.authf{margin-top:1.5rem}
.authf .field{margin-bottom:1rem}
.authf .field label{font-size:.76rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-mut);font-weight:700;margin-bottom:.42rem}
.authf .field input{padding:.86rem 1rem;border-radius:12px;background:rgba(255,255,255,.035);
  border:1px solid rgba(255,255,255,.12)}
.authf .field input::placeholder{color:#5C6B82}
.authf__wrap{position:relative}
.authf__wrap input{padding-right:3.1rem!important}
.authf__eye{position:absolute;right:.45rem;top:50%;transform:translateY(-50%);
  width:2.2rem;height:2.2rem;display:grid;place-items:center;border:0;border-radius:9px;
  background:transparent;color:var(--text-mut);transition:color .2s,background .2s}
.authf__eye:hover{color:#CFE4FF;background:rgba(255,255,255,.06)}
.authf__eye svg{width:17px;height:17px}
.authf__row{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  margin:.15rem 0 1.25rem}
.authf__rem{display:inline-flex;align-items:center;gap:.5rem;font-size:.84rem;color:var(--text-soft);
  cursor:pointer;user-select:none}
.authf__rem input{position:absolute;opacity:0;width:0;height:0;border:0}
/* Same geometry as the site-wide input[type=checkbox] rule near the top of this
   file — 22px, 6px radius, .22 border, .04 fill. This <s> predates that rule and
   was 17px, which made the remember-me box the one checkbox on the site that was
   a different size from every other one. There is no reason for two. */
.authf__rem s{width:22px;height:22px;border-radius:6px;text-decoration:none;flex:none;
  border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.04);
  display:grid;place-items:center;transition:background .2s,border-color .2s}
.authf__rem s::after{content:"";width:10px;height:5px;border-left:2px solid #fff;border-bottom:2px solid #fff;
  transform:rotate(-45deg) scale(0);transform-origin:center;transition:transform .2s var(--ease);
  margin-top:-2px}
.authf__rem input:checked + s{background:var(--brand);border-color:var(--brand)}
.authf__rem input:checked + s::after{transform:rotate(-45deg) scale(1)}
.authf__rem input:focus-visible + s{outline:2px solid var(--aqua);outline-offset:2px}
.authf__link{font-size:.84rem;color:var(--brand-bright);font-weight:600}
.authf__link:hover{text-decoration:underline}
.authf .btn--block{width:100%;justify-content:center}

.auth__err{display:flex;align-items:flex-start;gap:.6rem;margin-bottom:1rem;padding:.72rem .9rem;
  border-radius:12px;background:rgba(220,60,70,.10);border:1px solid rgba(220,60,70,.38);
  color:#FFB4B8;font-size:.87rem;line-height:1.45}
.auth__err svg{width:16px;height:16px;flex:none;margin-top:.15rem}
.auth__err[hidden]{display:none}

.auth__or{display:flex;align-items:center;gap:.85rem;margin:1.35rem 0 1.1rem;
  font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;color:var(--text-mut);font-weight:700}
.auth__or::before,.auth__or::after{content:"";flex:1;height:1px;background:rgba(255,255,255,.10)}

.auth__alt{display:grid;gap:.6rem}
.auth__alt a{display:flex;align-items:center;gap:.7rem;padding:.78rem .95rem;border-radius:13px;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.10);
  font-size:.88rem;color:var(--text-soft);font-weight:500;
  transition:border-color .25s,background .25s,transform .25s var(--ease)}
.auth__alt a:hover{border-color:rgba(59,158,255,.36);background:rgba(0,119,255,.07);
  transform:translateY(-2px);color:var(--text)}
.auth__alt a svg{width:17px;height:17px;color:var(--brand-bright);flex:none}
.auth__alt a b{color:var(--text);font-weight:600}
.auth__alt a em{font-style:normal;margin-left:auto;color:var(--brand-bright);font-size:1.05rem}

.authcard__fine{margin-top:1.2rem;text-align:center;font-size:.78rem;color:var(--text-mut);line-height:1.6}
.authcard__fine a{color:var(--brand-bright);font-weight:600}
.authcard__back{margin-top:1.35rem;text-align:center;font-size:.82rem}
.authcard__back a{color:var(--text-mut);display:inline-flex;align-items:center;gap:.4rem}
.authcard__back a:hover{color:var(--text)}

.authcode{letter-spacing:.55em;text-align:center;font-size:1.45rem!important;
  font-family:var(--font-display);font-weight:700;padding-right:1rem!important}

/* staged entrance — CSS-driven, so the form is never trapped behind JS */
.auth .aup{opacity:0;transform:translateY(22px);filter:blur(8px);
  animation:aupIn .9s var(--ease) forwards}
@keyframes aupIn{to{opacity:1;transform:none;filter:blur(0)}}

@media (max-width:980px){
  .auth{grid-template-columns:1fr}
  .auth__stage{border-right:0;border-bottom:1px solid var(--line);min-height:auto;
    padding:clamp(22px,5vw,34px)}
  .auth__mid{padding:clamp(20px,5vw,30px) 0}
  .auth__mid h2{max-width:18ch;font-size:clamp(1.75rem,6vw,2.4rem)}
  .auth__panel{padding:clamp(26px,7vw,44px) clamp(18px,5vw,30px)}
  /* The stage stops being a full-height column here and becomes a short band,
     so the panel is anchored to the bottom edge and allowed to run off it
     rather than being scaled down into an unreadable postage stamp. The icon
     cluster goes: at this width it lands on top of the trust list. */
  .authviz__app{top:auto;bottom:-18%;left:44%;width:min(640px,80%)}
  .authviz__icons{display:none}
  /* the panel really does run off the edge here, and the grid is gone, so the
     dissolve can be long enough to read as one */
  .authviz{-webkit-mask-image:linear-gradient(90deg,#000 0%,#000 62%,rgba(0,0,0,0) 100%);
                   mask-image:linear-gradient(90deg,#000 0%,#000 62%,rgba(0,0,0,0) 100%)}
  /* The directional scrim assumes a two-column page with all the text on the
     left. Here there is one column and the copy runs the full width, so the
     horizontal ramp would leave the right-hand half of every line sitting on
     bare art. Go back to an even wash for this breakpoint down. */
  .auth__veil{background:
    radial-gradient(92% 100% at 76% 2%, rgba(0,119,255,.24), transparent 58%),
    radial-gradient(70% 90% at 2% 96%, rgba(6,46,102,.58), transparent 72%),
    linear-gradient(180deg, rgba(4,7,12,.80) 0%, rgba(4,7,12,.52) 46%,
                            rgba(4,7,12,.92) 100%)}
}
@media (max-width:560px){
  .auth__kpis{grid-template-columns:repeat(3,1fr);gap:14px}
  .auth__kpis div b{font-size:1.28rem}
  .auth__mid p{font-size:.94rem}
  /* Portrait phone: 9.5px nav labels in a 3D-rotated panel are mush. Drop the
     dashboard and let the app icons carry the stage instead — they are pure
     geometry and read perfectly at any size. */
  .authviz__app{display:none}
  .authviz__icons{display:grid;right:-10%;bottom:auto;top:50%;
    grid-template-columns:repeat(3,58px);transform:translateY(-50%) rotateY(-16deg) rotateZ(-2deg)}
  .authviz__icons .ostile{box-shadow:none}
  .authviz{opacity:.5;
    -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 74%,rgba(0,0,0,0) 100%);
            mask-image:linear-gradient(90deg,#000 0%,#000 74%,rgba(0,0,0,0) 100%)}
  .authcard__in{padding:22px 18px}
  .authf__row{flex-wrap:wrap;gap:.6rem}
}
@media (prefers-reduced-motion:reduce){
  .auth__rays i{animation:none!important;opacity:.14}
  .auth__grid{opacity:1;animation:none!important}
  .auth .aup{opacity:1;transform:none;filter:none;animation:none!important}
  .authcard__badge i{animation:none!important}
}

/* ============================================================
   APP SHELL — MOBILE NAVIGATION v22 (2026-07-27)
   User: "make sure this website is responsive, and delivers same
          experience from any phone or screen"
   Below 900px the app pages (portal / admin / analytics /
   command-center) were dropping .app-side to display:none, which
   removed every navigation route AND the way back to the site.
   The sidebar now becomes a proper off-canvas drawer behind a
   sticky app bar. Same nav, same order, thumb-reachable.
   ============================================================ */
.appbar{display:none}

@media (max-width:900px){
  .appbar{position:sticky;top:0;z-index:60;display:flex;align-items:center;gap:.75rem;
    padding:.62rem clamp(14px,4vw,20px);
    background:rgba(6,9,14,.86);border-bottom:1px solid var(--line);
    -webkit-backdrop-filter:blur(16px) saturate(140%);backdrop-filter:blur(16px) saturate(140%)}
  .appbar__burger{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:11px;
    border:1px solid var(--hairline);background:rgba(255,255,255,.04);color:var(--text);
    transition:background .2s,border-color .2s}
  .appbar__burger:active{background:rgba(0,119,255,.16);border-color:rgba(59,158,255,.4)}
  .appbar__burger i{position:relative;display:block;width:17px;height:2px;border-radius:2px;background:currentColor;
    transition:transform .3s var(--ease),background .2s}
  .appbar__burger i::before,.appbar__burger i::after{content:"";position:absolute;left:0;width:17px;height:2px;
    border-radius:2px;background:currentColor;transition:transform .3s var(--ease),opacity .2s}
  .appbar__burger i::before{top:-6px}
  .appbar__burger i::after{top:6px}
  .app-shell.navopen .appbar__burger i{background:transparent}
  .app-shell.navopen .appbar__burger i::before{transform:translateY(6px) rotate(45deg)}
  .app-shell.navopen .appbar__burger i::after{transform:translateY(-6px) rotate(-45deg)}
  /* The DW mark is a 1115x540 horizontal monogram, so a 30x30 box squashed it
     to two-thirds of its width — the same distortion the rule at line 672
     already fixes for .brand__icon in the header and footer. Height leads,
     width follows. */
  .appbar__mark{width:auto;height:26px;max-width:64px;object-fit:contain;flex:none}
  .appbar__t{display:flex;flex-direction:column;line-height:1.15;min-width:0}
  .appbar__t b{font-family:var(--font-display);font-weight:700;letter-spacing:-.02em;font-size:.95rem;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .appbar__t span{font-size:.58rem;letter-spacing:.22em;text-transform:uppercase;color:var(--text-mut);font-weight:600}
  .appbar__out{margin-left:auto;flex:none;display:grid;place-items:center;width:40px;height:40px;border-radius:11px;
    border:1px solid var(--hairline);background:rgba(255,255,255,.04);color:var(--text-soft)}
  .appbar__out svg{width:17px;height:17px}

  /* the sidebar becomes a drawer instead of disappearing */
  .app-shell{grid-template-columns:1fr;position:relative}
  .app-side{display:flex!important;flex-direction:column;
    position:fixed;top:0;left:0;bottom:0;width:min(300px,84vw);height:100dvh;z-index:80;
    transform:translateX(-102%);transition:transform .38s var(--ease);
    box-shadow:0 0 60px rgba(0,0,0,.7);overscroll-behavior:contain}
  .app-shell.navopen .app-side{transform:none}
  .app-scrim{position:fixed;inset:0;z-index:70;background:rgba(2,4,8,.62);
    -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
    opacity:0;pointer-events:none;transition:opacity .32s}
  .app-shell.navopen .app-scrim{opacity:1;pointer-events:auto}
  .app-nav a{padding:.86rem .9rem;font-size:1rem}   /* thumb targets */
  .app-main{padding-top:clamp(16px,4vw,22px)}
  body.navlock{overflow:hidden}
}

@media (max-width:900px) and (prefers-reduced-motion:reduce){
  .app-side{transition:none}
  .app-scrim{transition:none}
}

/* app header block reads cleaner on a phone */
@media (max-width:640px){
  .app-top{flex-wrap:wrap;align-items:flex-start;gap:.75rem;margin-bottom:1.3rem}
  .app-top > .who{order:-1}
  .app-top h2{font-size:clamp(1.45rem,6.4vw,1.95rem);line-height:1.12}
}


/* ============================================================
   RESPONSIVE TABLES v23 (2026-07-27)
   User: "make sure this website is responsive, and delivers same
          experience from any phone or screen"
   table.data lives inside .panel on portal / admin / analytics /
   command-center / tools. On a phone the trailing columns were
   simply cut off at the panel edge — the data existed but could
   not be reached. Below 760px the table becomes its own scroll
   region so every column stays readable, with a fade on the right
   edge so it reads as scrollable rather than broken.
   ============================================================ */
@media (max-width:760px){
  .panel:has(> table.data){position:relative}
  .panel:has(> table.data)::after{content:"";position:absolute;top:0;right:0;bottom:0;width:34px;
    pointer-events:none;border-radius:0 inherit inherit 0;
    background:linear-gradient(90deg,rgba(6,9,14,0),rgba(6,9,14,.92))}
  table.data{display:block;width:100%;overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;scrollbar-width:thin}
  table.data thead,table.data tbody{display:table;width:max-content;min-width:100%}
  table.data th,table.data td{white-space:nowrap}
  table.data td:first-child,table.data th:first-child{padding-left:0}
}

/* ============================================================
   APP SPLIT GRID v24 (2026-07-27)
   User: "make sure this website is responsive, and delivers same
          experience from any phone or screen"
   admin.html / analytics.html carried the column ratio in an inline
   style="grid-template-columns:1.6fr 1fr". An inline declaration
   outranks every media query, so those two-up panel rows stayed
   two-up at 390px — a data table was rendering 113px wide inside a
   163px panel. The ratio now travels as a custom property (--split),
   which media queries CAN override because they set the property,
   not the variable.
   ============================================================ */
.app-split{grid-template-columns:var(--split,1fr 1fr)}
@media (max-width:1000px){.app-split{grid-template-columns:1fr}}

/* ============================================================
   NARROW-SCREEN FIT v25 (2026-07-27)
   User: "make sure this website is responsive, and delivers same
          experience from any phone or screen"
   The 320px audit (iPhone SE / folded devices) found one bug class
   repeated on 40+ pages, not 40 separate bugs:

   1. .btn is white-space:nowrap. A long label ("Request an
      Infrastructure Review", "Turn This Into a Real Proposal") then
      has a min-content width larger than the viewport, stretches its
      parent block, and drags every sibling — eyebrow, h2, lead —
      off the right edge with it. The button was never the only thing
      broken; it was the thing breaking everything else.
   2. The header brand (58px icon + 158px wordmark) plus the actions
      cluster needs 346px of the 280px available at 320.
   3. Grid/flex children default to min-width:auto, so one wide child
      blows out the whole track instead of shrinking.
   ============================================================ */

/* --- 1. buttons wrap instead of blowing out the line box --------- */
@media (max-width:560px){
  .btn,.nav__actions .btn,.nav__signin{white-space:normal;text-align:center;
    line-height:1.25;hyphens:none;overflow-wrap:break-word}
  .btn--lg{padding-left:1.15rem;padding-right:1.15rem}
  .btn-row,.flex.btn-row{flex-direction:column;align-items:stretch}
  .btn-row .btn{width:100%}
}

/* --- 2. header fits a 320px viewport ---------------------------- */
@media (max-width:400px){
  .nav{gap:.6rem}
  .brand{gap:.5rem;min-width:0}
  .brand__icon{width:44px;height:44px}
  .brand__text{font-size:.82em;min-width:0;overflow:hidden;text-overflow:ellipsis}
  .nav__actions{padding-left:.5rem;gap:.4rem}
  .nav__actions::before{display:none}
  .theme-toggle,.menu-toggle{width:40px;height:40px}
}

/* --- 3. no grid/flex child may widen its own track --------------- */
.app-shell>*,.app-main{min-width:0}
.grid>*,.kpi-grid>*,.cc-grid>*,.app-top>*{min-width:0}

/* --- 4. the ledger builds from the left; on a phone a 72px slide
       starts the copy off-screen. Shorten the travel, keep the move. */
@media (max-width:640px){
  .ledger .ledger__copy>*{transform:translateX(-28px)}
}


/* --- 5. the 4-up stat band. `repeat(2,1fr)` still lets a track grow
       past its share, because a grid child's min-width defaults to
       auto — so a wide display number ("+$842K" is 148px at 33.6px
       type) pushed the whole band 59px past a 320px viewport on
       case-study.html. minmax(0,1fr) caps the track; the type step
       makes the number actually fit inside it. */
.stats{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:680px){.stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:400px){
  .stats{gap:.75rem}
  .stat b{font-size:1.6rem}
  .stat span{font-size:.78rem}
}
/* --- 5b. a stat band is read across, so the labels have to sit on one line.
       The band is four independent cells, and each one is as tall as its own
       number, so the moment one value wraps its label drops away from the
       other three. Measured on about.html at 1440: "WCAG 2.2" needed 284px of
       a 252px content box, broke to two lines, and left "AA Build Target"
       85px below its neighbours — four numbers with three labels level and
       one adrift. sensory.html carried the identical band and the identical
       84px skew. Both were reworded so the value fits on one line, but the
       band should not depend on nobody ever writing a long number again.
       Each cell becomes a two-row subgrid, so every value in a row shares one
       track and every label shares the next. A value that wraps now lifts its
       neighbours' track with it and the labels stay level.
       @supports because the honest fallback without subgrid is exactly
       today's behaviour, not a broken one. */
@supports (grid-template-rows:subgrid){
  .stats>.stat, .hero__stats>.stat, .proof__kpis>.stat{
    display:grid; grid-template-rows:subgrid; grid-row:span 2;
    align-content:start; row-gap:.4rem
  }
}


/* --- 6. the retainer row on pricing.html is `.grid.cols-4`, which stays
       4-up until 980px. At 1024 that is a 214px track, and
       "$10,000+/mo" at 2.4rem has a 236px min-content with no break
       opportunity in it — so the widest plan pushed .container 12px
       past the viewport. The type ramps down only inside the 4-up
       band; at 1241+ it is still 2.4rem, and below 981 the grid goes
       2-up and gets the full size back. */
@media (min-width:981px) and (max-width:1240px){
  .plan .price{font-size:clamp(1.7rem,3.1vw,2.4rem)}
}


/* --- 7. the header bar. `@media(max-width:1200px)` hands 1200-and-down to
       the burger, so the full desktop nav switches on at 1201px — but the
       bar needs 1224.8px of content width (brand 227 + links 617 +
       actions 352 + two 14.4 gaps) and a 1201px viewport only offers
       1105 inside the container's 48px gutters. Result: the "Start a
       Project" CTA landed at x=1272 on EVERY page from 1201px to 1274px
       (sw=1272), which is exactly where a 1280x800 laptop with a
       scrollbar reports (~1265 CSS px).

       Two moves, no hamburger — a burger at 1250px on a laptop is a
       worse experience than a tighter bar:

       (a) Remove slack, not legibility. Both nav gaps drop to .6rem, the
           inter-link gap goes to 0 (the links already carry .55rem of
           their own padding), the actions divider inset and button side
           padding tighten a hair, and the brand tracking eases from
           .16em to .12em. Type size is untouched. That reclaims ~60px
           and, as a side effect, finally fits the bar INSIDE the 1184px
           container content box — before this the actions block always
           overhung the content edge (by 81px at 1440, 100px at 1600), so
           the header CTA never lined up with the page beneath it. The
           1561+ step carries the same treatment past the old
           `max-width:1560px` laptop rule so the bar is now pixel-
           identical and content-aligned from 1201px to 2560px.

       (b) In the 1201-1274 band that still is not enough (60px reclaimed,
           120px needed), drop the secondary "Dashboard" button only.
           It costs nothing: login.html is already in the Platform
           dropdown as "Client Portal" and twice in the footer, and the
           same button is already hidden on every screen 1200 and below.
           The primary CTA and all eight nav links stay. */
@media (min-width:1201px){
  .nav{gap:.6rem}
  .nav__links{gap:0}
  .nav__actions{padding-left:.85rem;gap:.55rem}
  .nav__actions .btn{padding-left:1.1rem;padding-right:1.1rem}
  .brand__name{letter-spacing:.12em}
}
@media (min-width:1561px){
  .nav__links a{padding:.5rem .55rem;font-size:.88rem}
  .brand__name{font-size:1.1rem}
}
@media (min-width:1201px) and (max-width:1274px){
  .nav__actions .btn--callnav{display:none}
}

/* ============================================================
   QUAD → PROOF BREATHING v26 (2026-07-27)
   User: "there should be a little space between 4 squares and
   the next revenue section, too tight."

   The proof deck is not a separate section — it is the fifth,
   full-width tile INSIDE `.quad__grid` (see the PROOF DECK
   relocated rule), so `main > section + section` breathing never
   applied to it and the only separation was the grid's own 12px
   `gap`. Raising the grid gap would also push the 2x2 tiles
   apart, and that tight 12px plate seam is the Apple-grid look
   he approved — so the space is bought on the proof item alone
   via `margin-top`, which stacks on top of the gap (12px + this)
   and leaves every other seam in the section untouched.
   ~40px on a desktop, ~30px on a laptop, 24px on phones where
   the grid is single-column and vertical rhythm is already long.
   ============================================================ */
.quad__grid .proof{margin-top:clamp(18px,2.2vw,30px)}
@media(max-width:860px){.quad__grid .proof{margin-top:12px}}

/* ============================================================
   MARK LIGHT — INSIDE THE SILHOUETTE, ONE PASS  v28 (2026-07-27)
   User: "the logo glow should have only been logo, and loads
   once, you see the white square around the effect, looks
   cheap, it needs to be invisible to the eye except inside
   the logo."

   ROOT CAUSE of the white square. This is a CSS ordering rule,
   not a tuning problem: the browser applies `filter` FIRST and
   `mask` AFTER, and a mask clips to the element's mask box,
   which is a RECTANGLE. The v15 pass layers carried their light
   in big filters -- drop-shadow(0 0 90px ...) on `.markpass`,
   blur(17px) on `.markpass--bloom` -- so the glow spilled far
   past the image box and was then sliced dead straight at the
   box edge. Measured on the shipped file: at the crossing the
   luminance ran 22 at x=1035 and 9 at x=1036, which is exactly
   `.markwrap`'s right edge, and that step ran the full height of
   the box. A hard vertical line that tracks the light as it
   travels is what he is calling the white square. Softening the
   gradient can never fix it, because the clip is a box, so the
   artifact is always a rectangle.

   REJECTED FIX (v27, measured and thrown out -- do not retry):
   inflating the mask box with `inset:-44px` + `padding:44px` so
   the clip edge lands where the light is already zero. It does
   not work here. `img` inherits `max-width:100%`, so the box
   never widened -- measured 792.8px both before and after -- it
   just translated 44px up and left, and the pass art came out
   704x341 at a 44px offset from an 792x384 base. The pass MUST
   stay registered 1:1 with the base mark or the light slides off
   the strokes.

   THE FIX: composite two mask layers and intersect them.
   Layer 2 is the travelling band. Layer 1 is dw-icon.png itself,
   so the mask is the logo's own alpha channel. `mask-composite:
   intersect` means a pixel only paints where BOTH are opaque --
   inside the silhouette AND inside the band. Light physically
   cannot land outside the logo at any blur radius, so there is
   no rectangle to see and nothing to tune. That is literally his
   requirement: invisible to the eye except inside the logo.
   Layer 1 uses `mask-size:contain` + `mask-position:center`,
   the same fit the `object-fit:contain` art resolves to, so mask
   and art agree to the pixel.

   Registration, which took three tries to get right at every
   width. The pass box must BE the base mark's box, so
   `inset:.6rem 0 auto` + `height:calc(100% - 2.6rem)` mirrors the
   base's own `margin:.6rem 0 2rem` against the wrapper. (v15 used
   `inset:0`, which is the wrapper box, and rode 11px low. And the
   inset/`width:auto` pair alone does not stretch a replaced
   element: with left and right both set and width auto, an abs
   positioned `img` takes its INTRINSIC width and the browser
   drops `right` as over-constrained -- hence the explicit width
   and height here.)

   The base mark also had to stop distorting. It was
   `height:clamp(232px,30vw,392px)` with width auto, and under
   ~480px of container the inherited `max-width:100%` clamped the
   width while the explicit height stood its ground -- so on a
   390px phone the mark rendered 390x232, a ratio of 1.68 against
   the art's 2.065. The logo was squashed 23% tall on every phone.
   That predates this round and breaks the rule that the mark is
   never distorted, and it also broke the light, because the pass
   art and the mask both resolve through `contain` and therefore
   letterbox inside a box whose ratio has been bent.
   The fix caps the requested height by what the viewport can
   actually give the width:
   `height:min(clamp(232px,30vw,392px),calc(100vw * 540 / 1115))`.
   The clamp is untouched wherever it already fit, so every width
   from 480 up is byte-identical; below that the second term takes
   over and the mark scales down in ratio instead of squashing
   (390 now renders 390x188, 320 renders 320x155).
   Driving it from the other side, `width:min(100%,calc(...))`,
   was tried first and rejected: a percentage width on the child
   of a shrink-to-fit inline-block makes `.markwrap` stop hugging
   the mark -- it jumped to the full 880px container at 1440 while
   the mark stayed 809 -- which breaks the pass box all over
   again.
   It also matters for the light: the mask and
   the pass art both resolve through `contain`, so once the base
   box carries the art's own ratio, mask, pass and base agree to
   the pixel at every width instead of only on desktop.

   Light budget. The sharp pass carries NO filter at all -- it is
   the same PNG at pure #fff over a base held at brightness(.90),
   so the slice reads brighter than the mark it crosses with no
   emitted halo whatsoever (the v11/v15 lesson: white cannot be
   made whiter, contrast against the satin base is what reads).
   The bloom copy blurs 9px so the light feathers ALONG the
   strokes; the alpha mask then trims that spill back to the
   silhouette, so its only visible boundary is the logo's own
   edge. The mark's arrive-and-stay glow stays a real halo --
   it is unmasked, so it cannot produce a box -- but tightens
   from 42px/104px to 18px/40px so the hero reads as a lit logo
   rather than a lit background ("not the glow starting in
   background").

   One crossing, and it LINGERS. v15 ran `markpass15 ...
   infinite`, sweeping every 8s forever. Now a single
   `1`-iteration run with `both`, resting at mask-position -6%,
   where the band sits 491px clear of the art -- past even the
   bloom band's 443px reach -- and paints nothing.
   Pacing was measured, not guessed. The first cut travelled
   106%->-6% on cubic-bezier(.42,0,.55,1), and frames showed the
   sharp band on the mark only from ~2.9s to ~4.1s: an ease-in-out
   sprints through its middle, which is where the whole effect
   lives, so 2/3 of the run was the band sitting off the artwork.
   Two changes. The travel starts at 96% instead of 106%, which
   removes dead approach while still beginning clear of the art
   (the band's own half-reach is ~246px and it starts 333px out).
   And the timing function is inverted to an S that is fast at
   both ends and slow in the middle -- cubic-bezier(.12,.42,.88,.58)
   -- so the light arrives quickly, crosses the mark slowly, and
   leaves quickly. Contact now runs about 2.3s of the 3.6s.

   -webkit-mask-* is declared BEFORE the standard properties on
   purpose: in current Chrome the webkit names are aliases of the
   standard ones, so the standard declaration must come last and
   win, while old Safari still gets a working legacy path.

   The mask is an inlined alpha-only data URL, defined once as
   --dw-markmask and referenced four times, for two reasons: a
   mask-image loaded from file:// is blocked by CORS ("Cross
   origin requests are only supported for protocol schemes...")
   and a mask layer that fails to load composites as transparent
   black, which under `intersect` would silently erase the whole
   effect -- so a plain path would have left the light working on
   the live host and dead in the single-file preview and in any
   folder opened locally. It also costs one fewer request on a
   file that renders in the first paint.
   ============================================================ */
:root{--dw-markmask:url("data:image/png;base64,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")}
.hero__brandmark--mono{animation:markGlowIn28 4.4s ease-out 1.5s both}
@keyframes markGlowIn28{
  0%{filter:brightness(.80)}
  12%{filter:drop-shadow(0 0 7px rgba(255,255,255,.16)) brightness(.82)}
  48%{filter:drop-shadow(0 0 22px rgba(255,255,255,.44)) drop-shadow(0 0 52px rgba(0,119,255,.42)) brightness(.96)}
  100%{filter:drop-shadow(0 0 18px rgba(255,255,255,.32)) drop-shadow(0 0 40px rgba(0,119,255,.36)) brightness(.90)}
}
@media (prefers-reduced-motion:reduce){
  .hero__brandmark--mono{animation:none;
    filter:drop-shadow(0 0 18px rgba(255,255,255,.32)) drop-shadow(0 0 40px rgba(0,119,255,.36)) brightness(.90)}
}
.hero__brandmark--mono{height:min(clamp(232px,30vw,392px),calc(100vw * 540 / 1115));width:auto}
.markpass{
  inset:.6rem 0 auto;width:100%;height:calc(100% - 2.6rem);padding:0;opacity:1;filter:none;
  -webkit-mask-image:var(--dw-markmask),linear-gradient(102deg,transparent 40%,#000 50%,transparent 60%);
  -webkit-mask-size:contain,300% 100%;
  -webkit-mask-position:center,96% 0;
  -webkit-mask-repeat:no-repeat,no-repeat;
  -webkit-mask-composite:source-in;
          mask-image:var(--dw-markmask),linear-gradient(102deg,transparent 40%,#000 50%,transparent 60%);
          mask-size:contain,300% 100%;
          mask-position:center,96% 0;
          mask-repeat:no-repeat,no-repeat;
          mask-composite:intersect;
  animation:markpass28 3.6s cubic-bezier(.12,.42,.88,.58) 1.7s 1 both}
.markpass--bloom{
  filter:blur(9px) brightness(1.4) saturate(.9);
  -webkit-mask-image:var(--dw-markmask),linear-gradient(102deg,transparent 32%,#000 50%,transparent 68%);
          mask-image:var(--dw-markmask),linear-gradient(102deg,transparent 32%,#000 50%,transparent 68%);
  animation:markpass28 3.6s cubic-bezier(.12,.42,.88,.58) 1.7s 1 both}
@keyframes markpass28{
  0%{-webkit-mask-position:center,96% 0;mask-position:center,96% 0}
  100%{-webkit-mask-position:center,-6% 0;mask-position:center,-6% 0}}
@media (prefers-reduced-motion:reduce){.markpass{display:none}}
/* If a browser can mask but cannot COMPOSITE masks, the two layers
   fall back to `add` -- a union -- and the band would paint as a
   full rectangle outside the logo, which is the exact defect this
   block exists to remove. Better to ship no sweep than a cheap
   one, so the pass layers hide themselves and the mark keeps its
   arrive-and-stay glow. (Chrome 120+, Safari 15.4+ and FF 53+ take
   the standard path; older Safari takes -webkit-mask-composite.) */
@supports not ((mask-composite:intersect) or (-webkit-mask-composite:source-in)){
  .markpass{display:none}
}

/* ============================================================================
   DARK WATER OS — PRICING EXPERIENCE  v29   (2026-07-27)
   ============================================================================
   Brief: "Completely replace the existing pricing section. Do NOT create
   another generic pricing table. This section should completely reposition
   Dark Water Ventures Inc. from a web design agency into a premium software
   company. The user should leave believing they are purchasing an Operating
   System for their business, not a website."
   And: "USE THIS TO SHOW ALL PACKAGES, PREMIUM PREMIUM, MUST BE FULLY ACCURATE."

   ARCHITECTURE
   · Every price rendered by these classes is generated from /plans.py. No
     price is ever typed by hand into a template, so the homepage band and
     pricing.html cannot drift apart.
   · The reference component the client supplied was React + shadcn/ui +
     Tailwind + TypeScript, none of which this site has and none of which it
     is getting (no build step). Its STRUCTURE is ported 1:1 — floating
     "Most Popular" pill above the table, bottom-aligned name/price header
     cells, full-height tinted recommended column, uppercase group bands,
     square check/cross cells, CTA row inside the table body, sticky head —
     and translated into the Dark Water dark-blue surface.
   · Monthly/annual switching is CSS-only: both figures ship in the markup
     and `.is-annual` on the [data-osbill] ancestor swaps which is visible.
     No JS arithmetic to drift, no flash of the wrong number.
   · Scroll choreography is driven by ONE custom property per stage
     (`--sp`, or `--p1..--p4` on the merge stage) written by
     assets/js/os-pricing.js inside a rAF. Everything else is pure CSS
     transform/opacity, so the whole experience composites on the GPU.

   SCOPING LAW
   Every class in this block is prefixed (oshero/osfl/oschaos/osmerge/osbill/
   osp/osmx/osrep/osgrow/oswhy/oskick). App-style pages (portal, admin,
   analytics, command-center) carry their own local <style> blocks; the v16
   `.ring` collision happened because a versioned block introduced a generic
   name. It does not happen again.

   PALETTE LAW
   Blue family only: #0077FF #3B9EFF #0A80FF #0A5FCC #062E66 #9CC9FF.
   No cyan, no teal, no purple, no orange.
   ========================================================================== */

/* ---------------------------------------------------------------- shared */
.os-sec{position:relative;isolation:isolate}
.os-h{font-family:var(--font-display);font-weight:700;letter-spacing:-.035em;line-height:1.02;color:#fff}
.os-h--xl{font-size:clamp(2.6rem,6.4vw,5.4rem)}
.os-h--lg{font-size:clamp(2.1rem,4.6vw,3.9rem)}
.os-h--md{font-size:clamp(1.7rem,3.2vw,2.7rem)}
.os-sub{font-size:clamp(1.02rem,1.35vw,1.28rem);line-height:1.62;color:var(--text-soft);font-weight:400}
.os-eye{display:inline-flex;align-items:center;gap:.6rem;font-size:.7rem;font-weight:700;letter-spacing:.3em;
  text-transform:uppercase;color:var(--aqua-soft);padding:.42rem .95rem;border-radius:999px;
  border:1px solid rgba(59,158,255,.24);background:rgba(0,119,255,.07);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.os-eye i{width:6px;height:6px;border-radius:50%;background:var(--aqua-bright);
  box-shadow:0 0 12px 2px rgba(59,158,255,.75);flex:none}
.os-wrap{width:100%;max-width:1240px;margin-inline:auto;padding-inline:clamp(20px,4vw,48px)}
.os-narrow{max-width:920px;margin-inline:auto}

/* =============================================================== SECTION 1
   HERO — "Stop Paying For Software. Start Running Your Business."
   Software wordmarks float upward and fade as the page scrolls.
   ======================================================================== */
.oshero{position:relative;overflow:hidden;isolation:isolate;
  padding:clamp(104px,15vh,180px) 0 clamp(72px,9vw,128px);text-align:center}
.oshero__glow{position:absolute;inset:-20% -10% auto;height:130%;z-index:-2;pointer-events:none;
  background:
    radial-gradient(58% 44% at 50% 8%, rgba(0,119,255,.30), transparent 68%),
    radial-gradient(40% 34% at 14% 44%, rgba(59,158,255,.16), transparent 70%),
    radial-gradient(46% 38% at 88% 30%, rgba(10,95,204,.20), transparent 72%)}
.oshero__grid{position:absolute;inset:0;z-index:-2;pointer-events:none;opacity:.4;
  background-image:linear-gradient(rgba(59,158,255,.055) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(59,158,255,.055) 1px,transparent 1px);
  background-size:76px 76px;
  -webkit-mask-image:radial-gradient(70% 58% at 50% 34%,#000 12%,transparent 76%);
          mask-image:radial-gradient(70% 58% at 50% 34%,#000 12%,transparent 76%)}
.oshero__float{position:absolute;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.osfl{position:absolute;font-family:var(--font-display);font-weight:600;white-space:nowrap;
  font-size:clamp(.72rem,1vw,.94rem);letter-spacing:-.005em;color:rgba(174,187,208,.5);
  padding:.5rem .95rem;border-radius:12px;border:1px solid rgba(255,255,255,.07);
  background:rgba(255,255,255,.028);-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);
  will-change:transform,opacity;
  transform:translate3d(0,calc(var(--sp,0) * var(--rise,-260px)),0);
  opacity:calc((1 - var(--sp,0) * 1.55) * var(--o,.85))}
.osfl--a{animation:osdrift 13s var(--ease) infinite alternate}
.osfl--b{animation:osdrift 17s var(--ease) infinite alternate-reverse}
@keyframes osdrift{from{margin-top:0}to{margin-top:-14px}}
.oshero__badge{margin-bottom:clamp(20px,2.4vw,30px)}
.oshero h1{margin:0 auto;max-width:15.5em}
.oshero h1 span{display:block}
.oshero h1 .oshero__l2{background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.oshero__sub{margin:clamp(20px,2.4vw,30px) auto 0;max-width:44em}
.oshero__cta{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin-top:clamp(26px,3vw,40px)}
.oshero__trust{display:flex;flex-wrap:wrap;gap:8px 26px;justify-content:center;margin-top:clamp(26px,3vw,40px);
  font-size:.82rem;color:var(--text-mut)}
.oshero__trust span{display:inline-flex;align-items:center;gap:.5rem}
.oshero__trust svg{width:15px;height:15px;color:var(--aqua-bright);flex:none}

/* =============================================================== SECTION 2
   "You're Probably Paying For This Already." — TWENTY-FOUR cards that drift
   apart into visual chaos as you scroll. 24 Companies. 24 Bills. 24 Logins.

   The tally is generated from STACK_COUNT in plans.py, so the headline can
   never disagree with the number of cards. What this block owns is making two
   dozen line items read as an overwhelming pile rather than a list: six columns
   of four rows reads as a bill stack, four columns of six rows reads as a
   spreadsheet. The stage widens to 1240px to buy the extra two columns.
   ======================================================================== */
.oschaos{padding-block:clamp(80px,11vw,150px);text-align:center;overflow:hidden}
.oschaos__head{margin-bottom:clamp(40px,5vw,66px)}
.oschaos__stage{position:relative;max-width:1240px;margin-inline:auto}
.oschaos__grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:clamp(10px,1.15vw,16px)}
.oscd{position:relative;padding:clamp(14px,1.5vw,20px) clamp(12px,1.4vw,18px);border-radius:16px;
  border:1px solid rgba(255,255,255,.075);background:rgba(255,255,255,.032);
  -webkit-backdrop-filter:blur(16px) saturate(130%);backdrop-filter:blur(16px) saturate(130%);
  text-align:left;will-change:transform,opacity;
  box-shadow:0 14px 40px rgba(0,0,0,.34);
  transition:border-color .4s var(--ease),background .4s var(--ease),box-shadow .4s var(--ease);
  transform:translate3d(calc(var(--dx,0px) * var(--sp,0)),calc(var(--dy,0px) * var(--sp,0)),0)
            rotate(calc(var(--rot,0deg) * var(--sp,0)))
            scale(calc(1 + var(--sp,0) * .04))}
.oscd:hover{border-color:rgba(59,158,255,.28);background:rgba(0,119,255,.055);
  box-shadow:0 22px 60px rgba(0,0,0,.44),0 0 0 1px rgba(59,158,255,.14)}
.oscd__cat{display:block;font-size:.62rem;font-weight:700;letter-spacing:.22em;text-transform:uppercase;
  color:var(--aqua-soft);opacity:.78;margin-bottom:.5rem}
.oscd__name{display:block;font-family:var(--font-display);font-weight:700;font-size:clamp(.95rem,1.15vw,1.1rem);
  color:#fff;letter-spacing:-.02em;line-height:1.2}
.oscd__alt{display:block;margin-top:.34rem;font-size:.72rem;line-height:1.45;color:var(--text-mut)}
.oscd__bill{position:absolute;top:12px;right:12px;font-size:.6rem;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(174,187,208,.42)}
.oschaos__tally{margin-top:clamp(40px,5vw,68px)}
.oschaos__tally b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;
  font-size:clamp(1.6rem,3.6vw,2.9rem);color:#fff;line-height:1.14}
.oschaos__tally b em{font-style:normal;background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.oschaos__tally p{margin-top:.8rem;color:var(--text-mut);font-size:.96rem}

/* =============================================================== SECTION 3
   THE MERGE — every card is sucked into a vortex, compressed into one glowing
   Dark Water cube, the cube resolves into the official app tile, the flagship
   six bloom out of it, then:
   One Login. One Bill. One Partner.
   "This should be one of the most satisfying animations on the website."

   THE CSS <-> JS CONTRACT for this section (os-pricing.js owns the other half):
     .osmerge__stage  --p1 --p2 --p3 --p5 --p4   five overlapping smoothstep
                                                 stages driven by one rAF
     .osch            --sx --sy --sr --spin --pd --pdk   seat + vortex + stagger
     .oscube__f       --cz
     .osbl            --acc --bx --by --bd --bdk         written by the generator
     [data-oscount]   textContent
   Nothing here animates anything but transform, opacity and filter.

   WHY THE STAGES OVERLAP. Read the ramps as one gesture, not five: the vortex
   (p1) is still tightening while the cube is already forming (p2), the cube is
   still turning as it resolves into the tile (p3), and the tile is still there
   when the six products bloom out of it (p5) and the copy lands (p4). Gaps
   between stages read as stalls.
   ======================================================================== */
.osmerge{position:relative;height:460vh}
.osmerge__stage{position:sticky;top:0;height:100vh;display:grid;place-items:center;overflow:hidden}

/* The aura is two layers: a base radial that brightens with the collapse, and a
   conic swirl that only exists while the vortex is pulling — it is what sells
   the suction as rotation rather than a simple scale-down. Radially masked so it
   never shows a hard conic seam against the page edge. */
.osmerge__aura{position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(46% 46% at 50% 50%, rgba(0,119,255,calc(.06 + var(--p1,0)*.14 + var(--p2,0)*.34)), transparent 72%);
  opacity:calc(.2 + var(--p1,0)*.36 + var(--p2,0)*.54)}
.osmerge__aura::after{content:"";position:absolute;inset:-25%;
  /* Three lobes at 120deg spacing, transparent at both 0 and 360 so the wrap is
     seamless. The old stops sat at 60 / 210 / 350 — spacings of 150, 140 and 70
     degrees — which put two lobes almost on top of each other and left an 80
     degree dead arc opposite them. Because the whole layer rotates, that dead
     arc swept slowly across the stage and the aura read as lit on one side and
     switched off on the other. Even spacing is the entire fix. */
  background:conic-gradient(from 0deg,transparent 0deg,rgba(59,158,255,.20) 60deg,transparent 120deg,
             rgba(0,119,255,.18) 180deg,transparent 240deg,rgba(59,158,255,.20) 300deg,transparent 360deg);
  -webkit-mask-image:radial-gradient(closest-side,#000 12%,rgba(0,0,0,.55) 46%,transparent 74%);
          mask-image:radial-gradient(closest-side,#000 12%,rgba(0,0,0,.55) 46%,transparent 74%);
  transform:rotate(calc(var(--p1,0)*140deg + var(--p2,0)*220deg));
  opacity:calc(min(var(--p1,0)*1.6,1) * max(0,1 - var(--p3,0)*1.3));
  will-change:transform,opacity}
.osmerge__inner{position:relative;z-index:1;display:grid;place-items:center;width:100%;height:100%;
  perspective:1400px;perspective-origin:50% 46%}

/* ---- the twenty-four chips, sucked into a vortex -------------------------
   THE VORTEX TRICK. transform functions compose left to right, so a leading
   rotate() rotates the *offset vector* that follows it: the chip does not just
   travel inward, it arcs. Scaling that leading angle by the chip's own progress
   turns a straight collapse into a spiral, with no trigonometry anywhere. The
   inner band gets a larger --spin than the outer so the two rings shear past
   each other instead of moving as one rigid disc.

   THE STAGGER. --q is this chip's own progress: p1 shifted by its --pd delay and
   renormalised so every chip still finishes exactly at p1 = 1. JS precomputes
   --pdk = 1/(1 - pd) and CSS MULTIPLIES by it, because dividing by a calc() that
   resolves to a plain number is unreliable in Chrome. Never divide here.

   THE PERF TRADE. backdrop-filter is gone from this rule on purpose. One
   backdrop-filter is cheap; twenty-four of them compositing over a live conic
   gradient while each also carries a blur() filter is not. A flat translucent
   ink background is indistinguishable at this scale and costs nothing, which is
   what buys the motion blur below. */
.osmerge__swarm{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}
.osch{--q:clamp(0, calc((var(--p1,0) - var(--pd,0)) * var(--pdk,1)), 1);
  position:absolute;padding:.48rem .88rem;border-radius:12px;font-family:var(--font-display);
  font-weight:600;font-size:clamp(.66rem,.86vw,.84rem);white-space:nowrap;color:var(--text-soft);
  border:1px solid rgba(255,255,255,.09);background:rgba(13,20,34,.62);
  will-change:transform,opacity,filter;
  transform:rotate(calc(var(--q) * var(--spin,26deg)))
            translate3d(calc(var(--sx,0px) * (1 - var(--q))),calc(var(--sy,0px) * (1 - var(--q))),0)
            rotate(calc(var(--sr,0deg) * (1 - var(--q))))
            scale(calc(1 - var(--q) * .8));
  filter:blur(calc(var(--q) * 5px));
  opacity:calc(1 - var(--q) * 1.08)}

/* ---- the cube -------------------------------------------------------------
   IT MUST NEVER BE FLAT-ON WHILE IT IS LARGE. With a single rotateY sweep the
   cube passes through 90 / 180 / 270 degrees, and at those angles a cube is a
   square: four faces edge-on and invisible, one face square to the camera. The
   old sweep put 176deg — a dead-flat presentation — at p2 = .77, which is very
   nearly the moment the cube is at maximum scale, so the beat the choreography
   builds to rendered as a glowing rounded rectangle.

   Tumbling on X at the same time is the fix, but the FIRST attempt at it still
   rendered flat, and the reason is worth writing down: a linear X sweep that
   runs from negative to positive has to pass through zero, and it passed
   through zero at almost exactly the p2 where Y passed through 180. Two
   flat-on terms cancelling to a perfect square is not bad luck, it is what a
   linear ramp does — it spends its whole time crossing.

   So X never crosses zero any more. It runs -34deg -> -14deg, which keeps the
   top face open to the camera through the entire beat no matter where Y is.
   Y does the tumbling (22deg -> 258deg, a full two-thirds of a revolution) and
   a rotateZ roll keeps the edges from ever settling parallel to the viewport.
   At the widest moment, p2 = .77, that resolves to X -18.6 / Y 203.7 / Z 16.9:
   three faces visible, no axis anywhere near a right angle.

   EACH FACE IS AN APP. Six faces, six flagship products, one sacred monogram
   on every one of them — the cube is not decoration, it is the six products
   held as a single solid, which is the entire argument of the page in one
   object. It then collapses into the one mark and blooms back out as the same
   six tiles, so the middle beat and the payoff are visibly the same six things.

   The faces stay translucent on purpose. A cube reads as three-dimensional
   because you can see its far edges through the near ones; at a high fill
   alpha the front face occludes everything behind it and all that is left is
   an outline. Low fill, legible border, monogram at partial opacity — the
   lattice does the work and the icons ride on it. */
.oscube{position:absolute;width:clamp(132px,16vw,240px);height:clamp(132px,16vw,240px);
  transform-style:preserve-3d;will-change:transform,opacity;pointer-events:none;
  transform:rotateX(calc(-34deg + var(--p2,0) * 20deg))
            rotateY(calc(-38deg + var(--p1,0) * 60deg + var(--p2,0) * 236deg))
            rotateZ(calc(var(--p2,0) * 22deg))
            scale(calc(.22 + var(--p1,0) * .20 + var(--p2,0) * .62 - var(--p3,0) * .08));
  opacity:calc(min(var(--p1,0) * .5 + var(--p2,0) * 1.9, 1) * (1 - var(--p3,0)))}
.oscube__f{position:absolute;inset:0;display:grid;place-items:center;overflow:hidden;
  border:1px solid rgba(147,197,253,.50);border-radius:14px;
  background:linear-gradient(160deg,rgba(9,20,40,.30),rgba(3,8,18,.26));
  box-shadow:inset 0 0 26px rgba(59,158,255,.14),0 0 30px rgba(0,119,255,.16)}
/* The accent lives in a pseudo-element rather than in the face background so
   its opacity can be dialled independently of the ink layer. --acc is the
   product's colour, emitted per face by gen_pricing.py from FLAGSHIP. */
.oscube__f::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(84% 60% at 50% 118%, var(--acc,#0077FF) 0%, transparent 74%);
  opacity:.34}
/* height:auto is not optional. dw-icon.png is 1115x540 — a WIDE mark. Any rule
   that gives it both a width and a height squashes it, which is the exact
   defect this project has already shipped once. */
.oscube__f img{position:relative;z-index:1;width:54%;height:auto;opacity:.78;
  filter:drop-shadow(0 2px 8px rgba(0,0,0,.55))}
.oscube__f:nth-child(1){transform:translateZ(var(--cz,60px))}
.oscube__f:nth-child(2){transform:rotateY(180deg) translateZ(var(--cz,60px))}
.oscube__f:nth-child(3){transform:rotateY(90deg)  translateZ(var(--cz,60px))}
.oscube__f:nth-child(4){transform:rotateY(-90deg) translateZ(var(--cz,60px))}
.oscube__f:nth-child(5){transform:rotateX(90deg)  translateZ(var(--cz,60px))}
.oscube__f:nth-child(6){transform:rotateX(-90deg) translateZ(var(--cz,60px))}
/* The core is a light source inside the lattice, not the subject. At inset 22%
   and .85 peak opacity it out-shone every edge it was supposed to be lighting
   and the cube read as one glowing blob. Smaller and dimmer, it does the job
   it was added for: it back-lights the far faces so their borders stay legible
   against the section's near-black ground. */
.oscube__core{position:absolute;inset:30%;border-radius:50%;background:var(--grad-aqua);filter:blur(16px);
  opacity:calc(.24 + var(--p2,0) * .34)}

/* ---- the shockwave --------------------------------------------------------
   Two rings that expand out of the cube at the moment it resolves. Both peak at
   p3 = 0.5 because opacity is p3 * (1 - p3): a ring that fades in and out inside
   one stage reads as an impact, a ring that lingers reads as a decoration. Two
   separate elements rather than ::before/::after on the stage, because each needs
   its own scale ramp to look like a wave rather than a growing circle. */
.osmerge__ring{position:absolute;z-index:1;pointer-events:none;
  width:clamp(150px,19vw,290px);aspect-ratio:1;border-radius:50%;
  border:1px solid rgba(59,158,255,.55);
  box-shadow:0 0 60px rgba(0,119,255,.30),inset 0 0 40px rgba(59,158,255,.18);
  transform:scale(calc(.3 + var(--p3,0) * 3.2));
  opacity:calc(var(--p3,0) * max(0, 1 - var(--p3,0)) * 3.4);
  will-change:transform,opacity}
.osmerge__ring--2{border-color:rgba(0,119,255,.34);
  transform:scale(calc(.3 + var(--p3,0) * 4.6))}

/* ---- the official app tile ------------------------------------------------
   Geometry from brand/ICON-SYSTEM.md and identical in every tile: rounded
   square, ink base, hairline border, MATTE — no gloss, no glass highlight. The
   white DW monogram is sacred and identical in every icon; the only thing that
   changes between products is --acc, the accent that lights the environment
   behind it.

   dw-icon.png is 1115x540 — a WIDE monogram, not a square. It is sized by width
   with height:auto and centred, so it is never stretched. Forcing it into a
   square box is the exact defect this rule exists to prevent. */
.ostile{position:relative;display:grid;place-items:center;aspect-ratio:1;
  border-radius:24%;overflow:hidden;isolation:isolate;
  background:linear-gradient(160deg,#0C0E12,#07080B 72%);
  border:1px solid rgba(255,255,255,.085)}
.ostile::before{content:"";position:absolute;inset:0;z-index:0;background:var(--acc,#0077FF);opacity:.2;
  -webkit-mask-image:radial-gradient(120% 88% at 50% 118%,#000 0%,rgba(0,0,0,.55) 44%,transparent 78%);
          mask-image:radial-gradient(120% 88% at 50% 118%,#000 0%,rgba(0,0,0,.55) 44%,transparent 78%)}
/* THE ACCENT GLOW MUST BE SIZE-INDEPENDENT. This was `box-shadow: inset 0 0
   40px -8px var(--acc)`, and 40px is 40px whatever the tile measures: it
   flooded a 76px flagship tile edge to edge while barely tinting the 190px
   hero tile beside it. The result looked like two different components — the
   small ones read as flat colour swatches and the big one read as near-black.
   A percentage-based radial gradient renders identically at every size, which
   is the whole point of a component used from 76px to 190px on one screen. */
.ostile::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:inherit;
  background:radial-gradient(72% 52% at 50% 114%, var(--acc,#0077FF) 0%, transparent 72%);
  opacity:.34}
.ostile img{position:relative;z-index:1;width:62%;height:auto}

/* the official app tile the cube becomes */
.osmerge__mark{position:absolute;z-index:2;width:clamp(116px,14vw,190px);will-change:transform,opacity;
  transform:scale(calc(.6 + var(--p3,0) * .4 - var(--p5,0) * .16 - var(--p4,0) * .14))
            translateY(calc(var(--p4,0) * -3vh));
  opacity:calc(var(--p3,0) * max(0, 1 - var(--p4,0) * 2.4));
  filter:drop-shadow(0 0 46px rgba(0,119,255,.45))}
.osmerge__mark .ostile{width:100%}

/* ---- the flagship six blooming out of the tile ---------------------------
   ICON-SYSTEM.md's restraint rule: six accents on one page is the sanctioned
   exception to the blue-only palette; fifteen is not. --bx/--by are the hexagon
   seats in vmin and --bd/--bdk the per-tile stagger, all written by
   gen_pricing.py because they are static. --bs is the responsive multiplier:
   vmin collapses to the 390px width on a phone, so the ring has to open wider
   there in vmin terms to occupy the same share of the screen. */
.osmerge__bloom{position:absolute;inset:0;z-index:3;display:grid;place-items:center;pointer-events:none;
  opacity:calc(min(var(--p5,0) * 1.4, 1) * max(0, 1 - var(--p4,0) * 1.9))}
.osbl{--bs:1;--e:clamp(0, calc((var(--p5,0) - var(--bd,0)) * var(--bdk,1)), 1);
  position:absolute;display:grid;justify-items:center;gap:.5rem;
  width:clamp(50px,6.2vw,76px);will-change:transform,opacity;
  transform:translate3d(calc(var(--bx,0vmin) * var(--bs) * var(--e)),
                        calc(var(--by,0vmin) * var(--bs) * var(--e)),0)
            scale(calc(.25 + var(--e) * .75));
  opacity:var(--e)}
.osbl .ostile{width:100%}
/* The floor is .75rem, not .56rem, because .7vw collapses to nothing on a
   phone: at 390px the middle term of the clamp is 2.7px, so the clamp always
   sat on its minimum, and .56rem is 9px. These labels are the only thing
   naming what each tile is, and the mobile audit's legibility floor is 12px —
   .75rem lands exactly on it rather than near it, because an intermediate
   value like .68rem (10.9px) is still too small to read at arm's length and
   fails the check anyway, so it would have been a change that bought nothing.

   The tracking comes down as the type goes up. .14em on 9px is a fifth of the
   word's width spent on gaps, which is what let a nine-character label stay
   nowrap over a 50px tile; at 12px that same tracking is what would push the
   montage into horizontal overflow. The two move together, and the result is
   measured at 390 and 1440: overflow 0 at both. */
.osbl i{font-style:normal;font-family:var(--font-display);font-weight:600;
  font-size:clamp(.75rem,.7vw,.82rem);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-mut);white-space:nowrap}

/* ---- the counting beat: 24 logins collapsing to 1 ------------------------
   The number is the argument. It counts down with the vortex and is gone before
   the cube resolves, so it never competes with the payoff lines. tabular-nums
   stops the digits jittering as the count crosses 10. */
.osmerge__count{position:absolute;z-index:2;left:50%;translate:-50% 0;
  bottom:clamp(66px,11vh,120px);margin:0;pointer-events:none;
  display:flex;align-items:baseline;gap:.55rem;
  opacity:calc(min(var(--p1,0) * 2, 1) * max(0, 1 - var(--p3,0) * 1.6));
  will-change:opacity}
.osmerge__count b{font-family:var(--font-display);font-weight:700;letter-spacing:-.04em;
  font-size:clamp(2.2rem,4.6vw,3.7rem);line-height:1;color:#fff;
  font-variant-numeric:tabular-nums;text-shadow:0 0 40px rgba(0,119,255,.55)}
/* .75rem, not .7rem: 11.2px sits just under the 12px legibility floor the
   mobile audit enforces, and this word is the unit on the only number in the
   section — "24" means nothing without "logins" next to it. The tracking stays
   at .24em because this is a centred flex pair with no nowrap constraint, so
   the extra ~4px of width costs nothing even at 320px. */
.osmerge__count i{font-style:normal;font-size:.75rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--text-mut)}

/* the payoff lines */
.osmerge__say{position:absolute;z-index:4;left:50%;top:50%;translate:-50% -50%;width:100%;
  text-align:center;padding-inline:clamp(20px,4vw,48px);pointer-events:none;
  transform:translateY(calc(6vh - var(--p4,0) * 6vh));opacity:var(--p4,0);
  will-change:transform,opacity}
.osmerge__say b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.04em;
  font-size:clamp(2.2rem,6.2vw,5rem);line-height:1.02;color:#fff}
.osmerge__say b:nth-child(2){background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.osmerge__say p{margin:clamp(16px,2vw,26px) auto 0;max-width:32em;color:var(--text-soft);
  font-size:clamp(1rem,1.3vw,1.22rem)}
.osmerge__say .oskick{margin-top:clamp(22px,2.6vw,34px);pointer-events:auto;display:inline-flex}

/* scroll hint that fades once the sequence starts */
.osmerge__hint{position:absolute;bottom:clamp(18px,3vh,40px);left:50%;translate:-50% 0;
  font-size:.72rem;letter-spacing:.24em;text-transform:uppercase;color:var(--text-mut);
  opacity:calc(1 - var(--p1,0) * 2.2);display:inline-flex;align-items:center;gap:.6rem}
.osmerge__hint svg{width:14px;height:14px;animation:osnudge 1.9s var(--ease) infinite}
@keyframes osnudge{0%,100%{transform:translateY(0);opacity:.6}50%{transform:translateY(4px);opacity:1}}

/* =============================================================== SECTION 4
   "Compare Every Plan" — Apple's comparison page, not a SaaS table.
   ======================================================================== */
.oscmp{padding-block:clamp(80px,11vw,150px)}
.oscmp__head{text-align:center;margin-bottom:clamp(30px,3.6vw,48px)}
.oscmp__head .os-sub{margin:clamp(16px,1.8vw,24px) auto 0;max-width:38em}

/* billing switch — annual keeps the promotion mechanic (2 months free) */
.osbill{display:inline-flex;position:relative;padding:5px;border-radius:999px;
  border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.045);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);margin-top:clamp(22px,2.6vw,34px)}
.osbill__thumb{position:absolute;top:5px;left:5px;bottom:5px;width:calc(50% - 5px);border-radius:999px;
  background:var(--grad-aqua);box-shadow:0 10px 30px rgba(0,119,255,.34);
  transition:transform .52s var(--ease);will-change:transform}
.osbill__tab{position:relative;z-index:1;border:0;background:none;color:var(--text-soft);
  font-weight:600;font-size:.9rem;padding:.62rem 1.5rem;border-radius:999px;
  transition:color .32s var(--ease);white-space:nowrap}
.osbill__tab[aria-selected="true"]{color:#04121C}
.is-annual .osbill__thumb{transform:translateX(100%)}
.osbill-note{display:block;margin-top:.85rem;font-size:.82rem;color:var(--text-mut)}
.osbill-note b{color:var(--aqua-bright);font-weight:600}

/* the CSS-only price swap */
.osp__yr,.osmx__yr{display:none}
.is-annual .osp__mo,.is-annual .osmx__mo{display:none}
.is-annual .osp__yr,.is-annual .osmx__yr{display:inline}
.osp__save{display:none}
.is-annual .osp__save{display:block}

/* ------------------------------------------------------------- plan cards */
.osrail{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.4vw,18px);
  max-width:1240px;margin:clamp(34px,4vw,54px) auto 0;align-items:stretch}
.osp{position:relative;display:flex;flex-direction:column;padding:clamp(20px,2vw,28px);
  border-radius:22px;border:1px solid rgba(255,255,255,.085);background:rgba(255,255,255,.032);
  -webkit-backdrop-filter:blur(20px) saturate(140%);backdrop-filter:blur(20px) saturate(140%);
  box-shadow:0 20px 60px rgba(0,0,0,.36);
  transition:transform .5s var(--ease),box-shadow .5s var(--ease),border-color .5s var(--ease);
  will-change:transform}
.osp:hover{transform:translateY(-6px);border-color:rgba(59,158,255,.24);
  box-shadow:0 34px 90px rgba(0,0,0,.5),0 0 0 1px rgba(59,158,255,.14)}
.osp--pop{background:linear-gradient(180deg,rgba(0,119,255,.13),rgba(0,119,255,.045) 42%,rgba(255,255,255,.03));
  border-color:rgba(59,158,255,.36);box-shadow:0 30px 90px rgba(0,119,255,.24),0 0 0 1px rgba(59,158,255,.20);
  transform:translateY(-10px);z-index:2}
.osp--pop:hover{transform:translateY(-16px);box-shadow:0 44px 120px rgba(0,119,255,.34),0 0 0 1px rgba(59,158,255,.3)}
.osp__badge{position:absolute;top:-12px;left:50%;translate:-50% 0;white-space:nowrap;
  font-size:.62rem;font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:#04121C;
  padding:.4rem .95rem;border-radius:999px;background:var(--grad-aqua);
  box-shadow:0 10px 28px rgba(0,119,255,.4)}
.osp__tile{width:40px;height:40px;border-radius:12px;display:grid;place-items:center;margin-bottom:14px;
  background:linear-gradient(140deg,rgba(0,119,255,.34),rgba(255,255,255,.04));
  border:1px solid rgba(59,158,255,.26)}
.osp__tile svg{width:20px;height:20px;color:#fff}
.osp__n{font-family:var(--font-display);font-weight:700;font-size:clamp(1.02rem,1.25vw,1.18rem);
  color:#fff;letter-spacing:-.02em}
.osp__d{margin-top:.5rem;font-size:.86rem;line-height:1.55;color:var(--text-mut);min-height:3.6em}
.osp__price{display:flex;align-items:flex-start;gap:.18rem;margin-top:16px;font-family:var(--font-display);
  color:#fff;letter-spacing:-.045em;line-height:1}
.osp__from{display:block;font-size:.68rem;font-weight:700;text-transform:uppercase;
  color:var(--text-mut);margin-bottom:.45rem;letter-spacing:.16em}
.osp__cur{font-size:1.2rem;font-weight:600;margin-top:.35rem}
.osp__n2{font-size:clamp(2.2rem,3vw,2.9rem);font-weight:700}
.osp__unit{font-size:.82rem;font-weight:500;color:var(--text-mut);align-self:flex-end;
  margin-bottom:.42rem;margin-left:.2rem;letter-spacing:0}
.osp__setup{margin-top:.6rem;font-size:.74rem;line-height:1.5;color:var(--text-mut)}
.osp__save{margin-top:.4rem;font-size:.74rem;font-weight:600;color:var(--aqua-bright)}
.osp__cta{margin-top:18px;width:100%}
.osp__inc{margin-top:20px;padding-top:18px;border-top:1px solid rgba(255,255,255,.08)}
.osp__inc h4{font-size:.66rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:var(--aqua-soft);margin-bottom:.9rem;font-family:var(--font-body)}
.osp__inc ul{display:grid;gap:.55rem}
.osp__inc li{display:flex;gap:.6rem;align-items:flex-start;font-size:.845rem;line-height:1.45;color:var(--text-soft)}
.osp__inc li svg{width:15px;height:15px;flex:none;margin-top:.2rem;color:var(--aqua-bright)}
.osp__foot{margin-top:auto}

/* ------------------------------------------------- the ported comparison table */
.osmx__wrap{position:relative;padding-top:24px;margin-top:clamp(56px,7vw,96px)}
.osmx__pop{position:absolute;top:0;left:58.75%;transform:translateX(-50%);white-space:nowrap;z-index:3;
  font-size:.62rem;font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:#04121C;
  padding:.4rem .95rem;border-radius:999px;background:var(--grad-aqua);
  box-shadow:0 10px 28px rgba(0,119,255,.4)}
.osmx{position:relative;border-radius:22px;border:1px solid rgba(255,255,255,.09);
  background:rgba(255,255,255,.026);
  -webkit-backdrop-filter:blur(20px) saturate(140%);backdrop-filter:blur(20px) saturate(140%);
  box-shadow:0 26px 80px rgba(0,0,0,.4);overflow:hidden}
.osmx__scroll{overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch}
.osmx__tbl{width:100%;min-width:1000px;border-collapse:separate;border-spacing:0;table-layout:fixed}
.osmx__tbl col:first-child{width:34%}
.osmx__tbl col{width:16.5%}
.osmx__tbl thead th{position:sticky;top:var(--header-h,78px);z-index:2;vertical-align:bottom;
  padding:clamp(18px,2vw,26px) clamp(12px,1.2vw,18px);text-align:left;
  background:linear-gradient(180deg,rgba(6,10,19,.97),rgba(6,10,19,.9));
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  border-bottom:1px solid rgba(255,255,255,.10)}
.osmx__tbl thead th:first-child{font-family:var(--font-body);font-size:.68rem;font-weight:700;
  letter-spacing:.22em;text-transform:uppercase;color:var(--text-mut)}
.osmx__ft.is-pop{background:linear-gradient(180deg,rgba(0,119,255,.18),rgba(0,119,255,.10))}
.osmx__pn{display:block;font-family:var(--font-display);font-weight:700;font-size:clamp(.94rem,1.1vw,1.06rem);
  color:#fff;letter-spacing:-.02em}
.osmx__pp{display:block;margin-top:.5rem;font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.5rem,2vw,2rem);color:#fff;letter-spacing:-.04em;line-height:1}
.osmx__pp small{font-family:var(--font-body);font-size:.7rem;font-weight:500;color:var(--text-mut);
  letter-spacing:0;margin-left:.15rem}
.osmx__pc{display:block;margin-top:.45rem;font-size:.72rem;line-height:1.45;color:var(--text-mut)}

.osmx__grp th{padding:clamp(20px,2vw,28px) clamp(12px,1.2vw,18px) .7rem;text-align:left;
  font-family:var(--font-body);font-size:.66rem;font-weight:800;letter-spacing:.24em;
  text-transform:uppercase;color:var(--aqua-soft);
  border-bottom:1px solid rgba(255,255,255,.07);background:rgba(0,119,255,.045)}
.osmx__tbl tbody td{padding:.82rem clamp(12px,1.2vw,18px);border-bottom:1px solid rgba(255,255,255,.05);
  vertical-align:middle}
.osmx__tbl tbody tr:hover td{background:rgba(255,255,255,.022)}
.osmx__lab{font-size:.88rem;line-height:1.45;color:var(--text-soft)}
.osmx__cell{text-align:center}
.osmx__cell.is-pop{background:rgba(0,119,255,.07)}
.osmx__tbl tbody tr:hover .osmx__cell.is-pop{background:rgba(0,119,255,.1)}
.osmx__y{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:7px;
  background:var(--grad-aqua);box-shadow:0 4px 14px rgba(0,119,255,.36)}
.osmx__y svg{width:13px;height:13px;color:#04121C}
.osmx__no{display:inline-block;width:22px;height:22px;border-radius:7px;
  background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.07);position:relative}
.osmx__no::before{content:"";position:absolute;left:5px;right:5px;top:50%;height:1.5px;
  border-radius:2px;background:rgba(174,187,208,.42)}
.osmx__txt{font-size:.8rem;font-weight:600;color:var(--text-soft)}
.osmx__ctarow td{padding:clamp(18px,2vw,26px) clamp(12px,1.2vw,18px);border-bottom:0}
.osmx__ctarow .btn{width:100%;padding:.72rem 1rem;font-size:.84rem}
.osmx__foot{display:flex;flex-wrap:wrap;gap:10px 26px;justify-content:center;align-items:center;
  padding:clamp(16px,1.8vw,22px);border-top:1px solid rgba(255,255,255,.07);
  background:rgba(255,255,255,.018);font-size:.8rem;color:var(--text-mut)}
.osmx__foot span{display:inline-flex;align-items:center;gap:.5rem}
.osmx__foot svg{width:14px;height:14px;color:var(--aqua-bright);flex:none}
.osmx__hint{display:none;margin-top:.9rem;text-align:center;font-size:.76rem;color:var(--text-mut)}

/* =============================================================== SECTION 5
   "What You're Replacing" — interactive. Pick what you pay for today,
   see the Dark Water column that swallows it.
   ======================================================================== */
.osrep{padding-block:clamp(80px,11vw,150px)}
.osrep__head{text-align:center;margin-bottom:clamp(36px,4.4vw,58px)}
.osrep__body{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(18px,2.4vw,34px);
  align-items:start;max-width:1120px;margin-inline:auto}
.osrep__nav{display:grid;gap:10px}
.osrep__tab{position:relative;display:block;width:100%;text-align:left;border:1px solid rgba(255,255,255,.08);
  background:rgba(255,255,255,.028);border-radius:16px;padding:clamp(14px,1.6vw,20px);color:var(--text-soft);
  transition:border-color .38s var(--ease),background .38s var(--ease),transform .38s var(--ease),box-shadow .38s var(--ease);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.osrep__tab:hover{transform:translateX(4px);border-color:rgba(59,158,255,.24);background:rgba(0,119,255,.05)}
.osrep__tab[aria-selected="true"]{border-color:rgba(59,158,255,.42);
  background:linear-gradient(120deg,rgba(0,119,255,.14),rgba(255,255,255,.035));
  box-shadow:0 18px 46px rgba(0,119,255,.18)}
.osrep__tab small{display:block;font-size:.62rem;font-weight:700;letter-spacing:.22em;text-transform:uppercase;
  color:var(--text-mut);margin-bottom:.42rem}
.osrep__tab[aria-selected="true"] small{color:var(--aqua-soft)}
.osrep__tab b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.02em;
  font-size:clamp(.95rem,1.15vw,1.08rem);color:#fff;line-height:1.28}
.osrep__panel{position:relative;border-radius:22px;padding:clamp(22px,2.6vw,34px);
  border:1px solid rgba(59,158,255,.22);
  background:linear-gradient(160deg,rgba(0,119,255,.10),rgba(255,255,255,.028) 58%);
  -webkit-backdrop-filter:blur(22px) saturate(140%);backdrop-filter:blur(22px) saturate(140%);
  box-shadow:0 28px 80px rgba(0,0,0,.4)}
.osrep__arrow{display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
  border:1px solid rgba(59,158,255,.3);background:rgba(0,119,255,.12);margin-bottom:16px}
.osrep__arrow svg{width:16px;height:16px;color:var(--aqua-bright);animation:osdown 2.3s var(--ease) infinite}
@keyframes osdown{0%,100%{transform:translateY(-2px)}50%{transform:translateY(3px)}}
.osrep__label{font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;
  font-size:clamp(1.35rem,2.2vw,1.9rem);color:#fff;line-height:1.1}
.osrep__label span{background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.osrep__chips{display:flex;flex-wrap:wrap;gap:9px;margin-top:clamp(18px,2vw,24px)}
.osrep__chip{display:inline-flex;align-items:center;gap:.5rem;padding:.52rem .9rem;border-radius:999px;
  font-size:.83rem;font-weight:500;color:#fff;border:1px solid rgba(59,158,255,.24);
  background:rgba(0,119,255,.09);opacity:0;transform:translateY(8px) scale(.96);
  animation:oschip .5s var(--ease) forwards}
.osrep__chip svg{width:13px;height:13px;color:var(--aqua-bright);flex:none}
@keyframes oschip{to{opacity:1;transform:none}}
.osrep__note{margin-top:clamp(18px,2vw,24px);padding-top:clamp(14px,1.6vw,18px);
  border-top:1px solid rgba(255,255,255,.09);font-size:.88rem;line-height:1.6;color:var(--text-soft)}
.osrep__note b{color:#fff;font-weight:600}

/* =============================================================== SECTION 6
   "Grow Into More" — the progression, with a line that fills as you scroll.
   ======================================================================== */
.osgrow{padding-block:clamp(80px,11vw,150px)}
.osgrow__head{text-align:center;margin-bottom:clamp(40px,5vw,64px)}
.osgrow__ladder{position:relative;max-width:760px;margin-inline:auto;padding-left:clamp(34px,4vw,52px)}
.osgrow__rail{position:absolute;left:clamp(11px,1.35vw,17px);top:8px;bottom:8px;width:2px;border-radius:2px;
  background:rgba(255,255,255,.08);overflow:hidden}
.osgrow__rail i{position:absolute;inset:0 0 auto;height:100%;transform-origin:top;
  transform:scaleY(var(--sp,0));background:var(--grad-aqua);
  box-shadow:0 0 18px 2px rgba(0,119,255,.5)}
.osgrow__step{position:relative;padding-block:clamp(14px,1.8vw,22px)}
.osgrow__step::before{content:"";position:absolute;left:calc(-1 * clamp(34px,4vw,52px) + clamp(5px,.75vw,11px));
  top:calc(clamp(14px,1.8vw,22px) + .35em);width:14px;height:14px;border-radius:50%;
  background:var(--deep);border:2px solid rgba(255,255,255,.16);transition:border-color .5s var(--ease),box-shadow .5s var(--ease)}
.osgrow__step.is-lit::before{border-color:var(--aqua-bright);box-shadow:0 0 0 5px rgba(0,119,255,.16),0 0 22px rgba(59,158,255,.6)}
.osgrow__step b{display:block;font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;
  font-size:clamp(1.25rem,2.4vw,2rem);color:var(--text-mut);line-height:1.14;
  transition:color .5s var(--ease)}
.osgrow__step.is-lit b{color:#fff}
.osgrow__step p{margin-top:.4rem;font-size:.94rem;color:var(--text-mut)}
.osgrow__copy{max-width:44em;margin:clamp(40px,5vw,64px) auto 0;text-align:center;
  font-size:clamp(1rem,1.3vw,1.18rem);line-height:1.7;color:var(--text-soft)}

/* =============================================================== SECTION 7
   "Why Businesses Switch" — the premium icon grid.
   ======================================================================== */
.oswhy{padding-block:clamp(80px,11vw,150px)}
.oswhy__head{text-align:center;margin-bottom:clamp(40px,5vw,64px)}
.oswhy__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:clamp(12px,1.4vw,18px);max-width:1140px;margin-inline:auto}
.oswhy__i{display:flex;align-items:center;gap:.9rem;padding:clamp(15px,1.7vw,21px);border-radius:16px;
  border:1px solid rgba(255,255,255,.075);background:rgba(255,255,255,.028);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  transition:transform .42s var(--ease),border-color .42s var(--ease),background .42s var(--ease),box-shadow .42s var(--ease)}
.oswhy__i:hover{transform:translateY(-4px);border-color:rgba(59,158,255,.26);background:rgba(0,119,255,.055);
  box-shadow:0 22px 56px rgba(0,0,0,.4)}
.oswhy__i span{display:grid;place-items:center;width:38px;height:38px;border-radius:11px;flex:none;
  background:linear-gradient(140deg,rgba(0,119,255,.28),rgba(255,255,255,.04));
  border:1px solid rgba(59,158,255,.24)}
.oswhy__i svg{width:18px;height:18px;color:var(--aqua-bright)}
.oswhy__i b{font-family:var(--font-body);font-weight:600;font-size:.9rem;line-height:1.35;color:#fff}

/* ============================================================== FINAL CTA
   Massive, dark, slow animated glow.
   ======================================================================== */
.oskickband{position:relative;overflow:hidden;isolation:isolate;text-align:center;
  padding-block:clamp(96px,14vw,190px);border-top:1px solid rgba(255,255,255,.06)}
.oskickband::before{content:"";position:absolute;inset:-40% -20%;z-index:-1;pointer-events:none;
  background:radial-gradient(46% 42% at 50% 52%, rgba(0,119,255,.30), transparent 68%);
  animation:osbreathe 11s ease-in-out infinite}
.oskickband::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(59,158,255,.05) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(59,158,255,.05) 1px,transparent 1px);
  background-size:88px 88px;
  -webkit-mask-image:radial-gradient(62% 60% at 50% 50%,#000 6%,transparent 74%);
          mask-image:radial-gradient(62% 60% at 50% 50%,#000 6%,transparent 74%)}
@keyframes osbreathe{0%,100%{transform:scale(1);opacity:.75}50%{transform:scale(1.14);opacity:1}}
.oskickband h2{margin:0 auto;max-width:20em;font-size:clamp(2.1rem,5.4vw,4.4rem);letter-spacing:-.04em;line-height:1.04}
.oskickband h2 span{display:block;background:var(--grad-aqua);-webkit-background-clip:text;background-clip:text;color:transparent}
.oskickband__say{margin-top:clamp(22px,2.6vw,34px);font-family:var(--font-display);font-weight:600;
  font-size:clamp(1rem,1.6vw,1.4rem);letter-spacing:.02em;color:var(--text-soft)}
.oskickband__cta{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin-top:clamp(28px,3.4vw,44px)}
.oskickband__fine{margin-top:clamp(24px,3vw,38px);font-size:.82rem;color:var(--text-mut)}

/* the outline kicker used above the table and inside the merge payoff */
.oskick{display:inline-flex;align-items:center;gap:.6rem;padding:.62rem 1.25rem;border-radius:999px;
  border:1px solid rgba(59,158,255,.3);background:rgba(0,119,255,.08);color:#fff;
  font-size:.86rem;font-weight:600;
  transition:border-color .36s var(--ease),background .36s var(--ease),transform .36s var(--ease)}
.oskick:hover{border-color:rgba(59,158,255,.55);background:rgba(0,119,255,.16);transform:translateY(-2px)}
.oskick svg{width:15px;height:15px;color:var(--aqua-bright)}

/* ============================================================ LEGACY CARE
   Unlisted page only. Never linked from nav or footer.
   ======================================================================== */
.oslg{max-width:560px;margin-inline:auto;padding:clamp(24px,3vw,38px);border-radius:22px;
  border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.03);
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);box-shadow:0 26px 80px rgba(0,0,0,.4)}
.oslg__p{display:flex;align-items:flex-start;gap:.2rem;font-family:var(--font-display);color:#fff;
  letter-spacing:-.045em;line-height:1;margin-block:14px}
.oslg__p b{font-size:clamp(2.4rem,4vw,3.2rem);font-weight:700}
.oslg__p i{font-size:1.2rem;font-style:normal;margin-top:.3rem}
.oslg__p small{font-size:.82rem;font-weight:500;color:var(--text-mut);align-self:flex-end;margin-bottom:.4rem;margin-left:.25rem}
.oslg ul{display:grid;gap:.6rem;margin-top:18px;padding-top:16px;border-top:1px solid rgba(255,255,255,.08)}
.oslg li{display:flex;gap:.6rem;align-items:flex-start;font-size:.88rem;color:var(--text-soft)}
.oslg li svg{width:15px;height:15px;flex:none;margin-top:.2rem;color:var(--aqua-bright)}

/* ============================================================ RESPONSIVE
   "Fully responsive on desktop, tablet, and mobile with no reduction in
   quality, spacing, or animation fidelity." Layout re-flows; nothing is
   switched off.
   ======================================================================== */
@media (max-width:1180px){
  .osrail{grid-template-columns:repeat(2,minmax(0,1fr));max-width:760px}
  .osp--pop{transform:none}
  .osp--pop:hover{transform:translateY(-8px)}
  .osmx__pop{display:none}
  .osmx__hint{display:block}
  .oschaos__grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  /* The hero floats eighteen chips at 1440px. Below this the float layer is
     narrower than the h1's box, so the tail is trimmed rather than allowed to
     collide with the headline. Twelve is what fits. */
  .oshero__float .osfl:nth-child(n+13){display:none}
}
@media (max-width:900px){
  .osrep__body{grid-template-columns:1fr}
  .osmerge{height:400vh}
  .oshero__float{opacity:.7}
  .oschaos__grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .osbl{--bs:1.5}
}
@media (max-width:720px){
  .oschaos__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .osgrow__ladder{padding-left:34px}
}
@media (max-width:620px){
  .osrail{grid-template-columns:1fr;max-width:420px}
  .osp__d{min-height:0}
  .oshero__cta .btn,.oskickband__cta .btn{width:100%}
  .oshero__float{display:none}
  .oscd__alt{display:none}
  .osmerge{height:350vh}
  .osmx__foot{justify-content:flex-start}
  /* One ring of chips on a phone. Two dozen pills on a 390px screen overlap into
     an unreadable mat, and os-pricing.js seeds only the chips that are actually
     visible, so hiding the tail closes the ellipse instead of leaving gaps. */
  .osmerge__swarm .osch:nth-child(n+13){display:none}
  /* 1.9 put half of three tiles off the screen. The ring is seeded at
     --bx:±24vmin, and below 620px vmin IS the width, so the horizontal reach
     from centre is 0.24·w·--bs — at 390px that was 178px from a centre of
     195px, i.e. tile centres at 17px and 373px. Nothing measured it because
     the section clips its own overflow, so documentElement.scrollWidth stayed
     equal to clientWidth and every numeric check passed while "SECURITY" was
     rendering as "ECURITY".

     The binding constraint is the label, not the tile: .osbl is 50px wide here
     but its <i> is white-space:nowrap and the widest word ("Commerce") measures
     85px, so it hangs ~18px past each side of its own tile. Solving
     w/2 − 0.24·w·--bs ≥ 85/2 + 8 for the narrowest phone still in this band
     (320px) gives --bs ≤ 1.42. 1.4 leaves 10px of air at 320px and 39px at
     390px, and still opens the ring to 80% of the viewport width, which is
     what the multiplier was for. Verified by measuring the label rects at 320,
     360, 390 and 430 rather than by reading the overflow number. */
  .osbl{--bs:1.4}
}

/* Motion is a garnish, never the meaning. With reduced motion the scroll
   choreography resolves to its finished state instead of animating. */
@media (prefers-reduced-motion:reduce){
  .osfl{transform:none!important;opacity:.5!important}
  .oscd{transform:none!important}
  .osmerge{height:auto}
  .osmerge__stage{position:static;height:auto;padding-block:clamp(70px,9vw,120px)}
  .osmerge__swarm,.oscube,.osmerge__hint,.osmerge__ring,.osmerge__count{display:none}
  .osmerge__aura::after{display:none}
  .osmerge__mark{position:static;opacity:1!important;transform:none!important;margin-inline:auto}
  /* The six product tiles carry real information, so they resolve to a static
     row instead of being switched off with the choreography. */
  .osmerge__bloom{position:static;inset:auto;display:flex;flex-wrap:wrap;justify-content:center;
    gap:clamp(14px,2vw,22px);margin-top:clamp(22px,3vw,34px);opacity:1!important}
  .osbl{position:static;transform:none!important;opacity:1!important}
  .osmerge__say{position:static;left:auto;top:auto;translate:none;transform:none!important;opacity:1!important;margin-top:28px}
  .osgrow__rail i{transform:scaleY(1)}
  .osgrow__step b{color:#fff}
  .osgrow__step::before{border-color:var(--aqua-bright)}
  .osrep__chip{opacity:1;transform:none;animation:none}
  .oskickband::before{animation:none}
}

/* ==========================================================================
   v30 — 2026-07-27 — PLAN CARD ROW ALIGNMENT (Apple-comparison discipline)
   The four plan cards carry descriptions of different lengths, so in the
   original flex column every price, setup line, CTA and feature list sat at
   a different height. Reading across the row was impossible. Subgrid pins
   every card's internals to the same nine shared row lines, so name, price,
   setup note, CTA and "Everything in ..." all land on one baseline no matter
   how long the copy is. Rows are placed explicitly (never auto-placed) so a
   card that omits a part — Enterprise has no annual saving, only Enterprise
   has "Starting at" — leaves that row empty instead of shifting everything
   below it up by one. Guarded by @supports: browsers without subgrid keep
   the previous flex layout untouched.
   ========================================================================== */
@supports (grid-template-rows: subgrid) {
  .osrail{row-gap:0}
  .osp{display:grid;grid-row:span 9;grid-template-rows:subgrid}
  .osp__tile{grid-row:1}
  .osp__n{grid-row:2}
  .osp__d{grid-row:3;min-height:0}
  .osp__foot{grid-row:4 / span 5;display:grid;grid-template-rows:subgrid;margin-top:0}
  .osp__from{grid-row:1;align-self:end}
  .osp__price{grid-row:2;margin-top:10px}
  .osp__setup{grid-row:3}
  .osp__save{grid-row:4}
  .osp__cta{grid-row:5;align-self:end}
  .osp__inc{grid-row:9}
}

/* v30b — matrix header: reserve the setup-note row so the plan names and the
   price numbers sit on one baseline across all four columns. The cells are
   bottom-aligned (Apple's comparison header), which means a note that wraps
   to three lines would otherwise shove that column's name and price upward. */
.osmx__pc{min-height:4.4em}

/* v30c — sticky comparison header. `overflow:hidden` on the card and
   `overflow-x:auto` on the scroller both create scroll containers, which
   scope a sticky <thead> to the table itself instead of the page — the
   header never sticks. Above 1180px the table already fits, so the scroller
   is not needed there: let overflow go visible and the header sticks under
   the site header exactly as the brief asks. Below 1180px the horizontal
   scroll is worth more than stickiness, so the original rules stand. */
@media (min-width:1181px){
  .osmx{overflow:visible}
  .osmx__scroll{overflow:visible}
  .osmx__tbl thead th:first-child{border-top-left-radius:22px}
  .osmx__tbl thead th:last-child{border-top-right-radius:22px}
}

/* v30d — the sticky header must be opaque. The panel's translucent glass is
   right for a header that sits still; once it sticks, the table rows scroll
   underneath it and read straight through the glass. Solid base colour +
   a hairline and a soft shadow so the header reads as a layer above. */
.osmx__tbl thead th{background:#060B14}
.osmx__tbl thead th::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:rgba(255,255,255,.10)}
.osmx__tbl thead th:first-child{box-shadow:-1px 0 0 rgba(255,255,255,.001)}
.osmx__ft.is-pop{background:linear-gradient(180deg,rgba(0,119,255,.22),rgba(0,119,255,.13)),#060B14}
.osmx__tbl thead tr{box-shadow:0 18px 34px -22px rgba(0,0,0,.9)}

/* ============================================================ v30e — 2026-07-27
   SECTION 5 balance + section rhythm.
   (a) The replace panel was sized by its own content, so on wide viewports it
       ended ~200px above the bottom of the five-tab rail beside it, leaving a
       dead notch in the grid. Stretch the row and let the panel fill it, with
       the note pinned to the bottom edge so the growth is absorbed as breathing
       room rather than as a stretched blank band.
   (b) .osrep's bottom padding and .osgrow's top padding were both
       clamp(80px,11vw,150px) and stacked to ~300px of black between
       "What You're Replacing" and "Grow Into More". Trim the seam.
   ============================================================================ */
/* NOTE: the inactive panels are hidden with the `hidden` ATTRIBUTE, so any
   unqualified `display` on .osrep__panel beats the UA `[hidden]{display:none}`
   and reveals all five at once. Every display rule below is scoped
   :not([hidden]). The nav must NOT stretch: it is itself a grid, and a
   stretched grid container grows its auto rows, which balloons the tabs. */
.osrep__body{align-items:stretch}
.osrep__nav{align-self:start}
.osrep__panels{display:grid}
.osrep__panel:not([hidden]){display:flex;flex-direction:column}
.osrep__chips{margin-bottom:clamp(6px,1vw,14px)}
.osrep__note{margin-top:auto;padding-top:clamp(16px,2vw,22px)}
.osrep{padding-bottom:clamp(56px,7vw,96px)}
.osgrow{padding-top:clamp(24px,3.2vw,44px)}
@media (max-width:900px){
  .osrep__body{align-items:start}
  .osrep__panel:not([hidden]){display:block}
  .osrep__note{margin-top:clamp(18px,2vw,24px)}
}

/* ============================================================ v30f — 2026-07-27
   SECTION 7 "Why Businesses Switch" — 13 reasons in an auto-fit grid wrapped
   5 / 5 / 3 and left-aligned the orphan row, which read as an unfinished
   layout. Flex-wrap with a fixed basis keeps the same 5-up rhythm but centres
   the final row, so 13 looks deliberate instead of truncated. Also trims the
   oswhy -> oskickband seam, which stacked two 150px paddings.
   ============================================================================ */
.oswhy__grid{display:flex;flex-wrap:wrap;justify-content:center;
  gap:clamp(12px,1.4vw,18px);max-width:1140px;margin-inline:auto}
.oswhy__i{flex:0 1 calc(20% - clamp(12px,1.4vw,18px));min-width:196px}
.oswhy{padding-bottom:clamp(52px,6.5vw,88px)}
@media (max-width:1180px){.oswhy__i{flex-basis:calc(33.333% - clamp(12px,1.4vw,18px))}}
@media (max-width:760px){.oswhy__i{flex-basis:calc(50% - clamp(12px,1.4vw,18px))}}
@media (max-width:460px){.oswhy__i{flex-basis:100%}}

/* ============================================================
   v30g · 2026-07-27 — HOMEPAGE PRICING BAND, 4 SUBSCRIPTION PLANS
   The band now carries DW Essential / Business OS / Industry Pro /
   Enterprise, so the 3-track grid gets a 4-track variant. Steps:
   4-up >=1180 -> 2-up 940..1179 -> 1-up <940. `.is-4` is written by
   the markup, not by JS; both classes are required so the legacy
   3-card layout on other pages is untouched.
   ============================================================ */
.prc__grid3--4.is-4{grid-template-columns:repeat(4,1fr);max-width:1280px}
@media (max-width:1179px){
  .prc__grid3--4.is-4{grid-template-columns:repeat(2,1fr);max-width:820px}
}
@media (max-width:939px){
  .prc__grid3--4.is-4{grid-template-columns:1fr;max-width:520px}
}
/* four cards in the space of three: tighten the type so nothing clips */
@media (min-width:1180px){
  .prc__grid3--4.is-4 .pcard{padding:24px 20px 26px}
  .prc__grid3--4.is-4 .pcard__t{font-size:1.24rem}
  .prc__grid3--4.is-4 .pcard__n{font-size:clamp(1.9rem,2.3vw,2.25rem)}
  .prc__grid3--4.is-4 .pcard__inc li{font-size:.845rem}
}
/* the one-time setup line — quiet, but always present */
.pcard__setup{margin:-.3rem 0 .85rem;font-size:.8rem;font-weight:600;
  letter-spacing:.01em;color:rgba(150,190,240,.78)}
.pcard--pop .pcard__setup{color:rgba(180,215,255,.9)}
/* the annual tab label is long — keep the switch inside the viewport */
@media (max-width:600px){
  .prc__switch{max-width:100%}
  .prc__tab{font-size:.76rem;padding:10px 12px;letter-spacing:0}
}

/* --- Lead form: honeypot + inline error ---------------------------------
   .hp-field is the spam trap. It must be invisible and untabbable to humans
   while remaining a real, filled-in field to a naive bot. display:none is
   avoided on purpose — the better form-fillers skip hidden inputs, and some
   password managers do too. Pushing it out of the layout keeps it "real". */
.hp-field{position:absolute!important;left:-9999px!important;top:auto;width:1px;height:1px;overflow:hidden}
.form-error{display:none;margin:10px 0 0;padding:10px 14px;border-radius:10px;
  background:rgba(239,68,68,.12);border:1px solid rgba(239,68,68,.35);
  color:#FCA5A5;font-size:.92rem;line-height:1.45}
.form-error.show{display:block}


/* ============================================================
   PHONE PASS — touch targets and legibility
   ------------------------------------------------------------
   Everything below applies only at phone widths. Two rules, and
   they are both about the hand holding the device:

   1. A control must be at least 44x44. That number is not
      arbitrary — it is the size of the pad of an adult index
      finger, and every control smaller than it is a control the
      user has to aim at. Aiming is what makes a site feel cheap
      on a phone even when nothing is visually broken.

   2. No text below 12px. Below that, a real person at arm's
      length on a moving bus stops reading and starts guessing.

   These are additive overrides at the end of the sheet, so they
   win on cascade order without touching the desktop design.
   ============================================================ */
@media (max-width:820px){

  /* --- 1. tap targets --------------------------------------- */

  /* Breadcrumb. 43x15 before this — the smallest control on the
     site and the first one on every inner page. */
  .crumb{margin-bottom:.2rem}
  .crumb a{display:inline-block;padding:.7rem .5rem;margin:-.7rem -.5rem;
    min-height:44px;line-height:30px}

  /* "Explore ->" card links. Inline-flex with no vertical padding
     gave a 24px strip; the padding is negative-margined back out
     so the card layout does not shift. */
  .card__link{padding:.6rem 0;margin-top:.55rem;min-height:44px;align-items:center}
  .mani__link{padding:.55rem 0;min-height:44px}

  /* Footer utility row (Portal / Analytics / Dashboard / Privacy)
     and the service column links. */
  .footer-bottom a{display:inline-block;padding:.65rem .35rem;min-height:44px;line-height:30px}
  .footer-grid ul a{display:inline-block;padding:.55rem 0;min-height:44px;line-height:33px}

  /* Social icons: 38 -> 44. */
  .social{gap:.5rem}
  .social a{width:44px;height:44px}

  /* Accordions on knowledge-base.html — a 24px summary is the
     hardest thing on the site to open. */
  summary{padding:.7rem 0;min-height:44px;display:flex;align-items:center}

  /* Auth forms: the show-password eye and the "Forgot password?"
     link both sat under 40. */
  .authf__eye{width:44px;height:44px;right:.25rem}
  .authf__link{display:inline-block;padding:.6rem .25rem;margin:0 -.25rem;min-height:44px;line-height:32px}

  /* Chips, pills and the design-vault badges. */
  .woven__chips a,.chip,a.tag,.va{min-height:44px;display:inline-flex;align-items:center}
  .va{padding:.55rem .9rem}

  /* Header wordmark — a 28px-tall logo link is a miss waiting to
     happen right next to the menu button. */
  .site-header .brand{min-height:44px;align-items:center}

  /* Concierge widget. */
  .chat-quick button{min-height:40px;padding:.55rem .8rem}
  #chatClose{width:40px;height:40px;display:grid;place-items:center}

  /* --- 2. legibility floor ---------------------------------- */

  .drawer__group-label{font-size:.8rem}
  .eyebrow,.eyebrow--center,div.eyebrow{font-size:.78rem;letter-spacing:.2em}
  .site-footer .brand__sub,.brand__sub{font-size:.76rem;letter-spacing:.22em}
  .closer__trust,.closer__trust li{font-size:.78rem}
  .auth__kpis div span,.auth__lock span{font-size:.78rem;letter-spacing:.1em}
  .neon__hint{font-size:.78rem;letter-spacing:.18em}
  .oscd__cat,.oscd__bill{font-size:.78rem;letter-spacing:.12em}
  .work-tile .tag,span.tag,a.tag{font-size:.8rem}
  .va{font-size:.8rem}
  .stat span{font-size:.85rem}
  .dkpi span,.dcard--conv span,.pviz__k span{font-size:.78rem;letter-spacing:.08em}
}

/* --- phone pass, second round: what the first pass missed -----
   A few of these carry inline style="font-size:…", which outranks
   a stylesheet rule no matter where it sits. !important is the
   correct tool for exactly that case and nothing else. */
@media (max-width:820px){
  /* Short tags ("AI", "CRO") were 44 tall but only 13-28 wide. */
  a.tag,.tag{min-width:44px;justify-content:center;padding:.4rem .7rem}

  /* App-shell chrome: the wordmark and the "back to site" link. */
  .app-side .brand,.app-top .brand{min-height:44px;align-items:center}
  .app-side a[style],.app-side>a{min-height:44px;padding:.6rem 0;line-height:1.9}
  .app-side .brand__sub,.app-top .brand__sub{font-size:.76rem!important;letter-spacing:.2em}

  /* Micro-badges and label rows. */
  .mprod__tier,.mprod__row em{font-size:.78rem}
  .mprod__badge{font-size:.72rem!important;padding:.35rem .7rem}
  .osp__badge{font-size:.74rem}
  .osp__setup{font-size:.82rem}
  .osp__inc h4{font-size:.78rem;letter-spacing:.12em}
  .osmx__tbl thead th:first-child,.osmx__pp small{font-size:.8rem}
  .dcard__lbl,.pviz__chrome span,.proof__live,.os-eye{font-size:.78rem}

  /* Anything still carrying a hard-coded sub-12px inline size. */
  [style*="font-size:.72rem"],[style*="font-size:.7rem"],
  [style*="font-size:.68rem"],[style*="font-size:.65rem"],
  [style*="font-size:.62rem"],[style*="font-size:.6rem"]{font-size:.78rem!important}
  .tl__when i,.vault-card i,.designs i{font-size:.8rem}
}

/* --- phone pass, third round -----------------------------------
   Correcting my own arithmetic: .72rem is 11.52px and .74rem is
   11.84px — both still under the 12px floor. Below, the floor is
   stated in px so it cannot be got wrong again. */
@media (max-width:820px){
  .brand__sub{font-size:12.5px!important;letter-spacing:.2em}
  .mprod__badge{font-size:12.5px!important}
  .osp__badge,.osp__from{font-size:12.5px!important}
  .dvault__stat span,.stat-mini span{font-size:12.5px}
  [style*="font-size:.74rem"],[style*="font-size:.66rem"],
  [style*="font-size:.63rem"],[style*="font-size:.64rem"],
  [style*="font-size:.58rem"],[style*="font-size:.56rem"],
  [style*="font-size:11px"],[style*="font-size:10px"]{font-size:12.5px!important}
}

/* --- phone pass, final residuals ------------------------------- */
@media (max-width:820px){
  .appbar__t span{font-size:12.5px;letter-spacing:.16em}
  .pviz__row span,.pviz__row em{font-size:12.5px}
  .osmx__pc{font-size:12.5px}
  .hero__mini b,.hero__mini span,.dmini b,.dmini span{font-size:12.5px}
}

/* Last of the sub-12px text that a person actually reads.
   .osfl / .osch / .bars are excluded on purpose — they are the
   drifting background ornaments in the pricing hero and the merge
   animation. They are texture, not copy, and blowing them up to
   12px would wreck the composition for no reading benefit. */
@media (max-width:820px){
  .dcard__head span,.dcard__val b,.dashshot__bar b,
  .wfeat__tag,.pcard__badge,.oscd__alt,.osp__save,
  .osmx__pop,.osmx__grp th,.osrep__tab small{font-size:12.5px}
}


/* ===================================================================
   THE COMMAND DECK
   Components emitted by portal/inc/charts.php.
   ===================================================================

   Every rule below styles markup that one PHP file produces, and that
   file draws with inline SVG and nothing else — no charting library,
   no canvas, no script. Which means these rules are not decoration on
   top of a chart; together with the SVG they ARE the chart. Change a
   class name here and something stops being readable somewhere.

   Three things hold the whole layer together:

   1. Depth is glass, never a flat panel. A card is a vertical gradient
      over a blurred backdrop with a single hairline of aqua across its
      top edge. That hairline is the entire reason a stat card reads as
      a lit surface rather than a grey box, and it costs one pseudo
      element.

   2. Numbers are set in the display face with tabular figures. A
      dashboard where the digits change width jitters every time it
      refreshes, and jitter reads as cheap.

   3. Nothing a person reads goes below 12px, at any width. The three
      phone passes further up this file exist because that rule was
      broken before. Do not break it here.

   Colour comes from :root and from inline custom properties the PHP
   sets per element (--dw-score-c, --dw-win-c, --dw-move-c, --dw-ms-c).
   There are no hex values in this block that are not neutral white
   alpha — the palette lives in one place and this is not it. */

/* ---- statistic cards ---------------------------------------------- */

.dw-stats{display:grid;gap:16px;grid-template-columns:repeat(4,minmax(0,1fr))}
.dw-stats[data-cols="1"]{grid-template-columns:minmax(0,1fr)}
.dw-stats[data-cols="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}
.dw-stats[data-cols="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
.dw-stats[data-cols="5"]{grid-template-columns:repeat(5,minmax(0,1fr))}
.dw-stats>*{min-width:0}

.dw-stat{position:relative;display:flex;align-items:center;gap:14px;
  padding:18px 20px;border-radius:var(--radius);
  background:linear-gradient(180deg,rgba(255,255,255,.055) 0%,rgba(255,255,255,.028) 100%);
  border:1px solid var(--glass-brd);backdrop-filter:blur(14px);
  color:inherit;text-decoration:none;overflow:hidden;min-width:0;
  transition:transform .35s var(--ease),border-color .35s var(--ease),box-shadow .35s var(--ease)}
/* The lit top edge. Fades out at both ends so it reads as a highlight
   catching the surface, not as a border someone forgot to finish. */
.dw-stat::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(59,158,255,.55),transparent);opacity:.7}
a.dw-stat:hover{transform:translateY(-3px);border-color:var(--line-2);
  box-shadow:0 18px 40px rgba(0,119,255,.18)}
a.dw-stat:focus-visible{outline:2px solid var(--aqua-bright);outline-offset:3px}

.dw-stat__body{flex:1 1 auto;min-width:0}
.dw-stat__head{display:flex;align-items:center;gap:9px;min-width:0}
.dw-stat__chip{flex:0 0 auto;width:28px;height:28px;border-radius:9px;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid transparent}
.dw-stat__chip svg{width:15px;height:15px;display:block}
/* .74rem and .06em rather than .8/.09. Four cards in a 1150px content column
   leave about 160px for the label once the chip, the gap and a 56px ring are
   taken out, and at the old size "CERTIFICATES" ellipsised to "CERTIFICAT…" —
   a truncation with no information in it, on the one card whose whole job is
   to say the word "certificates". */
.dw-stat__lbl{font-size:.74rem;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-mut);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dw-stat__val{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.55rem,2.3vw,2.05rem);line-height:1.1;
  letter-spacing:-.02em;margin:.5rem 0 .25rem;
  font-variant-numeric:tabular-nums;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-stat__foot{display:flex;align-items:baseline;gap:.4rem;flex-wrap:wrap;
  font-size:.78rem;line-height:1.35}
.dw-delta{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.dw-delta.good{color:#34D399}
.dw-delta.bad{color:#F87171}
.dw-delta.flat{color:var(--text-mut)}
.dw-stat__vs,.dw-stat__note{color:var(--text-mut)}
.dw-stat__spark{flex:0 0 auto;width:74px;opacity:.95}
.dw-stat__spark svg{display:block;width:100%;height:auto}
.dw-stat__ring{flex:0 0 auto}
/* The ring inside a stat card is 56px, not the 86px default, so the number in
   the middle has to come down with it or it touches the stroke on both sides. */
.dw-stat__ring .dw-ring__t{font-size:.72rem}

.dw-spark{display:block}

/* ---- the area chart ------------------------------------------------ */

/* The SVG stretches; the words do not live inside it. See the comment
   over dw_area() in charts.php for why. --dw-ch is set inline by PHP
   and is the drawing height in real pixels. */
.dw-chart-wrap{display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-rows:auto auto auto;column-gap:10px}
.dw-chart__ys{grid-column:1;grid-row:1;position:relative;width:46px;height:var(--dw-ch,230px)}
.dw-chart-wrap[data-money="1"] .dw-chart__ys{width:74px}
.dw-chart__c{grid-column:2;grid-row:1;position:relative;height:var(--dw-ch,230px);min-width:0}
.dw-chart__xs{grid-column:2;grid-row:2;position:relative;height:22px;min-width:0;margin-top:6px}
.dw-chart-wrap>.dw-legend{grid-column:1/-1;grid-row:3}

.dw-chart{display:block;width:100%;height:100%}
.dw-chart__grid line{stroke:rgba(255,255,255,.07);stroke-width:1;
  vector-effect:non-scaling-stroke}
/* Invisible until touched. The hover circle is the tooltip trigger and
   the <title> inside it is the tooltip — the browser draws it, so this
   works with scripting off and on a phone by long press. */
.dw-chart__dot{opacity:0;transition:opacity .18s var(--ease)}
.dw-chart__dot:hover{opacity:.9}

.dw-chart__ys span{position:absolute;right:0;transform:translateY(-50%);
  font-size:.72rem;line-height:1;color:var(--text-mut);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.dw-chart__x{position:absolute;top:0;transform:translateX(-50%);
  font-size:.72rem;line-height:1;color:var(--text-mut);white-space:nowrap}
/* The two ends are pinned rather than centred, so neither hangs off the
   edge of the panel and gets clipped. */
.dw-chart__x--s{transform:none}
.dw-chart__x--e{transform:translateX(-100%)}

.dw-chart-empty{display:grid;place-items:center;min-height:150px;padding:2rem 1rem;
  border:1px dashed var(--line);border-radius:var(--radius);
  background:rgba(255,255,255,.02)}
.dw-chart-empty span{color:var(--text-mut);font-size:.92rem;text-align:center;max-width:26rem}

/* ---- columns -------------------------------------------------------- */

.dw-cols{display:flex;align-items:flex-end;gap:8px;height:200px;padding-top:6px}
.dw-cols__c{flex:1 1 0;min-width:0;display:flex;flex-direction:column;
  justify-content:flex-end;align-items:center;height:100%;gap:8px}
.dw-cols__bar{display:block;width:100%;max-width:54px;border-radius:8px 8px 3px 3px;
  transition:filter .3s var(--ease),transform .3s var(--ease);transform-origin:bottom}
.dw-cols__c:hover .dw-cols__bar{filter:brightness(1.18);transform:scaleY(1.02)}
.dw-cols__lbl{flex:0 0 auto;font-size:.72rem;color:var(--text-mut);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}

/* ---- donut ---------------------------------------------------------- */

.dw-donut{display:flex;align-items:center;gap:26px;flex-wrap:wrap}
.dw-donut__ring{position:relative;flex:0 0 auto;line-height:0}
.dw-donut__ring svg{display:block;max-width:100%;height:auto}
.dw-donut__mid{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;pointer-events:none;text-align:center}
.dw-donut__mid b{font-family:var(--font-display);font-size:1.6rem;line-height:1;
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.dw-donut__mid span{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-mut);margin-top:.3rem}

.dw-legend{flex:1 1 200px;min-width:0;display:flex;flex-direction:column;gap:.55rem}
.dw-legend__row{display:grid;grid-template-columns:10px minmax(0,1fr) auto auto;
  align-items:center;gap:.7rem;font-size:.88rem}
.dw-legend i{width:10px;height:10px;border-radius:3px;flex:0 0 auto;display:block}
.dw-legend__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text-soft)}
.dw-legend__n{font-weight:700;font-variant-numeric:tabular-nums}
.dw-legend__p{color:var(--text-mut);font-variant-numeric:tabular-nums;
  min-width:2.6rem;text-align:right}
.dw-legend--row{flex-direction:row;flex-wrap:wrap;gap:1.1rem;margin-top:.9rem}
.dw-legend__i{display:inline-flex;align-items:center;gap:.5rem;
  font-size:.85rem;color:var(--text-soft)}

/* ---- ring ----------------------------------------------------------- */

.dw-ring{position:relative;flex:0 0 auto;display:grid;place-items:center}
.dw-ring svg{display:block;position:absolute;inset:0}
.dw-ring__t{position:relative;font-family:var(--font-display);font-weight:700;
  font-size:.86rem;line-height:1;font-variant-numeric:tabular-nums}

/* ---- horizontal bars ------------------------------------------------ */

.dw-bars{display:flex;flex-direction:column;gap:.95rem}
.dw-bars__row{min-width:0}
.dw-bars__top{display:flex;align-items:baseline;justify-content:space-between;
  gap:1rem;margin-bottom:.42rem;color:inherit;text-decoration:none}
a.dw-bars__top:hover .dw-bars__name{color:var(--aqua-bright)}
.dw-bars__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:.92rem;transition:color .25s var(--ease)}
.dw-bars__n{flex:0 0 auto;font-weight:700;font-size:.92rem;
  font-variant-numeric:tabular-nums}
.dw-bars__track{height:8px;border-radius:99px;background:rgba(255,255,255,.06);
  overflow:hidden}
.dw-bars__track>span{display:block;height:100%;border-radius:99px}

/* ---- progress ------------------------------------------------------- */

.dw-prog{display:flex;align-items:center;gap:.7rem;min-width:0}
.dw-prog__track{flex:1 1 auto;height:7px;border-radius:99px;
  background:rgba(255,255,255,.07);overflow:hidden;min-width:40px}
.dw-prog__track>span{display:block;height:100%;border-radius:99px}
.dw-prog__n{flex:0 0 auto;font-size:.78rem;color:var(--text-mut);
  font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:right}
.dw-prog--bare .dw-prog__track{min-width:0}

/* ---- timeline ------------------------------------------------------- */

.dw-tl{--dw-tl-lbl:190px;display:flex;flex-direction:column;gap:.6rem}
.dw-tl__scale{position:relative;height:18px;margin-left:var(--dw-tl-lbl);
  border-bottom:1px solid var(--line)}
.dw-tl__mark{position:absolute;top:0;left:0;font-size:.7rem;color:var(--text-mut);
  padding-left:5px;border-left:1px solid var(--line);height:18px;line-height:18px;
  white-space:nowrap}
/* Today. The one line on the chart that is not data, so it is the only
   one that gets the brand colour. */
.dw-tl__now{position:absolute;top:0;bottom:-4px;width:2px;border-radius:2px;
  background:var(--aqua-bright);box-shadow:0 0 10px rgba(59,158,255,.7);z-index:1}
.dw-tl__row{display:grid;grid-template-columns:var(--dw-tl-lbl) minmax(0,1fr);
  align-items:center;gap:0}
.dw-tl__lbl{display:flex;align-items:baseline;justify-content:space-between;
  gap:.6rem;padding-right:14px;min-width:0;font-size:.9rem}
.dw-tl__lbl a{color:inherit;text-decoration:none;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.dw-tl__lbl a:hover{color:var(--aqua-bright)}
.dw-tl__lbl>span{flex:0 0 auto;font-size:.78rem;color:var(--text-mut);
  font-variant-numeric:tabular-nums}
.dw-tl__track{position:relative;height:26px;border-radius:8px;
  background:rgba(255,255,255,.035);min-width:0}
.dw-tl__bar{position:absolute;top:5px;height:16px;border-radius:99px;
  box-shadow:0 4px 14px rgba(0,0,0,.35);overflow:hidden}
/* Work done, drawn inside the bar rather than beside it, so the row
   says "this long, this far in" in one shape. */
.dw-tl__bar>i{display:block;height:100%;border-radius:99px;
  background:rgba(255,255,255,.42)}

/* ---- panel furniture ------------------------------------------------ */

.dw-ph{display:flex;align-items:flex-start;justify-content:space-between;
  gap:1.2rem;margin-bottom:1.15rem;flex-wrap:wrap}
.dw-ph__t{min-width:0}
.dw-ph__t h3{font-family:var(--font-display);font-size:1.12rem;font-weight:700;
  letter-spacing:-.01em;margin:0}
.dw-ph__t p{margin:.3rem 0 0;font-size:.86rem;color:var(--text-mut);max-width:46ch}
.dw-ph__r{flex:0 0 auto;display:flex;align-items:center;gap:.6rem}
.dw-more{font-size:.85rem;font-weight:600;color:var(--aqua-bright);
  text-decoration:none;white-space:nowrap;transition:opacity .25s var(--ease)}
.dw-more:hover{opacity:.75}

.dw-pagehead{margin-bottom:1.6rem}
.dw-pagehead h1{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.7rem,3.2vw,2.4rem);line-height:1.12;letter-spacing:-.025em;
  margin:.7rem 0 0}
.dw-pagehead p{margin:.5rem 0 0;color:var(--aqua-soft);font-size:1rem;max-width:62ch}

/* ---- people --------------------------------------------------------- */

.dw-av{display:inline-flex;align-items:center;justify-content:center;
  border-radius:50%;font-weight:700;color:#fff;flex:0 0 auto;
  letter-spacing:.02em;line-height:1;
  box-shadow:0 2px 8px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.22)}
.dw-who{display:inline-flex;align-items:center;gap:.65rem;min-width:0}
.dw-who__t{display:flex;flex-direction:column;min-width:0;line-height:1.3}
.dw-who__t b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-who__t small{font-size:.76rem;color:var(--text-mut);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* ===== the half that is not reporting ==============================
   Below here nothing measures anything. The score, the win, the moves
   and the milestone exist to tell the owner where they stand, what
   went right, and what to do next. They are the difference between a
   page somebody checks and a page somebody runs a business from. */

/* ---- the score gauge ------------------------------------------------ */

.dw-score{position:relative;display:flex;flex-direction:column;align-items:center;
  text-align:center;padding:4px 0 2px}
.dw-score svg{display:block;width:100%;max-width:260px;height:auto;
  filter:drop-shadow(0 6px 22px color-mix(in srgb,var(--dw-score-c) 40%,transparent))}
/* The number sits up inside the arc, not under it. Negative margin is
   what pulls it into the empty half-circle the gauge leaves behind. */
.dw-score__n{margin-top:-3.4rem;display:flex;align-items:baseline;gap:.15rem;
  line-height:1}
.dw-score__n b{font-family:var(--font-display);font-weight:700;
  font-size:clamp(2.6rem,6vw,3.5rem);letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg,#fff 0%,var(--dw-score-c) 130%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.dw-score__n i{font-style:normal;font-size:1rem;color:var(--text-mut);font-weight:600}
.dw-score__w{margin-top:.45rem;font-weight:700;font-size:1.02rem;
  letter-spacing:.02em;color:var(--dw-score-c)}
.dw-score__s{margin-top:.35rem;font-size:.86rem;color:var(--text-mut);max-width:32ch}

/* ---- a win ---------------------------------------------------------- */

.dw-win{position:relative;display:flex;align-items:center;gap:.95rem;
  padding:14px 16px;border-radius:var(--radius);
  background:rgba(255,255,255,.045);
  border:1px solid var(--glass-brd);
  background:linear-gradient(135deg,
    color-mix(in srgb,var(--dw-win-c) 16%,transparent) 0%,
    rgba(255,255,255,.03) 62%);
  border:1px solid color-mix(in srgb,var(--dw-win-c) 30%,transparent)}
.dw-win__ico{flex:0 0 auto;width:34px;height:34px;border-radius:11px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--dw-win-c);
  background:rgba(255,255,255,.07);
  border:1px solid var(--glass-brd);
  background:color-mix(in srgb,var(--dw-win-c) 18%,transparent);
  border:1px solid color-mix(in srgb,var(--dw-win-c) 34%,transparent)}
.dw-win__ico svg{width:17px;height:17px;display:block}
.dw-win__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:.15rem}
.dw-win__t b{font-weight:700;font-size:.98rem}
.dw-win__t span{font-size:.85rem;color:var(--text-soft)}
.dw-win__go{flex:0 0 auto;font-size:.85rem;font-weight:600;
  color:var(--dw-win-c);text-decoration:none;white-space:nowrap}
.dw-win__go:hover{opacity:.78}

/* ---- the next move -------------------------------------------------- */

.dw-moves{display:flex;flex-direction:column;gap:.7rem}
.dw-move{position:relative;display:flex;align-items:center;gap:.95rem;
  padding:14px 16px;border-radius:var(--radius);
  background:rgba(255,255,255,.035);border:1px solid var(--glass-brd);
  transition:border-color .3s var(--ease),background .3s var(--ease)}
.dw-move:hover{background:rgba(255,255,255,.055);
  border-color:var(--line-2);
  border-color:color-mix(in srgb,var(--dw-move-c) 40%,transparent)}
/* The urgency stripe. Only the left edge is coloured, so a list of six
   reads as a list, not as six competing alerts. */
.dw-move::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;
  border-radius:0 3px 3px 0;background:var(--dw-move-c)}
.dw-move--idea::before{opacity:.45}
.dw-move__ico{flex:0 0 auto;width:32px;height:32px;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--dw-move-c);
  background:rgba(255,255,255,.06);
  border:1px solid var(--glass-brd);
  background:color-mix(in srgb,var(--dw-move-c) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--dw-move-c) 30%,transparent)}
.dw-move__ico svg{width:16px;height:16px;display:block}
.dw-move__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:.15rem}
.dw-move__t b{font-weight:600;font-size:.96rem}
.dw-move__t span{font-size:.84rem;color:var(--text-mut)}
.dw-move .btn{flex:0 0 auto}

.dw-moves--clear{display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:.4rem;padding:2rem 1.25rem;
  border:1px dashed var(--line-2);border-radius:var(--radius);
  background:rgba(59,158,255,.03)}
.dw-moves--clear .dw-moves__tick{width:40px;height:40px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;margin-bottom:.35rem;
  color:#34D399;background:rgba(52,211,153,.14);border:1px solid rgba(52,211,153,.3)}
.dw-moves--clear .dw-moves__tick svg{width:19px;height:19px;display:block}
.dw-moves--clear b{font-weight:700;font-size:1rem}
.dw-moves--clear span{font-size:.88rem;color:var(--text-mut);max-width:38ch}

/* ---- milestone ------------------------------------------------------ */

.dw-ms{padding:18px 20px;border-radius:var(--radius);
  background:linear-gradient(180deg,rgba(255,255,255,.05) 0%,rgba(255,255,255,.025) 100%);
  border:1px solid var(--glass-brd)}
.dw-ms__top{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
.dw-ms__lbl{font-size:.78rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-mut);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-ms__pct{flex:0 0 auto;font-weight:700;font-size:.86rem;color:var(--dw-ms-c);
  font-variant-numeric:tabular-nums}
/* The distance left, not the percentage, gets the big type. */
.dw-ms__big{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.35rem,2.2vw,1.75rem);line-height:1.15;letter-spacing:-.02em;
  margin:.5rem 0 .85rem;font-variant-numeric:tabular-nums}
.dw-ms__track{height:9px;border-radius:99px;background:rgba(255,255,255,.07);
  overflow:hidden}
.dw-ms__track>span{display:block;height:100%;border-radius:99px;
  box-shadow:0 0 14px color-mix(in srgb,var(--dw-ms-c) 55%,transparent)}
.dw-ms__foot{display:flex;justify-content:space-between;gap:1rem;
  margin-top:.5rem;font-size:.78rem;color:var(--text-mut);
  font-variant-numeric:tabular-nums}

/* ---- narrower screens ----------------------------------------------- */

@media (max-width:1180px){
  .dw-stats[data-cols="4"],.dw-stats[data-cols="5"]{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:980px){
  .dw-stats,.dw-stats[data-cols="3"],.dw-stats[data-cols="4"],
  .dw-stats[data-cols="5"]{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dw-tl{--dw-tl-lbl:140px}
}
@media (max-width:640px){
  .dw-stats,.dw-stats[data-cols="2"],.dw-stats[data-cols="3"],
  .dw-stats[data-cols="4"],.dw-stats[data-cols="5"]{grid-template-columns:minmax(0,1fr)}
  .dw-donut{gap:18px;justify-content:center}
  .dw-donut__ring{margin:0 auto}
  /* The timeline label column stops being a column. Two rows per bar is
     readable at 360px; a 90px name column is not. */
  .dw-tl{--dw-tl-lbl:0px}
  .dw-tl__scale{margin-left:0}
  .dw-tl__row{grid-template-columns:minmax(0,1fr);gap:.3rem}
  .dw-tl__lbl{padding-right:0}
  .dw-tl__bar{top:6px;height:14px}
}

/* Reduced motion: the lifts and scales go, the colour changes stay —
   hover still has to tell you the thing is a link. */
@media (prefers-reduced-motion:reduce){
  .dw-stat,.dw-cols__bar,.dw-chart__dot,.dw-move,.dw-bars__name{transition:none}
  a.dw-stat:hover{transform:none}
  .dw-cols__c:hover .dw-cols__bar{transform:none}
}

/* ============================================================
   THE TOP BAR
   ------------------------------------------------------------
   app_top() in portal/inc/layout.php now emits three things on
   the right of every one of the 52 pages: a search field, a bell
   with a count on it, and who is signed in. None of it had any
   CSS, so it rendered as a bare input, a blue link and two words
   stacked on top of each other.

   The bar is a flex row that wraps, and the heading block is the
   one allowed to grow. That ordering matters on a laptop at
   1280px: the search shrinks before the name does, because the
   name is identity and the search is a tool.
   ============================================================ */
.app-top__h{flex:1 1 320px;min-width:0}
/* The heading was inheriting the marketing site's h2, which is sized to be the
   first thing a stranger reads on a landing page. On a dashboard it is the
   least interesting thing on the screen — the reader knows which page they
   opened — and at 1440 "Welcome back, Dark Water Ventures" wrapped to two
   lines fifty pixels tall and shoved the search and the bell into the corner.
   Sized down, the row fits on one line and the eye lands on the score. */
.app-top__h h2{font-size:clamp(1.5rem,2.1vw,1.85rem);line-height:1.16;
  letter-spacing:-.02em;margin:.1rem 0 0}
.app-top__h p{margin:.4rem 0 0;font-size:.9rem}
.app-top__r{display:flex;align-items:center;gap:.85rem;flex:0 1 auto;min-width:0}

.app-search{position:relative;display:flex;align-items:center;
  flex:0 1 260px;min-width:120px}
.app-search__i{position:absolute;left:12px;top:50%;transform:translateY(-50%);
  color:var(--text-mut);display:inline-flex;pointer-events:none}
.app-search__i svg{width:16px;height:16px;display:block}
.app-search input{width:100%;min-width:0;height:44px;
  padding:0 .9rem 0 34px;border-radius:999px;
  background:rgba(255,255,255,.045);border:1px solid var(--glass-brd);
  color:var(--text);font-family:var(--font-body);font-size:.88rem;
  transition:border-color .3s var(--ease),background .3s var(--ease),
             box-shadow .3s var(--ease)}
.app-search input::placeholder{color:var(--text-mut)}
.app-search input:focus{outline:none;border-color:var(--line-2);
  background:rgba(255,255,255,.07);box-shadow:0 0 0 3px rgba(0,119,255,.14)}
/* The browser's own clear button on type=search is a grey X that reads as a
   defect on a dark field. */
.app-search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}

.app-bell{position:relative;flex:0 0 auto;width:44px;height:44px;
  border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.045);border:1px solid var(--glass-brd);
  color:var(--text-soft);
  transition:color .3s var(--ease),border-color .3s var(--ease),
             background .3s var(--ease)}
.app-bell svg{width:19px;height:19px;display:block}
.app-bell:hover{color:var(--aqua-bright);border-color:var(--line-2);
  background:rgba(0,119,255,.10)}
.app-bell:focus-visible{outline:2px solid var(--aqua-bright);outline-offset:3px}
/* .has, not a count > 0 check in CSS: the class is set once in PHP so the ring
   and the badge can never disagree with each other. */
.app-bell.has{color:var(--aqua-bright);border-color:var(--line-2)}
.app-bell i{position:absolute;top:-3px;right:-3px;min-width:19px;height:19px;
  padding:0 5px;border-radius:999px;background:#F87171;color:#1A0505;
  font-style:normal;font-weight:700;font-size:.68rem;line-height:19px;
  text-align:center;font-variant-numeric:tabular-nums;
  border:2px solid var(--deep);box-shadow:0 2px 10px rgba(248,113,113,.45)}

/* .who already sets margin-top:auto for the sidebar card it was written for.
   In a top bar that pushes it to the bottom of a wrapped row. */
/* flex:0 0 auto — identity does not shrink.
   Both this and the search field were shrinkable, so on a 1440 laptop the
   search kept its 260px and the company name was the thing that got an
   ellipsis. The search is a tool and can lose 30px without anyone noticing;
   the name is the reader's own business and reads as a bug when it is cut. */
.app-user{margin-top:0;gap:.7rem;flex:0 0 auto;min-width:0}
.app-user__t{display:flex;flex-direction:column;line-height:1.25;min-width:0;
  max-width:230px;overflow:hidden;text-align:right;align-items:flex-end}
/* max-width:100%, not a pixel figure.
   A fixed cap was 190px here and it was wrong: when the row runs out of room
   this column shrinks below that, and because the column aligns to flex-end an
   over-wide child spills to the LEFT — the company name ran back over the
   notification bell instead of ending in an ellipsis. Sizing the name against
   its own parent means it can never be wider than the space it was given. */
.app-user__t b{font-weight:600;font-size:.92rem;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app-user__t span{color:var(--text-mut);font-size:.76rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase}
.app-user .av{flex:0 0 auto}

@media (max-width:1180px){
  .app-search{flex-basis:200px}
  .app-top__r{gap:.6rem}
}
@media (max-width:900px){
  /* The sidebar is gone and a phone app bar has taken over the top of the
     screen. The search would be the third search box in view; it moves onto
     its own full-width row underneath rather than being deleted, because on a
     phone it is the fastest way to reach anything. */
  .app-top__r{width:100%;flex-wrap:wrap;justify-content:flex-end}
  .app-search{order:2;flex:1 1 100%}
  .app-bell,.app-user{order:1}
  .app-user{margin-right:auto}
}
@media (max-width:640px){
  .app-user__t{max-width:46vw}
  .app-top__h{flex-basis:100%}
}

/* ---- the search page ------------------------------------------------
   The big field at the top of portal/search.php, and the result rows.
   A hit is a link and has to read as one at a glance, so it gets the same
   hairline-and-lift treatment as a stat card rather than table styling —
   people scan this list, they do not read it. */
.dw-search-big{display:flex;gap:.7rem;align-items:center;position:relative}
.dw-search-big__i{position:absolute;left:16px;top:50%;transform:translateY(-50%);
  color:var(--text-mut);display:inline-flex;pointer-events:none}
.dw-search-big__i svg{width:19px;height:19px;display:block}
.dw-search-big input{flex:1 1 auto;min-width:0;height:56px;
  padding:0 1.1rem 0 46px;border-radius:999px;
  background:rgba(255,255,255,.045);border:1px solid var(--glass-brd);
  color:var(--text);font-family:var(--font-body);font-size:1rem}
.dw-search-big input::placeholder{color:var(--text-mut)}
.dw-search-big input:focus{outline:none;border-color:var(--line-2);
  background:rgba(255,255,255,.07);box-shadow:0 0 0 3px rgba(0,119,255,.14)}
.dw-search-big input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.dw-search-big .btn{flex:0 0 auto}

.dw-hits{display:flex;flex-direction:column;gap:.5rem}
.dw-hit{display:flex;align-items:center;gap:.9rem;min-width:0;
  padding:.8rem .95rem;border-radius:var(--radius-sm);
  border:1px solid transparent;color:inherit;text-decoration:none;
  transition:background .3s var(--ease),border-color .3s var(--ease),
             transform .3s var(--ease)}
.dw-hit:hover{background:rgba(255,255,255,.04);border-color:var(--line-2);
  transform:translateX(3px)}
.dw-hit:focus-visible{outline:2px solid var(--aqua-bright);outline-offset:2px}
.dw-hit__i{flex:0 0 auto;width:32px;height:32px;border-radius:9px;
  display:grid;place-items:center;color:var(--aqua-bright);
  background:rgba(0,119,255,.10);border:1px solid var(--line-2)}
.dw-hit__i svg{width:16px;height:16px;display:block}
.dw-hit__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;line-height:1.3}
.dw-hit__t b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-hit__t span{color:var(--text-mut);font-size:.82rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dw-hit__n{flex:0 0 auto;font-family:var(--font-display);font-weight:600;
  font-variant-numeric:tabular-nums;font-size:.92rem}

@media (max-width:640px){
  .dw-search-big{flex-wrap:wrap}
  .dw-search-big input{flex-basis:100%;height:52px}
  .dw-search-big .btn{flex:1 1 auto}
  /* The magnifying glass is absolute against the form, and once the form wraps
     to two rows "top:50%" is the gap between the input and the button — the
     glyph fell out of the field it belongs to and sat under it. Half of the
     input's own 52px is where it goes, whether the button is beside it or
     under it. */
  .dw-search-big__i{top:26px}

  /* A result becomes two rows.
     Everything in .dw-hit is a flex sibling that refuses to shrink — the
     amount, the status pill — and at 350px they take their width first and
     the title gets what is left, which was a four-character column. Giving
     the title a basis of "the row minus the icon" forces the amount and the
     pill onto a second line, indented to sit under the title rather than
     under the icon.

     The amount used to be display:none here. Hiding the one number on an
     invoice to save a line is the wrong trade: it is the thing the reader
     opened the search for. */
  .dw-hit{flex-wrap:wrap;row-gap:.4rem}
  /* 60px, not the 46px the icon and the gap actually occupy. A flex basis of
     exactly "the row minus the icon" is a rounding error away from being one
     pixel too wide, and wrap happens before shrink — so the title dropped to
     its own line and left the icon sitting alone above it. The slack is spare
     room the title grows back into, because flex-grow is 1. */
  .dw-hit__t{flex:1 1 calc(100% - 60px)}
  /* The title wraps rather than ellipsising. "Elite Roofing — main s…" is a
     result you cannot tell apart from the next one; two lines costs nothing
     on a page that is a list. The subtitle keeps its ellipsis — it is context,
     not identity. */
  .dw-hit__t b{white-space:normal;overflow:visible}
  .dw-hit__n{font-size:.88rem}
  .dw-hit__t + .dw-hit__n,.dw-hit__t + .pill{margin-left:46px}
}

/* ============================================================
   THE COMMAND DECK
   ------------------------------------------------------------
   The band at the top of the dashboard: one score on the left,
   what went right and what to do next stacked on the right.

   The score column is fixed at 340px rather than a fraction,
   because a half-circle gauge has one good size and stretching
   it to half a 1600px screen makes the whole page look like a
   car dashboard. The right column takes whatever is left, which
   is the column that actually benefits from width — the moves
   in it are sentences.
   ============================================================ */
.dw-hero{display:grid;grid-template-columns:340px minmax(0,1fr);
  gap:24px;align-items:start;margin-bottom:1.4rem}
.dw-hero__score{display:flex;flex-direction:column;align-items:center;
  padding-top:1.6rem}
.dw-hero__side{min-width:0}

/* The pillars the score is made of. Without these the number is an
   oracle: it tells you 62 and gives you no way to argue with it or
   act on it. With them it is an argument you can check. */
.dw-pillars{width:100%;margin-top:1.5rem;padding-top:1.2rem;
  border-top:1px solid var(--line);display:flex;flex-direction:column;gap:.9rem}
.dw-pillar{display:flex;flex-direction:column;gap:.4rem;min-width:0}
.dw-pillar__t{display:flex;align-items:baseline;justify-content:space-between;
  gap:.8rem;min-width:0}
.dw-pillar__t b{font-weight:600;font-size:.88rem;flex:0 0 auto}
.dw-pillar__t span{font-size:.78rem;color:var(--text-mut);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}

/* The empty-account welcome that stands in for the score. */
.dw-hero__new{display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:.6rem;padding:1.4rem .4rem 1rem}
.dw-hero__newico{width:46px;height:46px;border-radius:50%;display:grid;
  place-items:center;color:var(--aqua-bright);background:rgba(0,119,255,.10);
  border:1px solid var(--line-2)}
.dw-hero__newico svg{width:21px;height:21px;display:block}
.dw-hero__new b{font-family:var(--font-display);font-size:1.15rem;font-weight:700}
.dw-hero__new span{font-size:.88rem;color:var(--text-mut);max-width:34ch;line-height:1.55}
.dw-hero__new .btn{margin-top:.4rem}

.dw-wins{display:flex;flex-direction:column;gap:.7rem}

/* 1100px, not 900px. The breakpoint is set by the score column plus a
   readable line of text beside it, not by the sidebar: below this the
   moves column is down to about 300px and every one of them wraps to
   three lines. */
@media (max-width:1100px){
  .dw-hero{grid-template-columns:1fr;gap:18px}
  .dw-hero__score{padding-top:1.2rem}
  .dw-score svg{max-width:300px}
}
