/* =====================================================================
   Air — stylesheet
   Type scale, grid, tokens and component geometry measured from air.inc
   ===================================================================== */

/* ---------- fonts ---------- */
@font-face {
  font-family: "Control Compressed";
  src: url("../assets/fonts/control-compressed/ControlCompressed-Super-Web.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap
}

@font-face {
  font-family: "Control TNT";
  src: url("../assets/fonts/control-cursive/ControlUpright-RegularTNT-Web.woff2") format("woff2");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap
}

@font-face {
  font-family: "Control";
  src: url("../assets/fonts/control-cursive/ControlUpright-Regular-Web.woff2") format("woff2");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap
}

@font-face {
  font-family: "Control Light";
  src: url("../assets/fonts/control-cursive/ControlUpright-LightTNT-Web.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap
}

@font-face {
  font-family: "Control Cursive";
  src: url("../assets/fonts/control-cursive/ControlCursive-RegularTNT-Web.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap
}

/* ---------- tokens ---------- */
:root {
  --white: #fff;
  --white-rgb: 255, 255, 255;
  --black: #1b1b1b;
  --black-void: #000;
  --accent: #4c96f7;
  --blue: #33b6ff;
  --sky: #1095ed;
  --altitude: #0563e9;
  --haze: #f5f5f5;
  --column-gutter: 24px;
  --page-pad: 24px;
  --hdr-h: 72px;
  --radius-bar: 10px;
  --ease-out: cubic-bezier(0, 0, .2, 1);
  --ease-in-out: cubic-bezier(.4, 0, .2, 1);
  --font-head: "Control TNT", Arial, Helvetica, sans-serif;
  --font-body: "Control", Arial, Helvetica, sans-serif;
  --font-display: "Control Compressed", Arial, Helvetica, sans-serif;
  --font-cursive: "Control Cursive", "Control TNT", cursive;
}

*,
*::before,
*::after {
  box-sizing: border-box
}

html {
  -webkit-text-size-adjust: 100%
}

body {
  margin: 0;
  background: #0b4fa0;
  color: var(--white);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
video {
  display: block;
  max-width: 100%
}

a {
  color: inherit;
  text-decoration: none
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer
}

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

/* ---------- type scale ---------- */
.u-h1 {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(56px, min(17vw, 26vh), 245px);
  line-height: .85;
  letter-spacing: normal;
  margin: 0;
}

/* the pinned triptych words use the smaller of the two display sizes */
.u-h1-small {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: min(min(20vw, 30vh), 12.5rem);
  line-height: .85;
  letter-spacing: normal;
  margin: 0;
}

.u-h2-large {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(34px, 3.9vw, 56px);
  line-height: 1;
  margin: 0
}

h2.pillar__title,
.s h2:not(.u-h1):not(.u-h1-small):not(.u-h2-large) {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 40px;
  line-height: 40px;
  margin: 0
}

.s h3 {
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.1;
  margin: 0
}

.s h4,
.s h3.section-heading--small {
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 20px;
  line-height: 30px;
  margin: 0
}

.u-body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  margin: 0
}

.cursive {
  font-family: var(--font-cursive);
  font-style: normal;
  font-weight: 400
}

.tcenter {
  text-align: center
}

/* ---------- WebGL canvas ---------- */
.canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none
}

.canvas canvas {
  width: 100%;
  height: 100%;
  display: block
}

/* ---------- grid ---------- */
.grid {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--page-pad);
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--column-gutter);
}

.col--4-9 {
  grid-column: 4 / span 6
}

@media (max-width:860px) {
  .col--4-9 {
    grid-column: 1 / -1
  }
}

main {
  position: relative;
  z-index: 1
}

.s {
  position: relative;
  width: 100%
}

/* =====================================================================
   Header
   ===================================================================== */
.hdr {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  height: var(--hdr-h);
  pointer-events: none
}

.hdr::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 132px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(0, 12, 38, .55) 0%, rgba(0, 12, 38, .34) 38%, rgba(0, 12, 38, .12) 72%, rgba(0, 12, 38, 0) 100%)
}

.hdr__grid {
  position: relative;
  z-index: 1
}

.hdr__grid {
  position: relative;
  height: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--page-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.hdr__nav {
  display: flex;
  align-items: stretch;
  height: var(--hdr-h);
  pointer-events: auto
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%
}

.nav-item__btn {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 100%;
  padding: 0 12px 0 0;
  margin-right: 12px;
  font-family: var(--font-head);
  font-size: 14px;
  line-height: 21px;
  font-weight: 500;
  color: #fff;
  opacity: .92;
  transition: opacity .2s var(--ease-out);
}

.nav-item__btn:hover {
  opacity: 1
}

.nav-item__arrow {
  width: 16px;
  height: 16px;
  display: block;
  transition: transform .28s var(--ease-out)
}

.nav-item__arrow svg {
  width: 16px;
  height: 16px;
  display: block
}

.nav-item.is-open .nav-item__arrow {
  transform: rotate(180deg)
}

.nav-sub {
  position: absolute;
  top: calc(100% + 15px);
  left: -16px;
  width: 757px;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--haze);
  border-radius: 16px;
  padding: 20px 0;
  color: var(--black);
  box-shadow: 0 24px 60px -20px rgba(0, 20, 60, .35);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px) scale(.985);
  transform-origin: top left;
  transition: opacity .24s var(--ease-out), transform .3s var(--ease-out), visibility .24s;
}

.nav-sub--wide {
  width: 1080px
}

.nav-item.is-open .nav-sub {
  opacity: 1;
  visibility: visible;
  transform: none
}

.nav-sub__cols {
  display: flex;
  gap: 0;
  padding-inline: 1px
}

.nav-sub__col {
  flex: 1 1 0;
  padding: 0 20px
}

.nav-sub__col--media {
  flex: 0 0 300px;
  display: flex;
  align-items: stretch
}

.nav-sub--wide .nav-sub__col--media {
  flex: 0 0 280px
}

.nav-sub__label {
  font-family: var(--font-head);
  font-size: 12px;
  line-height: 18px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: rgba(27, 27, 27, .45);
  margin: 0 0 8px 19px;
}

.nav-sub__list {
  display: flex;
  flex-direction: column
}

.nav-sub__item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px;
  border-radius: 8px;
  cursor: default;
  user-select: none;
  transition: background .18s var(--ease-out);
}

.nav-sub__item:hover {
  background: var(--haze)
}

.nav-sub__icon {
  flex: 0 0 54px;
  width: 54px;
  height: 54px;
  border-radius: 8px;
  background: var(--haze);
  display: grid;
  place-items: center
}

.nav-sub__icon img {
  width: 23px;
  height: 23px;
  object-fit: contain
}

.nav-sub__body {
  display: flex;
  flex-direction: column
}

.nav-sub__title {
  font-family: var(--font-head);
  font-size: 15px;
  line-height: 23px;
  font-weight: 500
}

.nav-sub__desc {
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 19.5px;
  font-weight: 500;
  color: rgba(27, 27, 27, .62)
}

.hdr__logo {
  position: absolute;
  left: 50%;
  top: 0;
  height: var(--hdr-h);
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  pointer-events: auto;
}

.hdr__logo-svg {
  width: 66px;
  height: 44px;
  overflow: visible;
  opacity: 0;
  transition: opacity .25s var(--ease-out)
}

.hdr__logo-svg path {
  stroke: #fff;
  fill: none;
  stroke-width: var(--stroke-w, .156);
  stroke-linecap: round;
  stroke-linejoin: round
}

.hdr__logo-svg circle {
  fill: #fff
}

body.logo-visible .hdr__logo-svg {
  opacity: 1
}

.hdr__ctas {
  display: flex;
  align-items: center;
  gap: 12px;
  pointer-events: auto
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-head);
  font-size: 14px;
  line-height: 21px;
  font-weight: 500;
  height: 38px;
  padding: 0 16px;
  border-radius: 8px;
  border: 1px solid transparent;
  white-space: nowrap;
  transition: background .2s var(--ease-out), color .2s var(--ease-out), border-color .2s var(--ease-out), transform .2s var(--ease-out);
}

.btn--ghost {
  padding: 0 8px
}

.btn--ghost:hover {
  opacity: .75
}

.btn--outline {
  border-color: rgba(255, 255, 255, .75);
  color: #fff
}

.btn--outline:hover {
  background: #fff;
  color: var(--black);
  border-color: #fff
}

.btn--white {
  background: #fff;
  color: var(--black);
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  word-spacing: 0.14em;
}

.btn--white:hover {
  background: rgba(255, 255, 255, .86)
}

/* icon-only siblings of the primary CTA — same surface, square footprint */
.btn--icon {
  width: 38px;
  padding: 0;
  flex: 0 0 auto;
  letter-spacing: 0;
  word-spacing: 0
}

.btn--icon svg {
  width: 17px;
  height: 17px;
  display: block
}

.hdr__ctas {
  gap: 8px
}

.btn--dark {
  background: var(--black);
  color: #fff
}

.btn--dark:hover {
  background: #000
}

.btn--lg {
  height: 38px;
  padding: 0 18px
}

/* on phones the nav collapses into a third icon button, matched to the
   WhatsApp and X ones — a chevron that flips up while the menu is open */
.hdr__burger {
  display: none;
  pointer-events: auto;
  cursor: pointer
}

.hdr__burger svg {
  width: 17px;
  height: 17px;
  display: block;
  transition: transform .3s var(--ease-out)
}

body.nav-open .hdr__burger svg {
  transform: rotate(180deg)
}

/* ---------- time-of-day switcher ---------- */
/* The lit slot is one disc owned by the rail, not a background that switches
   from one button to another: the rail carries the index of the chosen hour and
   the disc travels to it, so the change of hour reads as a move rather than as
   one light going out and another coming on. Every measurement the disc needs
   is a variable here, which is what lets the same rule serve the column on a
   desktop and the row along the bottom of a phone. */
.tod {
  --tod-slot: 26px;
  --tod-knob: 26px;
  --tod-gap: 2px;
  --tod-pad: 4px;
  --tod-i: 0;
  --tod-step: calc(var(--tod-slot) + var(--tod-gap));
  --tod-inset: calc(var(--tod-pad) + (var(--tod-slot) - var(--tod-knob)) / 2);
  position: fixed;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 55;
  display: flex;
  flex-direction: column;
  gap: var(--tod-gap);
  padding: var(--tod-pad);
  border-radius: 14px;
  background: rgba(255, 255, 255, .12);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.tod::before {
  content: '';
  position: absolute;
  left: var(--tod-inset);
  top: var(--tod-inset);
  width: var(--tod-knob);
  height: var(--tod-knob);
  border-radius: 10px;
  background: #fff;
  translate: 0 calc(var(--tod-i) * var(--tod-step));
  transition: translate .42s var(--ease-out), border-radius .25s var(--ease-out);
  pointer-events: none
}

.tod button {
  position: relative;
  width: var(--tod-slot);
  height: var(--tod-slot);
  border-radius: 10px;
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, .55);
  transition: color .25s var(--ease-out)
}

.tod button svg {
  width: 15px;
  height: 15px
}

.tod button:hover {
  color: #fff
}

.tod button.is-active {
  color: var(--black)
}

/* =====================================================================
   1 · hero  (the glass wordmark lives on the WebGL canvas)
   ===================================================================== */
.s--hero {
  height: calc(100vh + 120px)
}

/* =====================================================================
   2 · intro
   ===================================================================== */
.s--intro {
  padding-top: 48px;
  padding-bottom: 56px
}

.s--intro .u-h2-large {
  margin-bottom: 16px
}

.s--intro .u-body {
  margin-bottom: 32px;
  color: #fff
}

.s--intro .btn--outline {
  margin-inline: auto
}

.prompt-pill {
  --pill-w: auto;
  margin: 60px auto 0;
  width: max-content;
  max-width: calc(100% - 48px);
  display: flex;
  align-items: center;
  gap: 10px;
  height: 34px;
  padding: 0 18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .28);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: var(--font-head);
  font-size: 14px;
  line-height: 1;
  font-weight: 500;
  transition: width .5s var(--ease-in-out);
}

.prompt-pill__icon img {
  width: 14px;
  height: 14px;
  opacity: .9
}

.prompt-pill__text {
  white-space: nowrap;
  transition: opacity .35s var(--ease-out)
}

.prompt-pill.is-swapping .prompt-pill__text {
  opacity: 0
}

/* --- pillar cards --- */
.pillars {
  display: flex;
  justify-content: center;
  gap: var(--column-gutter);
  margin-top: 20px;
  padding-inline: var(--page-pad);
  max-width: 1440px;
  margin-inline: auto;
}

.pillar {
  position: relative;
  flex: 0 1 351px;
  min-width: 0;
  height: 535px;
  padding: 21px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0);
  background: rgba(255, 255, 255, 0);
  display: flex;
  flex-direction: column;
  transition: background 1.1s cubic-bezier(.16, 1, .3, 1), border-color 1.1s cubic-bezier(.16, 1, .3, 1), opacity 1.1s cubic-bezier(.16, 1, .3, 1);
}

.pillar.is-active {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(255, 255, 255, .22);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px)
}

.pillar__media {
  position: relative;
  flex: 1 1 auto;
  margin: 0 0 22px;
  overflow: visible;
  opacity: .34;
  transform: scale(.985);
  transition: opacity 1.1s cubic-bezier(.16, 1, .3, 1), transform 1.2s cubic-bezier(.16, 1, .3, 1)
}

.pillar.is-active .pillar__media {
  opacity: 1;
  transform: none
}

.pillar__title {
  margin: 0 0 8px;
  transition: color .9s cubic-bezier(.16, 1, .3, 1), opacity .9s cubic-bezier(.16, 1, .3, 1)
}

.pillar__copy {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  margin: 0;
  color: rgba(255, 255, 255, .6);
  transition: color .9s cubic-bezier(.16, 1, .3, 1)
}

.pillar:not(.is-active) .pillar__title {
  color: rgba(255, 255, 255, .55)
}

.pillar:not(.is-active) .pillar__copy {
  color: rgba(255, 255, 255, .4)
}

.pillar.is-active .pillar__copy {
  color: rgba(255, 255, 255, .88)
}

/* Understand — photo with smart-tag panels */
.explode {
  position: absolute;
  inset: 0
}

.explode__img {
  position: absolute;
  left: 0;
  top: 2%;
  width: 63%;
  border-radius: 8px;
  object-fit: cover;
  box-shadow: 0 18px 40px -14px rgba(0, 20, 60, .55);
  transition: transform .9s var(--ease-in-out), opacity .6s var(--ease-out);
}

.explode__img--1 {
  z-index: 4
}

.explode__img--2 {
  z-index: 3;
  opacity: 0;
  transform: translate(3%, 3%) rotate(2deg)
}

.explode__img--3 {
  z-index: 2;
  opacity: 0;
  transform: translate(6%, 6%) rotate(4deg)
}

.explode__img--4 {
  z-index: 1;
  opacity: 0;
  transform: translate(9%, 9%) rotate(6deg)
}

.explode__info {
  position: absolute;
  z-index: 6;
  opacity: 0;
  border-radius: 6px;
  filter: drop-shadow(0 10px 26px rgba(0, 20, 60, .42));
  transition: opacity .55s var(--ease-out), transform .8s var(--ease-out);
}

.explode__info--1 {
  width: 60%;
  right: 2%;
  top: 26%;
  transform: translate(10px, 8px)
}

.explode__info--2 {
  width: 55%;
  right: 4%;
  top: 53%;
  transform: translate(10px, 8px)
}

.explode__info--3 {
  display: none
}

.explode__info--4 {
  display: none
}

.explode__tag {
  position: absolute;
  z-index: 7;
  height: 14px;
  width: auto;
  opacity: 0;
  transition: opacity .5s var(--ease-out), transform .7s var(--ease-out)
}

.explode__tag--a {
  top: 10%;
  right: 6%;
  transform: translateY(6px)
}

.explode__tag--b {
  top: 20%;
  left: -4%;
  transform: translateY(6px)
}

.explode__tag--c {
  top: 46%;
  left: -6%;
  transform: translateY(6px)
}

.explode__tag--d {
  bottom: 26%;
  right: -2%;
  transform: translateY(6px)
}

.explode__tag--e {
  bottom: 10%;
  left: 2%;
  transform: translateY(6px)
}

.explode__tag--f {
  top: 2%;
  left: 30%;
  transform: translateY(6px)
}

.pillar.is-active .explode__info--1,
.pillar.is-active .explode__info--2 {
  opacity: 1;
  transform: none
}

.pillar.is-active .explode__tag {
  opacity: .95;
  transform: none
}

/* Organize — folder grid → stack */
.pillar .folders {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 9px;
  transition: opacity .5s var(--ease-out), transform .8s var(--ease-in-out);
}

.folder {
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: 8px;
  padding: 7px;
  background: rgba(255, 255, 255, .06);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 0;
}

.folder__img {
  flex: 1 1 auto;
  border-radius: 4px;
  overflow: hidden;
  min-height: 0
}

.folder__img img {
  width: 100%;
  height: 100%;
  object-fit: cover
}

.folder span {
  font-size: 11px;
  line-height: 14px;
  color: rgba(255, 255, 255, .85)
}

.pillar .stack {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity .5s var(--ease-out)
}

.stack__card {
  position: absolute;
  width: 44%;
  border-radius: 6px;
  box-shadow: 0 20px 44px -16px rgba(0, 20, 60, .6);
  transition: transform .9s var(--ease-in-out);
}

.stack__card--1 {
  transform: rotate(-9deg) translate(-16%, 4%)
}

.stack__card--2 {
  transform: rotate(-2deg) translate(-4%, -2%)
}

.stack__card--3 {
  transform: rotate(6deg) translate(10%, 2%)
}

.stack__card--4 {
  transform: rotate(14deg) translate(22%, 8%)
}

.stack__play {
  position: absolute;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: var(--black);
  display: grid;
  place-items: center;
}

.stack__play svg {
  width: 18px;
  height: 18px
}

.pillar[data-pillar="1"].is-active .folders {
  opacity: 0;
  transform: scale(.94)
}

.pillar[data-pillar="1"].is-active .stack {
  opacity: 1
}

/* Scale — smart-resize canvas */
.resize {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center
}

.resize__canvas {
  position: absolute;
  inset: 8% 2%;
  border-radius: 6px;
  background-image: radial-gradient(rgba(255, 255, 255, .5) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: 0;
  transition: opacity .6s var(--ease-out);
}

.resize__bottle {
  position: absolute;
  width: 38%;
  transition: transform .9s var(--ease-in-out), opacity .5s
}

.resize__panel {
  position: absolute;
  right: -2%;
  top: 16%;
  width: 58%;
  filter: drop-shadow(0 12px 30px rgba(0, 20, 60, .45));
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .5s var(--ease-out), transform .7s var(--ease-out)
}

.resize__panel--detail {
  opacity: 0
}

.pillar[data-pillar="2"].is-active .resize__canvas {
  opacity: 1
}

.pillar[data-pillar="2"].is-active .resize__bottle {
  transform: translate(-16%, 4%) scale(1.04)
}

.pillar[data-pillar="2"].is-active .resize__panel {
  opacity: 1;
  transform: none
}

.pillar[data-pillar="2"].is-active .resize__panel--detail {
  opacity: 0
}

/* =====================================================================
   3 · customers / 9 · integrations marquees
   ===================================================================== */
.s--logos {
  padding: 56px 0 64px
}

.s--logos h4,
.s--integrations h4 {
  margin-bottom: 0
}

.marquee {
  margin-top: 44px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent)
}

.marquee__row {
  display: flex;
  align-items: center;
  gap: 80px;
  width: max-content;
  will-change: transform
}

.marquee__row img {
  height: 80px;
  width: 80px;
  object-fit: contain;
  opacity: .92;
  filter: brightness(0) invert(1)
}

/* wordmarks are wide: boxing them into a square is what made this row read as
   a line of tiny marks. They keep their own ratio here and simply run taller. */
.marquee--sm .marquee__row img {
  height: 58px;
  width: auto;
  max-width: 168px
}

.marquee--sm .marquee__row {
  gap: 96px
}

.marquee--sm {
  margin-top: 36px
}

.s--integrations {
  padding: 73px 0 72px
}

/* =====================================================================
   4 · coming soon
   ===================================================================== */
.s--library {
  padding-top: 20px;
  position: relative
}

.glow {
  position: absolute;
  left: 50%;
  top: -8%;
  width: 62%;
  transform: translateX(-50%);
  opacity: .5;
  mix-blend-mode: screen;
  pointer-events: none;
  filter: blur(6px)
}

.chip {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .4);
  background: rgba(255, 255, 255, .08);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-head);
  font-size: 13px;
  line-height: 1;
  font-weight: 500;
  margin-bottom: 26px;
}

.s--library h2 {
  margin-bottom: 18px
}

.s--library .u-body {
  max-width: 440px;
  margin: 0 auto 30px;
  color: rgba(255, 255, 255, .92)
}

.notify {
  display: flex;
  gap: 10px;
  justify-content: center;
  align-items: center
}

.notify input {
  width: 336px;
  max-width: 60vw;
  height: 40px;
  padding: 0 16px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, .35);
  background: rgba(255, 255, 255, .12);
  color: #fff;
  font-family: var(--font-body);
  font-size: 14px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.notify input::placeholder {
  color: rgba(255, 255, 255, .6)
}

.notify input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, .7)
}

.notify .btn {
  height: 40px
}

.ui-panel {
  position: relative;
  margin: 56px auto 0;
  width: min(1064px, calc(100% - 48px));
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 40px 90px -30px rgba(0, 26, 72, .55);
  transform: translateY(40px) scale(.96);
  opacity: 0;
  transition: transform 1.1s var(--ease-out), opacity .8s var(--ease-out);
}

.ui-panel.is-in {
  transform: none;
  opacity: 1
}

.ui-panel video {
  width: 100%;
  display: block
}

/* =====================================================================
   5 · statement
   ===================================================================== */
.s--statement {
  padding: 16px 0 32px;
  min-height: 56vh;
  display: flex;
  align-items: center;
  overflow: hidden
}

.statement {
  padding-inline: var(--page-pad);
  width: 100%;
  max-width: 1440px;
  margin-inline: auto
}

.statement .line {
  display: block;
  overflow: hidden
}

.statement .line i {
  display: block;
  font-style: normal;
  transform: translateY(105%);
  opacity: 0;
  transition: none;
  will-change: transform, opacity
}

.statement.is-in .line i {
  transform: none;
  opacity: 1;
  transition: transform 1s cubic-bezier(.16, 1, .3, 1), opacity .8s cubic-bezier(.16, 1, .3, 1)
}

.statement .line:nth-child(1) i {
  transition-delay: 0s
}

.statement .line:nth-child(2) i {
  transition-delay: .09s
}

.statement .line:nth-child(3) i {
  transition-delay: .18s
}

.statement .line:nth-child(4) i {
  transition-delay: .27s
}

.statement .line:nth-child(n+5) i {
  transition-delay: .36s
}

/* =====================================================================
   6 · product demo
   ===================================================================== */
.s--demo {
  padding: 20px 0 24px
}

.demo {
  width: min(914px, calc(100% - 48px));
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center
}

.demo__frame {
  position: relative;
  width: min(695px, 100%);
  aspect-ratio: 695/496;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255, 255, 255, .08);
  box-shadow: 0 40px 90px -34px rgba(0, 26, 72, .5);
  transform: scale(var(--demo-scale, 1));
  transform-origin: center top;
  will-change: transform;
}

.demo__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .5s var(--ease-out)
}

.demo__media.is-active {
  opacity: 1
}

.tabs {
  position: relative;
  display: flex;
  justify-content: space-between;
  width: min(727px, 100%);
  height: 44px;
  margin-top: 24px;
  padding: 4px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.tab {
  position: relative;
  z-index: 1;
  flex: 0 1 auto;
  padding: 0 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  border-radius: 8px;
  font-family: var(--font-head);
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, .9);
  transition: color .35s var(--ease-out);
}

.tab img {
  width: 14px;
  height: 14px;
  object-fit: contain;
  filter: brightness(0) invert(1);
  transition: filter .35s
}

.tabs__indicator {
  position: absolute;
  left: 0;
  top: 2px;
  height: 40px;
  border-radius: 8px;
  background: #fff;
  transition: transform .45s var(--ease-in-out), width .45s var(--ease-in-out);
  overflow: hidden
}

.tabs__indicator::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: var(--tab-progress, 0%);
  background: var(--haze)
}

.tab.is-active {
  color: var(--black)
}

.tab.is-active img {
  filter: none
}

/* =====================================================================
   7 · features
   ===================================================================== */
.s--features {
  padding: 72px 0 0
}

.s--features h3 {
  margin-bottom: 14px
}

.s--features .u-body {
  max-width: 460px;
  margin-inline: auto;
  color: rgba(255, 255, 255, .85)
}

.fgrid {
  width: min(1102px, calc(100% - 48px));
  margin: 64px auto 0;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 24px;
}

.fcard {
  /* the copy and the visual are one centred group, with matching air above and
     below, instead of copy pinned to the top and art pinned to the floor */
  position: relative;
  grid-column: span 7;
  height: 418px;
  padding: 34px 32px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .07);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
}

/* The lift uses `translate`, not `transform`: these cards also carry .reveal,
   which owns transform for the entry, and the two would fight. .reveal also
   owns the transition and sits later in this file, so the entry's own timings
   are restated here rather than lost. */
.fcard,
.fcard.reveal {
  transition: opacity .8s var(--ease-out), transform .9s var(--ease-out),
    translate .5s var(--ease-out), border-color .4s var(--ease-out),
    background .4s var(--ease-out), box-shadow .5s var(--ease-out);
}

/* the card answers the pointer the way the pricing tiles do: it lifts a
   little, its glass brightens and the frame around it firms up — the motion
   study inside is already playing, this is the card acknowledging you */
.fcard:hover,
.fgrid[data-auto="true"]:not([data-manual]) .fcard.is-playing {
  translate: 0 -4px;
  border-color: rgba(255, 255, 255, .42);
  background: rgba(255, 255, 255, .12);
  box-shadow: 0 26px 48px -26px rgba(4, 26, 66, .6), 0 0 0 1px rgba(255, 255, 255, .1)
}

.fcard__media {
  transition: scale .5s var(--ease-out)
}

.fcard:hover .fcard__media,
.fgrid[data-auto="true"]:not([data-manual]) .fcard.is-playing .fcard__media {
  scale: 1.018
}

.fgrid>.fcard:nth-child(2),
.fgrid>.fcard:nth-child(3) {
  grid-column: span 5
}

.fgrid>.fcard:nth-child(4) {
  grid-column: span 7
}

/* One spacing value runs down every card: the 20px flex gap. The title used to
   add 4px on top of it and then a further 5px of its own leading — 3px below
   the title's baseline box and 2px above the copy's — so the space under the
   heading measured 29px against the 20px between the copy and the visual, on
   every card. The leading is paid back here, which lands the gap under the
   title on the same 20px as everything else in the card. */
.fcard h4 {
  margin-bottom: -5px
}

.fcard p {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  margin: 0;
  color: rgba(255, 255, 255, .72)
}

.fcard__media {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  overflow: hidden;
  border-radius: 10px
}

.fcard__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border-radius: inherit;
  display: block
}

/* =====================================================================
   8 · one plan
   ===================================================================== */
/* the neighbouring sections overlap it by a few pixels top and bottom, so the
   card is lifted into its own stacking context and keeps the whole of itself
   hoverable */
.s--plan {
  padding: 32px 0 0;
  position: relative;
  z-index: 3
}

/* A normal card, sized and spaced like the bento cards above it: same width,
   same radius, same border. Its colour is an animated mesh on its own layer so
   the copy stays selectable text rather than sitting on a flattened image. */
.plan {
  position: relative;
  width: min(1102px, calc(100% - 48px));
  margin-inline: auto;
  min-height: 192px;
  padding: 34px 32px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  border: 1px solid rgba(255, 255, 255, .24);
  overflow: hidden;
  background: linear-gradient(100deg, rgba(33, 110, 214, .55) 0%, rgba(33, 110, 214, .2) 40%, rgba(255, 255, 255, .08) 100%);
}

.plan>* {
  position: relative;
  z-index: 2
}

/* The card stays glass: its own translucent background is what you see, with
   the sky still coming through it. The gradient is not a surface under the
   card, it is something that gathers on the right and fades out before it
   reaches the copy — so the whole stack below is masked once, here, and every
   layer inherits that fade. */
/* the card answers the pointer the same way the feature cards do */
.plan,
.plan.reveal {
  transition: opacity .8s var(--ease-out), transform .9s var(--ease-out),
    translate .5s var(--ease-out), border-color .4s var(--ease-out),
    box-shadow .5s var(--ease-out)
}

.plan:hover {
  translate: 0 -6px;
  border-color: rgba(255, 255, 255, .62);
  box-shadow: 0 34px 64px -30px rgba(4, 26, 66, .68), inset 0 1px 0 rgba(255, 255, 255, .34)
}

/* the gradient opens up a little under the pointer, the way the pricing tiles do */
.plan__bg {
  transition: opacity .5s var(--ease-out)
}

.plan:hover .plan__bg {
  opacity: 1
}

.plan .plan__bg {
  opacity: .88
}

.plan__cta {
  transition: background .3s var(--ease-out), color .3s var(--ease-out),
    scale .4s var(--ease-out), box-shadow .4s var(--ease-out)
}

.plan:hover .plan__cta {
  scale: 1.035;
  box-shadow: 0 14px 28px -14px rgba(4, 26, 66, .55)
}

.plan__bg {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(100deg, transparent 0%, rgba(0, 0, 0, .08) 26%, rgba(0, 0, 0, .38) 44%, rgba(0, 0, 0, .78) 64%, #000 82%);
  mask-image: linear-gradient(100deg, transparent 0%, rgba(0, 0, 0, .08) 26%, rgba(0, 0, 0, .38) 44%, rgba(0, 0, 0, .78) 64%, #000 82%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat
}

/* ---------------------------------------------------------------------
   A living mesh, not a still plate.
   The card it is modelled on never holds a pose: wide soft fields of colour
   travel across the panel while the hue inside each of them keeps turning
   over, so the mix never repeats. Same construction here, painted entirely
   out of Follow up's own gradient — one base plate plus three masked copies,
   each panning through a different part of the image on its own clock.
   --------------------------------------------------------------------- */
.plan {
  --plate: url("https://cdn.calendlycms.com/follow-active-bg-gradient-1.png")
}

.plan__plate {
  position: absolute;
  inset: -26%;
  display: block;
  background-image: var(--plate);
  background-size: cover;
  background-position: 50% 74%;
  opacity: .88;
  filter: blur(16px) saturate(1.22);
  animation: gradDrift 21s ease-in-out infinite alternate;
}

/* the travelling fields. Each one is the same plate seen through a single
   very large soft blob; the blob drifts (transform) while the image slides
   underneath it (background-position), which is what makes the colour morph
   rather than merely move. */
.plan__mesh {
  position: absolute;
  inset: -14%;
  display: block;
  background-image: var(--plate);
  background-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  filter: blur(24px) saturate(1.55);
  will-change: background-position, transform;
}

.plan__mesh--a {
  opacity: .82;
  background-size: 220% 360%;
  -webkit-mask-image: radial-gradient(56% 160% at 62% 46%, #000 0%, rgba(0, 0, 0, .68) 38%, rgba(0, 0, 0, .22) 64%, transparent 84%);
  mask-image: radial-gradient(56% 160% at 62% 46%, #000 0%, rgba(0, 0, 0, .68) 38%, rgba(0, 0, 0, .22) 64%, transparent 84%);
  animation: planMeshA 27s ease-in-out infinite alternate
}

.plan__mesh--b {
  opacity: .7;
  background-size: 280% 420%;
  -webkit-mask-image: radial-gradient(46% 150% at 84% 62%, #000 0%, rgba(0, 0, 0, .6) 40%, rgba(0, 0, 0, .18) 68%, transparent 86%);
  mask-image: radial-gradient(46% 150% at 84% 62%, #000 0%, rgba(0, 0, 0, .6) 40%, rgba(0, 0, 0, .18) 68%, transparent 86%);
  animation: planMeshB 34s ease-in-out infinite alternate
}

.plan__mesh--c {
  opacity: .6;
  background-size: 320% 300%;
  -webkit-mask-image: radial-gradient(50% 140% at 44% 70%, #000 0%, rgba(0, 0, 0, .56) 38%, rgba(0, 0, 0, .16) 66%, transparent 85%);
  mask-image: radial-gradient(50% 140% at 44% 70%, #000 0%, rgba(0, 0, 0, .56) 38%, rgba(0, 0, 0, .16) 66%, transparent 85%);
  animation: planMeshC 19s ease-in-out infinite alternate
}

@keyframes planMeshA {
  0% {
    background-position: 84% 58%;
    transform: translate3d(-7%, 3%, 0)
  }

  50% {
    background-position: 12% 98%;
    transform: translate3d(7%, -4%, 0)
  }

  100% {
    background-position: 62% 68%;
    transform: translate3d(-2%, 5%, 0)
  }
}

@keyframes planMeshB {
  0% {
    background-position: 8% 88%;
    transform: translate3d(6%, -3%, 0)
  }

  50% {
    background-position: 94% 62%;
    transform: translate3d(-8%, 4%, 0)
  }

  100% {
    background-position: 30% 100%;
    transform: translate3d(4%, -2%, 0)
  }
}

@keyframes planMeshC {
  0% {
    background-position: 48% 100%;
    transform: translate3d(3%, 4%, 0)
  }

  50% {
    background-position: 78% 60%;
    transform: translate3d(-6%, -5%, 0)
  }

  100% {
    background-position: 18% 86%;
    transform: translate3d(5%, 2%, 0)
  }
}

/* ---- the pool that follows the cursor --------------------------------
   Not a white light and not a second palette: the plate itself, the same
   image registered in the same place, only brighter and more saturated,
   revealed through one wide soft circle centred on the pointer. The mask is
   positioned against the card's own box, so it lands exactly under the
   cursor; ui.js eases the two custom properties frame by frame, which is
   what gives it the flow. */
.plan__magnet {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  -webkit-mask-image: radial-gradient(circle var(--mag-r, 460px) at var(--px, 50%) var(--py, 50%), #000 0%, rgba(0, 0, 0, .74) 30%, rgba(0, 0, 0, .34) 54%, rgba(0, 0, 0, .1) 72%, transparent 86%);
  mask-image: radial-gradient(circle var(--mag-r, 460px) at var(--px, 50%) var(--py, 50%), #000 0%, rgba(0, 0, 0, .74) 30%, rgba(0, 0, 0, .34) 54%, rgba(0, 0, 0, .1) 72%, transparent 86%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  transition: opacity .55s cubic-bezier(.16, 1, .3, 1)
}

.plan__magnet .plan__plate {
  filter: saturate(1.8) brightness(1.12)
}

.plan:hover .plan__magnet {
  opacity: .62
}

@keyframes gradDrift {
  0% {
    transform: translate3d(-4%, 2%, 0) scale(1.06)
  }

  50% {
    transform: translate3d(5%, -3%, 0) scale(1.16)
  }

  100% {
    transform: translate3d(-2%, 4%, 0) scale(1.08)
  }
}

@media (prefers-reduced-motion: reduce) {

  .plan__plate,
  .plan__mesh {
    animation-duration: 44s
  }
}

.plan__copy {
  max-width: 560px
}

.plan__copy h3 {
  font-size: 30px;
  margin-bottom: 4px
}

.plan__copy h4 {
  margin-bottom: 10px
}

.plan__copy p {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  margin: 0
}

.plan .btn {
  flex: 0 0 auto
}

/* the CTA sits in the bottom-right corner of the card, with the same air on
   both edges as the copy has on its side */
.plan {
  align-items: stretch;
  padding-bottom: 64px
}

.plan__cta {
  position: absolute;
  right: 32px;
  bottom: 28px;
  height: 46px;
  padding: 0 26px;
  font-size: 15px;
  z-index: 3
}

.plan__copy {
  align-self: center
}

/* =====================================================================
   10 · storytelling triptych
   ===================================================================== */
/* height is 1.5 screens per word and the run starts half a screen early, exactly
   as the original — the pacing comes from the per-word easing in ui.js, not
   from the length of the pin */
/* the pinned run opens and closes with the words at opacity 0; the negative
   margin slides those empty stretches under the sections on either side */
/* The section is pulled up over the one before it by most of a screen, and
   its pinned box is a full screen tall, so between them they lie on top of the
   Support card and swallow every pointer event aimed at it: the card's hover
   never fired on the part of it they covered. Nothing in here is interactive,
   so the whole run lets the pointer through. */
.s--triptych {
  height: calc(100lvh * var(--tript-len, 3.6));
  margin-top: -42vh;
  position: relative;
  pointer-events: none
}

/* The pinned box is a full screen tall and the section is pulled up over the
   one before it, so it lies on top of the Support card and swallowed every
   pointer event aimed at it: the card's hover simply never fired on the two
   thirds of it this covered. Nothing in here is interactive, so it lets the
   pointer through. */
.tript__sticky {
  position: sticky;
  top: 0;
  height: 100lvh;
  width: 100%;
  overflow: hidden;
  pointer-events: none;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  align-items: center;
  justify-content: center;
  justify-items: center
}

.tript__word {
  grid-row: 1;
  grid-column: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 920px;
  padding-top: var(--hdr-h);
  padding-inline: var(--page-pad);
}

/* both children start hidden and are driven individually by the scroll */
.tript__word>* {
  opacity: 0;
  will-change: opacity, translate, scale
}

.tript__word h2 {
  text-align: center;
  color: #fff
}

.tript__word p {
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 1.4;
  font-weight: 500;
  margin: 16px 0 0;
  max-width: 500px;
  text-align: center;
  color: #fff;
}

/* =====================================================================
   11 · contact
   ===================================================================== */
.s--contact {
  padding: 160px 0 120px
}

.s--contact h2 {
  margin-bottom: 18px
}

.s--contact .u-body {
  max-width: 520px;
  margin-inline: auto;
  color: rgba(255, 255, 255, .92)
}

.formcard {
  width: min(630px, calc(100% - 48px));
  margin: 44px auto 0;
  padding: 32px;
  border-radius: 18px;
  background: #fff;
  color: var(--black);
  box-shadow: 0 44px 90px -34px rgba(0, 26, 72, .5);
}

.formcard .f2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 14px
}

.formcard input[type=text],
.formcard input[type=email],
.formcard textarea {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  border-radius: 8px;
  border: 1px solid #e6e6e6;
  background: var(--haze);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--black);
}

.formcard textarea {
  height: 96px;
  padding: 12px 14px;
  resize: vertical
}

.formcard input::placeholder,
.formcard textarea::placeholder {
  color: #8b8b8b
}

.formcard input:focus,
.formcard textarea:focus {
  outline: none;
  border-color: #bcbcbc;
  background: #fff
}

.formcard fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 18px
}

.formcard legend {
  font-family: var(--font-head);
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 10px;
  padding: 0
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px
}

.chips label {
  cursor: pointer
}

.chips input {
  position: absolute;
  opacity: 0;
  pointer-events: none
}

.chips span {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid #e2e2e2;
  font-family: var(--font-body);
  font-size: 14px;
  transition: all .2s var(--ease-out);
}

.chips input:checked+span {
  background: var(--black);
  color: #fff;
  border-color: var(--black)
}

.fmsg {
  display: block;
  margin-bottom: 18px
}

.fsubmit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px
}

.fine {
  font-size: 12px;
  line-height: 18px;
  color: #7a7a7a;
  text-align: center;
  margin: 0;
  max-width: 340px
}

.fine a {
  text-decoration: underline
}

/* =====================================================================
   12 · outro + footer  (night scene renders on the canvas beneath)
   ===================================================================== */
/* the lockup reassembles over the last two screens of the document, so the
   outro has to be tall enough that the run starts once the deck has cleared —
   otherwise most of the animation plays hidden behind the cards */
.s--outro {
  height: 150vh
}

.ftr {
  position: relative;
  z-index: 2;
  max-width: 1440px;
  margin-inline: auto;
  padding: 0 var(--page-pad) 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ftr__email {
  color: rgba(255, 255, 255, .75);
  font: 500 12px/18px var(--font-body);
  text-decoration: none
}

.ftr__email:hover { color: #fff; text-decoration: underline }

.pricing__email {
  display: block;
  width: fit-content;
  margin: 18px auto 0;
  color: rgba(255, 255, 255, .68);
  font: 500 12px/18px var(--font-body);
  text-decoration: underline;
  text-underline-offset: 3px
}

.pricing__email:hover { color: #fff }

.ftr__copy {
  font-size: 12px;
  line-height: 18px;
  margin: 0;
  color: rgba(255, 255, 255, .75)
}

/* ---------- reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .8s var(--ease-out), transform .9s var(--ease-out)
}

.reveal.is-in {
  opacity: 1;
  transform: none
}

/* =====================================================================
   responsive
   ===================================================================== */
@media (max-width:1180px) {
  .nav-sub--wide {
    width: min(96vw, 900px);
    left: -24px
  }

  .fgrid {
    grid-template-columns: repeat(4, 1fr)
  }

  .fcard {
    grid-column: span 2
  }

  .fcard--sm {
    grid-column: span 2
  }
}

@media (max-width:1040px) {
  .pillars {
    flex-wrap: wrap
  }

  .pillar {
    flex: 1 1 320px;
    height: auto;
    min-height: 480px
  }

  /* auto height lets the art grow past its box and sit over the copy */
  .pillar__media {
    flex: 0 0 auto;
    height: 300px
  }

  .pillar .explode__img {
    width: 58%
  }

  .pillar .resize__bottle {
    width: auto;
    max-width: 42%;
    max-height: 88%
  }

  .pillar .resize__panel {
    width: 54%
  }

  .pillar .folders,
  .pillar .stack {
    max-height: 100%
  }
}

@media (max-width:860px) {
  :root {
    --page-pad: 16px
  }

  .hdr__nav,
  .hdr__ctas .btn--ghost,
  .hdr__ctas .btn--outline {
    display: none
  }

  .hdr__ctas .btn--icon {
    width: 34px;
    height: 34px
  }

  .hdr__ctas .btn--icon svg {
    width: 15px;
    height: 15px
  }

  /* The phone header carries no menu at all: the nav is already hidden here
     and the button that opened it goes with it, so only the logo and the
     direct actions remain. */
  .hdr__burger {
    display: none
  }

  /* with the nav gone, space-between would strand the CTA on the left where
     the logo lives — pin the logo left and push the rest to the right */
  .hdr__grid {
    justify-content: flex-end;
    gap: 8px
  }

  .hdr__ctas {
    margin-left: auto
  }

  .hdr__logo {
    left: var(--page-pad);
    transform: none
  }

  body.nav-open .hdr__nav {
    display: flex;
    position: fixed;
    inset: var(--hdr-h) 0 auto;
    flex-direction: column;
    height: auto;
    background: rgba(9, 44, 96, .92);
    backdrop-filter: blur(16px);
    padding: 12px var(--page-pad) 24px;
  }

  body.nav-open .nav-item {
    height: auto;
    display: block
  }

  body.nav-open .nav-item__btn {
    height: 48px;
    width: 100%;
    justify-content: space-between
  }

  body.nav-open .nav-sub {
    position: static;
    width: 100%;
    opacity: 1;
    visibility: visible;
    transform: none;
    display: none;
    background: rgba(255, 255, 255, .96);
    margin-bottom: 10px
  }

  body.nav-open .nav-item.is-open .nav-sub {
    display: block
  }

  body.nav-open .nav-sub__cols {
    flex-direction: column
  }

  body.nav-open .nav-sub__col--media {
    display: none
  }

  /* On a phone the rail down the side sits over the content and is awkward to
     reach; it becomes a horizontal bar floating at the foot of the screen
     instead, clear of the home indicator. */
  /* Laid on its side, the rail was sized for a 48px touch slot around a 26px
     disc, which left it nearly as wide as the sentence behind it. The slot is
     now the disc plus a couple of pixels of glass, and the disc travels along
     the row rather than down the column. */
  .tod {
    --tod-slot: 34px;
    --tod-knob: 30px;
    --tod-gap: 2px;
    --tod-pad: 4px;
    right: auto;
    left: 50%;
    top: auto;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    flex-direction: row;
    border-radius: 999px;
    /* the same glass as the desktop rail, just laid on its side */
    background: rgba(255, 255, 255, .12);
    box-shadow: 0 12px 28px -16px rgba(4, 26, 66, .45)
  }

  .tod::before {
    border-radius: 50%;
    translate: calc(var(--tod-i) * var(--tod-step)) 0
  }

  .tod button {
    color: rgba(255, 255, 255, .7);
    border-radius: 50%
  }

  /* ---- mobile vertical rhythm --------------------------------------
     Phone spacing is set here rather than inherited from the desktop scale:
     the desktop paddings are tuned for a 900px viewport and leave screens of
     empty sky on a 390px one. */
  .s--intro {
    padding-top: 24px;
    padding-bottom: 36px
  }

  .s--logos {
    padding: 36px 0 40px
  }

  .s--library {
    padding-top: 12px
  }

  .s--statement {
    padding: 18px 0 26px;
    min-height: 0
  }

  .s--demo {
    padding: 12px 0 16px
  }

  .s--features {
    padding: 44px 0 0
  }

  .fgrid {
    margin-top: 36px
  }

  .s--plan {
    padding: 24px 0 0
  }

  .s--integrations {
    padding: 57px 0 44px
  }

  .marquee {
    margin-top: 28px
  }

  .marquee--sm {
    margin-top: 24px
  }

  .pillars {
    flex-direction: column;
    align-items: stretch;
    margin-top: 28px;
    gap: 16px
  }

  .pillar {
    flex: 1 1 auto;
    min-height: 380px
  }

  .fgrid {
    grid-template-columns: 1fr;
    width: calc(100% - 32px)
  }

  /* the span rules above (and the --sm !important) all have to be beaten */
  .fgrid>.fcard,
  .fgrid>.fcard--sm {
    grid-column: 1/-1 !important;
    height: auto;
    min-height: 0;
    padding: 28px 20px 0
  }

  .s--features .fgrid > .fcard {
    padding-bottom: 28px
  }

  .fcard--sm {
    padding-bottom: 28px
  }

  /* the media stops floating over the copy and becomes the foot of the card */
  .fcard__media {
    position: relative;
    left: auto;
    right: auto;
    bottom: auto;
    height: auto;
    aspect-ratio: 16/10;
    margin: 22px 0 0;
    overflow: hidden;
    border-radius: 10px 10px 0 0
  }

  .fcard__media img {
    border-radius: inherit
  }

  .s--features .fgrid > .fcard > .fcard__media {
    border-radius: 10px
  }

  .s--features .fviz--integrations {
    touch-action: none
  }

  .plan {
    flex-direction: column;
    align-items: flex-start;
    --mag-r: 260px
  }

  .formcard {
    padding: 22px
  }

  .formcard .f2 {
    grid-template-columns: 1fr
  }

  /* The two hand-overs do not read the same at the same scroll distance. On the
     way in the logo row leaves at the top and STRUCTURE has to fade up on an
     empty screen, so an even gap there feels like waiting; on the way out the
     pricing block is already sliding in from below while CONVERSION fades, so
     the same gap feels full. STRUCTURE therefore arrives well before the even
     point and CONVERSION still leaves with air after it: measured from the
     centre of the screen, the logo row is 82px clear when STRUCTURE reaches
     half strength and the pricing heading 236px clear when CONVERSION falls
     back through it. The length sets the second and the margin sets the first. */
  .s--triptych {
    --tript-len: 3.2;
    margin-top: -31.5vh
  }

  /* the outro run is anchored to the bottom of the page, so its height is what
     sets how much sky there is between the last pricing card and the grass.
     A phone had a screen of it; this is the trim, and it stays on the phone */
  .s--outro {
    height: 130vh
  }

  .tript__word p {
    font-size: 16px;
    line-height: 25px
  }

  .ftr {
    flex-direction: column;
    align-items: flex-start
  }

  .marquee__row img {
    height: 56px;
    width: 56px
  }

  .marquee--sm .marquee__row img {
    height: 44px;
    width: auto;
    max-width: 124px
  }

  .marquee--sm .marquee__row {
    gap: 60px
  }

  /* the art inside a pillar is composed for a 351-wide card, so stacking them
     full-bleed on a tablet stretches it out of shape — cap the column instead */
  .pillar {
    min-height: 0;
    padding: 20px;
    width: 100%;
    max-width: 420px;
    margin-inline: auto
  }

  .pillar__media {
    flex: 0 0 auto;
    height: 250px;
    margin-bottom: 18px
  }

  .prompt-pill {
    font-size: 13px
  }

  .tod {
    --tod-slot: 34px;
    --tod-knob: 30px
  }
}

/* ---------- phones ---------- */
@media (max-width:560px) {
  .s--hero {
    height: calc(100svh + 80px)
  }

  .s--intro {
    padding-top: 20px;
    padding-bottom: 32px
  }

  .s--logos {
    padding: 32px 0 36px
  }

  .s--statement {
    padding: 14px 0 22px;
    min-height: auto
  }

  .s--features {
    padding: 40px 0 0
  }

  .s--integrations {
    padding: 53px 0 40px
  }

  .fgrid {
    margin-top: 32px;
    gap: 16px
  }

  .pillars {
    margin-top: 24px;
    gap: 16px
  }

  .pillar__media {
    height: 210px
  }

  .s h3 {
    font-size: 26px
  }

  .s h4,
  .s h3.section-heading--small {
    font-size: 18px;
    line-height: 26px
  }

  .u-h2-large {
    font-size: clamp(26px, 7.6vw, 34px)
  }

  .ftr {
    gap: 20px
  }
}

/* the original bumps every display size at the narrowest widths so the
   statement still fills the column instead of stranding it mid-screen */
@media (max-width:500px) {
  .u-h1 {
    font-size: 25vw
  }

  /* u-h1-small keeps its own 20vw — a single
                                    word at 25vw would run off the column */
  .tript__word p {
    max-width: 320px
  }
}

@media (prefers-reduced-motion:reduce) {

  /* The ambient colour meshes are excluded: they drift slowly in place and
     carry no motion-sickness risk, and without them the cards read as flat
     images. Everything else still stops. */
  *:not(.mesh-img):not(.plan__plate):not(.plan__mesh) {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important
  }

  .mesh-img,
  .plan__plate,
  .plan__mesh {
    animation-duration: 40s !important
  }
}

/* =====================================================================
   Pillar visualisations — Structure · Design · Convert
   Three motion studies built from the page's own primitives (the same
   squircles, pills, type scale and blues) rather than imagery. Each sits
   quietly at rest and plays when its pillar becomes active — the state the
   existing cycle and the hover handlers already set.
   ===================================================================== */
.viz {
  position: absolute;
  inset: 0
}

.viz__frame {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .04));
  border: 1px solid rgba(255, 255, 255, .16);
}

/* shared primitives */
.viz .vz-line {
  display: block;
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .5)
}

.viz .vz-line--xl {
  height: 13px;
  width: 76%;
  background: rgba(255, 255, 255, .82)
}

.viz .vz-line--lg {
  height: 10px;
  width: 58%;
  background: rgba(255, 255, 255, .72)
}

.viz .vz-line--md {
  height: 7px;
  width: 64%
}

.viz .vz-line--sm {
  height: 6px;
  width: 80%;
  background: rgba(255, 255, 255, .42)
}

.viz .vz-line--xs {
  height: 6px;
  width: 54%;
  background: rgba(255, 255, 255, .28)
}

.viz .vz-pill {
  display: block;
  height: 18px;
  width: 78px;
  border-radius: 9px;
  background: rgba(255, 255, 255, .9)
}

.viz .vz-pill--sm {
  height: 14px;
  width: 56px;
  background: rgba(255, 255, 255, .66)
}

.viz .vz-square {
  display: block;
  height: 32px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .22)
}

/* ---------- Structure: a page assembling itself ---------- */
.viz--structure .viz__frame {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 14px
}

.viz--structure .vz-nav {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: none;
  height: 18px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .14);
  padding: 0 8px;
}

.viz--structure .vz-dot {
  display: block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .45)
}

.viz--structure .vz-navbar {
  display: block;
  margin-left: auto;
  width: 44px;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .45)
}

.viz--structure .vz-block {
  display: flex;
  flex-direction: column;
  gap: 7px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .10);
  padding: 10px;
  /* at rest the page is already laid out, just quiet */
  opacity: .62;
  transform: translateY(7px);
  transform-origin: top;
  transition: opacity .55s var(--ease-out), transform .7s cubic-bezier(.16, 1, .3, 1);
}

.viz--structure .vz-hero {
  flex: none;
  align-items: flex-start
}

.viz--structure .vz-row {
  display: flex;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 0
}

.viz--structure .vz-col {
  flex: 1 1 0;
  min-width: 0
}

.viz--structure .vz-col .vz-square {
  flex: 1 1 auto;
  height: auto;
  min-height: 22px
}

.viz--structure .vz-band {
  flex: none;
  flex-direction: row;
  align-items: center;
  justify-content: space-between
}

/* active: the blocks settle into alignment one after another */
.pillar.is-active .viz--structure .vz-block {
  opacity: 1;
  transform: none
}

.pillar.is-active .viz--structure .vz-hero {
  transition-delay: .05s
}

.pillar.is-active .viz--structure .vz-row .vz-col:nth-child(1) {
  transition-delay: .20s
}

.pillar.is-active .viz--structure .vz-row .vz-col:nth-child(2) {
  transition-delay: .29s
}

.pillar.is-active .viz--structure .vz-row .vz-col:nth-child(3) {
  transition-delay: .38s
}

.pillar.is-active .viz--structure .vz-band {
  transition-delay: .52s
}

/* ---------- Design: loose parts resolving into a composition ---------- */
.viz--design .vd-swatches,
.viz--design .vd-type,
.viz--design .vd-shape,
.viz--design .vd-grid,
.viz--design .vd-card {
  position: absolute;
  transition: all .75s cubic-bezier(.16, 1, .3, 1)
}

.viz--design .vd-swatches {
  top: 14px;
  left: 14px;
  display: flex;
  gap: 5px
}

.viz--design .vd-swatches i {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 5px;
  background: var(--c);
  transition: transform .7s cubic-bezier(.16, 1, .3, 1)
}

.viz--design .vd-type {
  top: 12px;
  right: 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: flex-end;
  width: 80px
}

.viz--design .vd-type b {
  font-family: var(--font-head);
  font-size: 22px;
  line-height: 1;
  color: rgba(255, 255, 255, .9)
}

.viz--design .vd-shape {
  border-radius: 50%;
  background: rgba(255, 255, 255, .16)
}

.viz--design .vd-shape--circle {
  width: 46px;
  height: 46px;
  left: 16px;
  bottom: 18px
}

.viz--design .vd-shape--squircle {
  width: 40px;
  height: 40px;
  right: 20px;
  bottom: 22px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .12)
}

.viz--design .vd-grid {
  left: 50%;
  top: 52%;
  transform: translate(-50%, -50%);
  display: grid;
  grid-template-columns: repeat(3, 15px);
  gap: 6px;
  opacity: .45
}

.viz--design .vd-grid i {
  display: block;
  height: 15px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .2)
}

.viz--design .vd-card {
  left: 50%;
  top: 52%;
  width: 70%;
  transform: translate(-50%, -50%) scale(.84);
  border-radius: 10px;
  background: rgba(255, 255, 255, .15);
  border: 1px solid rgba(255, 255, 255, .24);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  opacity: 0;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.viz--design .vd-card__art {
  display: block;
  height: 56px;
  border-radius: 7px;
  background: linear-gradient(120deg, rgba(43, 132, 255, .8), rgba(152, 223, 54, .62) 55%, rgba(177, 138, 255, .75))
}

.pillar.is-active .viz--design .vd-swatches i:nth-child(2) {
  transform: translateY(4px)
}

.pillar.is-active .viz--design .vd-swatches i:nth-child(3) {
  transform: translateY(9px)
}

.pillar.is-active .viz--design .vd-swatches i:nth-child(4) {
  transform: translateY(14px)
}

.pillar.is-active .viz--design .vd-shape--circle {
  transform: translate(22px, -16px) scale(.7);
  opacity: .55
}

.pillar.is-active .viz--design .vd-shape--squircle {
  transform: translate(-18px, -12px) scale(.68);
  opacity: .55
}

.pillar.is-active .viz--design .vd-grid {
  opacity: 0;
  transform: translate(-50%, -50%) scale(1.35)
}

.pillar.is-active .viz--design .vd-card {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  transition-delay: .18s
}

/* ---------- Convert: a miniature page, and a click ---------- */
.viz--convert .vc-page {
  position: absolute;
  inset: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 8px;
  padding: 0 16px;
}

.viz--convert .vc-eyebrow {
  display: block;
  width: 46px;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .42)
}

.viz--convert .vc-head {
  display: block;
  width: 88%;
  height: 12px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .88)
}

.viz--convert .vc-head--2 {
  width: 60%
}

.viz--convert .vc-sub {
  display: block;
  width: 74%;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .4);
  margin-bottom: 6px
}

.viz--convert .vc-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  padding: 0 18px;
  border-radius: 9px;
  font-family: var(--font-head);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  background: #fff;
  color: #0b2d5c;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0, 20, 60, .28);
}

.viz--convert .vc-trust {
  display: block;
  width: 52%;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .26);
  margin-top: 8px
}

.viz--convert .vc-cursor {
  position: absolute;
  left: 78%;
  top: 86%;
  width: 17px;
  height: 17px;
  color: #fff;
  filter: drop-shadow(0 1px 2px rgba(0, 20, 60, .55));
  opacity: 0;
  transition: opacity .35s var(--ease-out);
}

.viz--convert .vc-cursor svg {
  width: 100%;
  height: 100%;
  display: block
}

.viz--convert .vc-ripple {
  position: absolute;
  left: 27%;
  top: 60%;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .8);
  opacity: 0;
  transform: translate(-50%, -50%) scale(.25);
  pointer-events: none;
}

.viz--convert .vc-toast {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translate(-50%, 14px);
  padding: 5px 12px;
  border-radius: 999px;
  font-family: var(--font-head);
  font-size: 11px;
  background: rgba(11, 45, 92, .92);
  color: #fff;
  opacity: 0;
  white-space: nowrap;
}

.pillar.is-active .viz--convert .vc-cursor {
  opacity: 1;
  animation: vcTravel 4.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.pillar.is-active .viz--convert .vc-cta {
  animation: vcPress 4.4s ease-in-out infinite
}

.pillar.is-active .viz--convert .vc-ripple {
  animation: vcRipple 4.4s ease-out infinite
}

.pillar.is-active .viz--convert .vc-toast {
  animation: vcToast 4.4s ease-out infinite
}

@keyframes vcTravel {
  0% { left: 80%; top: 88%; opacity: 0 }
  10% { opacity: 1 }
  32%, 75% { left: 24%; top: 57%; opacity: 1 }
  90%, 100% { left: 24%; top: 57%; opacity: 0 }
}

@keyframes vcPress {

  0%,
  34% {
    transform: translateY(0) scale(1);
    box-shadow: 0 2px 10px rgba(0, 20, 60, .28)
  }

  39% {
    transform: translateY(2px) scale(.96);
    box-shadow: 0 1px 4px rgba(0, 20, 60, .34)
  }

  46%,
  100% {
    transform: translateY(0) scale(1);
    box-shadow: 0 2px 10px rgba(0, 20, 60, .28)
  }
}

@keyframes vcRipple {

  0%,
  36% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(.25)
  }

  40% {
    opacity: .85;
    transform: translate(-50%, -50%) scale(.45)
  }

  60%,
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.6)
  }
}

@keyframes vcToast {

  0%,
  42% {
    opacity: 0;
    transform: translate(-50%, 14px)
  }

  52%,
  80% {
    opacity: 1;
    transform: translate(-50%, 0)
  }

  92%,
  100% {
    opacity: 0;
    transform: translate(-50%, 14px)
  }
}

@media (prefers-reduced-motion:reduce) {

  .pillar.is-active .viz--convert .vc-cursor,
  .pillar.is-active .viz--convert .vc-cta,
  .pillar.is-active .viz--convert .vc-ripple,
  .pillar.is-active .viz--convert .vc-toast {
    animation: none
  }

  .pillar.is-active .viz--convert .vc-cursor {
    opacity: 1
  }
}

/* =====================================================================
   Bento visualisations — Art direction · Analytics · Performance · Motion
   Same language as the three pillar cards: built from the page's own
   primitives, still at rest, and only playing while the card is hovered.
   ===================================================================== */
.fviz {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .04));
  border: 1px solid rgba(255, 255, 255, .14);
}

.fviz i,
.fviz b {
  display: block
}

/* The animation exists only while the pointer is on the card, or — where
   there is no pointer to hover with — while ui.js has the card marked as
   playing because it is in view. `animation:none` (rather than a pause) is
   deliberate: dropping out of either state drops the animation entirely, so
   the next time round the sequence starts from the beginning. Nothing adds
   .is-playing on a desktop, so the hover behaviour there is untouched. */
.fcard:not(:hover):not(.is-playing) .fviz * {
  animation: none !important
}

.fgrid[data-manual] .fcard.is-playing:not(:hover) .fviz *,
.fgrid[data-manual] .fcard.is-playing:not(:hover) .fviz *::before,
.fgrid[data-manual] .fcard.is-playing:not(:hover) .fviz *::after { animation-play-state: paused !important }

/* ---------- Lead generation: one SVG surface carries the funnel/button morph ---------- */
.fviz--lead { container-type: size }
.lg-defs { position: absolute; width: 0; height: 0; overflow: hidden }
.lg-canvas { display: block; width: 100%; height: 100%; overflow: hidden }
.lg-canvas text { font-family: var(--font-body); font-weight: 600; dominant-baseline: central }
.lg-cursor {
  position: absolute; z-index: 4; left: 0; top: 0;
  width: 18px; height: 21px; background: #000; opacity: 0;
  clip-path: polygon(0 0, 0 100%, 4px 12px, 7px 18px, 10px 16px, 7px 11px, 15px 10px);
  pointer-events: none;
}

/* ---------- Art direction: sample the spectrum, select three hues, blend ---------- */
.ad-stage {
  --ad-spectrum: linear-gradient(90deg, #4aabe5 0%, #60c8bd 16%, #79d77a 27%, #e0d361 43%, #f4ac52 57%, #e98591 74%, #a783d3 91%, #9576d9 100%);
  --ad-panel: 31.666667cqw;
  --ad-duration: 16s;
  --ad-blend: linear-gradient(90deg, #67ba6e 0%, #f4ac52 50%, #a783d3 100%);
  container-type: size;
  position: relative; display: block; width: 100%; height: 100%; overflow: hidden;
  border-radius: 8px; background: #f3f7fb
}
.ad-stage::before { content: ''; position: absolute; z-index: 4; inset: 0; background: var(--ad-spectrum); pointer-events: none }
.ad-grid { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); grid-template-rows: repeat(5, minmax(0, 1fr)); width: 100%; height: 100%; gap: 0 }
.ad-grid i { position: relative; min-width: 0; min-height: 0; border-radius: 0; background-color: var(--tone); overflow: hidden }
.ad-grid i:nth-child(9n+1) { --tone: #4aabe5 }
.ad-grid i:nth-child(9n+2) { --tone: #55bfd3 }
.ad-grid i:nth-child(9n+3) { --tone: #67ba6e }
.ad-grid i:nth-child(9n+4) { --tone: #b8d96b }
.ad-grid i:nth-child(9n+5) { --tone: #f4ac52 }
.ad-grid i:nth-child(9n+6) { --tone: #f49568 }
.ad-grid i:nth-child(9n+7) { --tone: #e98591 }
.ad-grid i:nth-child(9n+8) { --tone: #a783d3 }
.ad-grid i:nth-child(9n+9) { --tone: #9576d9 }
.ad-pick { z-index: 1 }
.ad-trio {
  position: absolute; z-index: 2; inset: 0; display: grid; align-items: center;
  grid-template-columns: 1fr 1fr 1fr; gap: 2.5cqw; opacity: 0; pointer-events: none
}
.ad-trio i { position: relative; overflow: hidden; height: 100cqh; border-radius: 8px; background: #67ba6e }
.ad-trio i:nth-child(2) { background: #f4ac52 }
.ad-trio i:nth-child(3) { background: #a783d3 }
.ad-trio i::after { content: ''; position: absolute; inset: 0; opacity: 0; background: var(--ad-blend) 0% 50% / 100cqw 100cqh }
.ad-trio i:nth-child(2)::after { background-position: 50% 50% }
.ad-trio i:nth-child(3)::after { background-position: 100% 50% }
.ad-final { position: absolute; z-index: 3; inset: 0; opacity: 0; background: var(--ad-blend) }
.hviz.is-play .ad-grid { animation: adGrid var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-grid i:not(.ad-pick) { animation: adTile var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-stage::before { animation: adCover var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-pick { animation: adChosen var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-pick--green { animation-name: adChosen, adGreen }
.hviz.is-play .ad-pick--orange { animation-name: adChosen, adOrange }
.hviz.is-play .ad-pick--purple { animation-name: adChosen, adPurple }
.hviz.is-play .ad-trio { animation: adTrio var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite, adWidths var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite, adJoin var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-trio i { animation: adCorners var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-final { animation: adBlend var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
.hviz.is-play .ad-trio i::after { animation: adSoften var(--ad-duration) cubic-bezier(.65, 0, .35, 1) infinite }
@keyframes adGrid { 0%, 7% { gap: 0 } 18%, 39% { gap: 5px } 50%, 100% { gap: 0 } }
@keyframes adCover { 0%, 7% { opacity: 1 } 18%, 96% { opacity: 0 } 100% { opacity: 1 } }
@keyframes adTile {
  0%, 7% { background-color: var(--tone); border-radius: 0; opacity: 1 }
  18%, 21% { background-color: var(--tone); border-radius: 5px; opacity: 1 }
  27%, 31% { background-color: #c9d4e0; border-radius: 5px; opacity: 1 }
  39%, 94% { background-color: #c9d4e0; border-radius: 5px; opacity: 0 }
  100% { background-color: var(--tone); border-radius: 0; opacity: 1 }
}
@keyframes adChosen {
  0%, 7% { width: 11.111111cqw; height: 20cqh; border-radius: 0; opacity: 1 }
  18%, 39% { width: calc(11.111111cqw - 4.444444px); height: calc(20cqh - 4px); border-radius: 5px; opacity: 1 }
  50% { width: var(--ad-panel); height: 100cqh; border-radius: 8px; opacity: 1 }
  52%, 94% { width: var(--ad-panel); height: 100cqh; border-radius: 8px; opacity: 0 }
  100% { width: 11.111111cqw; height: 20cqh; border-radius: 0; opacity: 1 }
}
@keyframes adGreen {
  0%, 39% { translate: 0 0 }
  50%, 94% { translate: -22.222222cqw 0 }
  100% { translate: 0 0 }
}
@keyframes adOrange {
  0%, 39% { translate: 0 0 }
  50%, 94% { translate: -10.277778cqw -40cqh }
  100% { translate: 0 0 }
}
@keyframes adPurple {
  0%, 39% { translate: 0 0 }
  50%, 94% { translate: -9.444444cqw -80cqh }
  100% { translate: 0 0 }
}
@keyframes adTrio { 0%, 49% { opacity: 0 } 52%, 90% { opacity: 1 } 91%, 100% { opacity: 0 } }
@keyframes adWidths {
  0%, 54% { grid-template-columns: 1fr 1fr 1fr }
  59% { grid-template-columns: 1.8fr .6fr .6fr }
  63% { grid-template-columns: 1fr 1fr 1fr }
  67% { grid-template-columns: .6fr 1.8fr .6fr }
  71% { grid-template-columns: 1fr 1fr 1fr }
  75% { grid-template-columns: .6fr .6fr 1.8fr }
  79%, 100% { grid-template-columns: 1fr 1fr 1fr }
}
@keyframes adJoin { 0%, 79% { gap: 2.5cqw } 90%, 100% { gap: 0 } }
@keyframes adCorners { 0%, 79% { border-radius: 8px } 90%, 100% { border-radius: 0 } }
@keyframes adBlend {
  0%, 90% { opacity: 0 }
  91%, 100% { opacity: 1 }
}
@keyframes adSoften { 0%, 79% { opacity: 0 } 90%, 100% { opacity: 1 } }

/* ---------- Analytics: a chart filling, events firing ---------- */
.fviz--ana {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px
}

.fviz--ana .fn-head {
  display: flex;
  align-items: center;
  justify-content: space-between
}

.fviz--ana .fn-kpi {
  width: 72px;
  height: 12px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .85)
}

.fviz--ana .fn-chip {
  width: 46px;
  height: 16px;
  border-radius: 8px;
  background: rgba(152, 223, 54, .55)
}

.fviz--ana .fn-bars {
  display: flex;
  align-items: flex-end;
  gap: 7px;
  flex: 1 1 auto;
  min-height: 0
}

.fviz--ana .fn-bars i {
  flex: 1 1 0;
  height: var(--h);
  border-radius: 5px 5px 3px 3px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .55), rgba(255, 255, 255, .18));
  transform-origin: bottom;
  transform: scaleY(.12);
  animation: fnGrow 6.5s cubic-bezier(.16, 1, .3, 1) infinite;
}

.fviz--ana .fn-bars i:nth-child(1) {
  animation-delay: 0s
}

.fviz--ana .fn-bars i:nth-child(2) {
  animation-delay: .09s
}

.fviz--ana .fn-bars i:nth-child(3) {
  animation-delay: .18s
}

.fviz--ana .fn-bars i:nth-child(4) {
  animation-delay: .27s
}

.fviz--ana .fn-bars i:nth-child(5) {
  animation-delay: .36s
}

.fviz--ana .fn-bars i:nth-child(6) {
  animation-delay: .45s
}

.fviz--ana .fn-bars i:nth-child(7) {
  animation-delay: .54s
}

.fviz--ana .fn-bars i:nth-child(8) {
  animation-delay: .63s
}

.fviz--ana .fn-events {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 14px;
  height: 0
}

.fviz--ana .fn-events i {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(152, 223, 54, .95);
  box-shadow: 0 0 0 3px rgba(152, 223, 54, .22);
  opacity: 0;
}

.fviz--ana .fn-events i:nth-child(1) {
  left: 18%;
  animation: fnPing 6.5s ease-out infinite .6s
}

.fviz--ana .fn-events i:nth-child(2) {
  left: 52%;
  animation: fnPing 6.5s ease-out infinite 1.5s
}

.fviz--ana .fn-events i:nth-child(3) {
  left: 82%;
  animation: fnPing 6.5s ease-out infinite 2.4s
}

@keyframes fnGrow {

  0%,
  6% {
    transform: scaleY(.12)
  }

  34%,
  74% {
    transform: scaleY(1)
  }

  96%,
  100% {
    transform: scaleY(.12)
  }
}

@keyframes fnPing {

  0%,
  8% {
    opacity: 0;
    transform: translateY(0) scale(.6)
  }

  16% {
    opacity: 1;
    transform: translateY(-10px) scale(1)
  }

  40%,
  100% {
    opacity: 0;
    transform: translateY(-34px) scale(.9)
  }
}

/* ---------- Performance: a score sweeping to 100 ---------- */
.fviz--perf {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 18px
}

.fviz--perf .fp-gauge {
  position: relative;
  display: block;
  width: 88px;
  height: 88px;
  flex: none
}

.fviz--perf .fp-arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 140deg, rgba(152, 223, 54, .85) 0turn, rgba(152, 223, 54, .85) var(--p, 0turn), rgba(255, 255, 255, .16) var(--p, 0turn), rgba(255, 255, 255, .16) .72turn, transparent .72turn);
  mask: radial-gradient(circle, transparent 58%, #000 60%);
  -webkit-mask: radial-gradient(circle, transparent 58%, #000 60%);
  animation: fpFill 7s cubic-bezier(.16, 1, .3, 1) infinite;
}

.fviz--perf .fp-needle {
  display: none
}

.fviz--perf .fp-score {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-size: 20px;
  color: rgba(255, 255, 255, .92);
  animation: fpScore 7s ease-out infinite;
}

.fviz--perf .fp-bars {
  display: flex;
  flex-direction: column;
  gap: 11px;
  flex: 1 1 auto;
  min-width: 0
}

.fviz--perf .fp-row {
  display: flex;
  align-items: center;
  gap: 9px
}

.fviz--perf .fp-lab {
  width: 34px;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .4);
  flex: none
}

.fviz--perf .fp-track {
  position: relative;
  flex: 1 1 auto;
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .14);
  overflow: hidden
}

.fviz--perf .fp-track b {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(43, 132, 255, .8), rgba(152, 223, 54, .9));
  animation: fpBar 7s cubic-bezier(.16, 1, .3, 1) infinite;
}

.fviz--perf .fp-row:nth-child(1) b {
  animation-delay: .1s
}

.fviz--perf .fp-row:nth-child(2) b {
  animation-delay: .3s
}

.fviz--perf .fp-row:nth-child(3) b {
  animation-delay: .5s
}

@property --p {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0turn
}

@keyframes fpFill {

  0%,
  4% {
    --p: 0turn
  }

  46%,
  82% {
    --p: .72turn
  }

  98%,
  100% {
    --p: 0turn
  }
}

@keyframes fpScore {

  0%,
  10% {
    opacity: 0;
    transform: scale(.86)
  }

  40%,
  82% {
    opacity: 1;
    transform: scale(1)
  }

  96%,
  100% {
    opacity: 0;
    transform: scale(.86)
  }
}

@keyframes fpBar {

  0%,
  6% {
    width: 0
  }

  44%,
  82% {
    width: 96%
  }

  98%,
  100% {
    width: 0
  }
}

/* ---------- Motion & interaction: a grabbed priority reorders with the pointer ---------- */
.fviz--mot { display: grid; place-items: center; padding: 16px; container-type: size }
.mi-stage {
  --mi-step: clamp(20px, 20cqh, 46px);
  --mi-half: clamp(9px, 9cqh, 15.5px);
  position: relative; display: block; width: 100%; height: 100%; overflow: hidden;
  border: 1px solid #d5e4f2; border-radius: 9px; background: #f5f9ff
}
.mi-row {
  position: absolute; left: 12%; width: 76%; height: clamp(18px, 18cqh, 31px);
  display: flex; align-items: center; gap: 10px; padding: 0 12px;
  border: 1px solid #d5e2f0; border-radius: 7px; background: #fff;
  color: #0b2d5c; box-shadow: 0 5px 12px -10px rgba(11, 45, 92, .4)
}
.mi-row b { color: #6c91b7; font: 700 9px/1 var(--font-head) }
.mi-row strong { flex: 1; font: 700 clamp(8px, 1.2vw, 11px)/1 var(--font-head); letter-spacing: .075em }
.mi-row i { width: 12px; height: 14px; opacity: .5; background: repeating-linear-gradient(0deg, currentColor 0 2px, transparent 2px 5px) }
.mi-row--one { top: calc(50% - var(--mi-step) - var(--mi-half)) }
.mi-row--two { top: calc(50% - var(--mi-half)) }
.mi-row--three {
  z-index: 2; top: calc(50% + var(--mi-step) - var(--mi-half));
  border-color: #2b84ff; background: linear-gradient(115deg, #2b84ff, #1763c0);
  color: #fff; box-shadow: 0 9px 18px -12px rgba(43, 132, 255, .75)
}
.mi-row--three b { color: rgba(255, 255, 255, .75) }
.mi-cursor {
  position: absolute; z-index: 3; left: 72%; top: calc(50% + var(--mi-step) - var(--mi-half) + 5px);
  width: 18px; height: 21px; background: #000; opacity: 0;
  clip-path: polygon(0 0, 0 100%, 4px 12px, 7px 18px, 10px 16px, 7px 11px, 15px 10px);
  filter: drop-shadow(0 1px 1px rgba(255, 255, 255, .8)); pointer-events: none
}
.fcard:is(:hover,.is-playing) .mi-row--one,
.fcard:is(:hover,.is-playing) .mi-row--two { animation: miMakeRoom 6.4s cubic-bezier(.65, 0, .35, 1) infinite }
.fcard:is(:hover,.is-playing) .mi-row--three { animation: miReorder 6.4s cubic-bezier(.65, 0, .35, 1) infinite }
.fcard:is(:hover,.is-playing) .mi-cursor { animation: miPointer 6.4s cubic-bezier(.65, 0, .35, 1) infinite }
@keyframes miMakeRoom {
  0%, 33% { transform: none }
  62%, 84% { transform: translateY(var(--mi-step)) }
  100% { transform: none }
}
@keyframes miReorder {
  0%, 27% { transform: none }
  32% { transform: scale(.97) translateY(2px) }
  62%, 84% { transform: translateY(calc(-2 * var(--mi-step))) scale(1.025); box-shadow: 0 17px 25px -14px rgba(43, 132, 255, .68) }
  100% { transform: none }
}
@keyframes miPointer {
  0%, 12% { opacity: 0; transform: translate(35px, 24px) }
  20% { opacity: 1; transform: none }
  30% { opacity: 1; transform: scale(.78) }
  34% { opacity: 1; transform: none }
  62% { opacity: 1; transform: translateY(calc(-2 * var(--mi-step))) }
  70% { opacity: 1; transform: translateY(calc(-2 * var(--mi-step))) scale(1.08) }
  82%, 100% { opacity: 0; transform: translate(-16px, calc(-2 * var(--mi-step))) }
}
@media (prefers-reduced-motion: reduce) {
  .fcard .fviz * { animation: none !important; transition: none !important }
  .ad-grid { display: none }
  .ad-stage::before, .ad-trio { display: none }
  .ad-final, .ad-final::after { opacity: 1 }
  .fviz--ana .fn-bars i { transform: scaleY(1) }
  .fviz--perf .fp-score { opacity: 1 }
  .fviz--perf .fp-arc { --p: .72turn }
  .fviz--perf .fp-track b { transform: scaleX(1) }
  .mi-cursor { display: none }
}
/* =====================================================================
   Navigation visualisations
   One rectangle per menu, one scene per category. The same language as
   the bento cards: built from the page's own primitives, still until the
   pointer picks a category, and reset the moment it leaves — so every
   scene starts from its first frame rather than mid-loop.
   ===================================================================== */
.nav-sub__preview {
  position: relative;
  width: 100%;
  min-height: 300px;
  border-radius: 12px;
  overflow: hidden;
  background: linear-gradient(168deg, #3f8bf2 0%, #2668d4 54%, #17469f 100%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16)
}

.nviz {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
  padding: 24px 20px;
  opacity: 0;
  transition: opacity .3s var(--ease-out)
}

.nviz.is-on {
  opacity: 1
}

/* animation only while this scene is the one on show, and only while the
   menu is actually open — `animation:none` rather than a pause, so the next
   hover replays from the top */
.nviz:not(.is-on) *,
.nav-item:not(.is-open) .nviz * {
  animation: none !important
}

.nviz i,
.nviz b,
.nviz u {
  display: block;
  font-style: normal;
  text-decoration: none
}

/* ---- shared primitives ---- */
.nviz .nv-pane {
  position: relative;
  border-radius: 10px;
  background: rgba(255, 255, 255, .09);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .24);
  overflow: hidden
}

.nviz .nv-click-cursor {
  position: absolute;
  z-index: 4;
  display: block;
  width: 18px;
  height: 21px;
  background: #fff;
  clip-path: polygon(0 0, 0 100%, 4px 12px, 7px 18px, 10px 16px, 7px 11px, 15px 10px);
  filter: drop-shadow(1px 1px 0 #174c98) drop-shadow(-1px -1px 0 #174c98);
  pointer-events: none
}

/* ---- shared motion ---- */
@keyframes nvRise {
  0% { opacity: 0; transform: translateY(14px) }
  22%, 86% { opacity: 1; transform: none }
  100% { opacity: 0; transform: translateY(-5px) }
}

@keyframes nvGrowW {
  0% { transform: scaleX(.06) }
  26%, 86% { transform: scaleX(1) }
  100% { transform: scaleX(.06) }
}

@keyframes nvGrowH {
  0% { transform: scaleY(.05) }
  30%, 86% { transform: scaleY(1) }
  100% { transform: scaleY(.05) }
}

@keyframes nvSweep {
  0% { transform: translateX(-30%); opacity: 0 }
  12% { opacity: .9 }
  88% { opacity: .9 }
  100% { transform: translateX(700%); opacity: 0 }
}

@keyframes nvPing {
  0% { transform: translate(-50%, -50%) scale(.35); opacity: .75 }
  75%, 100% { transform: translate(-50%, -50%) scale(2.4); opacity: 0 }
}

@keyframes nvPop {
  0% { transform: scale(.3); opacity: 0 }
  26% { transform: scale(1.12); opacity: 1 }
  38%, 86% { transform: scale(1); opacity: 1 }
  100% { transform: scale(.9); opacity: 0 }
}

@keyframes nvBeat {
  0%, 100% { transform: scale(1) }
  48% { transform: scale(1.055) }
}

/* ---------- Landing Page Design: a page laying itself out ---------- */
.nviz--design .nvd-page {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 34px 14px 14px
}

.nviz--design .nvd-page::before {
  content: '';
  position: absolute;
  top: 13px;
  left: 14px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #b9e9ff;
  box-shadow: 12px 0 rgba(255, 255, 255, .35), 24px 0 rgba(255, 255, 255, .2)
}

.nviz--design .nvd-hero {
  height: 24px;
  width: 72%;
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .9), rgba(196, 231, 255, .55));
  transform-origin: left;
  animation: nvGrowW 5.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--design .nvd-line {
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .3);
  transform-origin: left;
  animation: nvGrowW 5.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--design .nvd-line--a { width: 86%; animation-delay: .1s }
.nviz--design .nvd-line--b { width: 64%; animation-delay: .18s }
.nviz--design .nvd-line--c { width: 44%; animation-delay: .5s }

.nviz--design .nvd-cols {
  display: flex;
  gap: 8px;
  flex: 1 1 auto;
  align-items: flex-end;
  margin: 4px 0
}

.nviz--design .nvd-cols b {
  position: relative;
  flex: 1 1 0;
  border-radius: 7px;
  background: rgba(255, 255, 255, .13);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
  animation: nvRise 5.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--design .nvd-cols b::after {
  content: '';
  position: absolute;
  inset: 12px 9px auto;
  height: 8px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .47)
}

.nviz--design .nvd-cols b:first-child { height: 66% }
.nviz--design .nvd-cols b:last-child { height: 82% }

.nviz--design .nvd-cols b:nth-child(2) { animation-delay: .1s }
.nviz--design .nvd-cols b:nth-child(3) { animation-delay: .2s }

.nviz--design .nvd-guide {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 10%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .5), transparent);
  animation: nvSweep 5.4s ease-in-out infinite
}

/* ---------- Analytics & Tracking: events landing in the chart ---------- */
.nviz--analytics .nva-chart {
  flex: 1 1 auto;
  min-height: 0;
  padding: 14px;
  background-image: repeating-linear-gradient(0deg, rgba(255, 255, 255, .08) 0 1px, transparent 1px 41px)
}

.nviz--analytics .nva-cols {
  position: absolute;
  inset: 24px 14px 58px;
  display: flex;
  align-items: flex-end;
  gap: 7px
}

.nviz--analytics .nva-cols b {
  flex: 1 1 0;
  border-radius: 4px 4px 2px 2px;
  background: rgba(255, 255, 255, .13);
  transform-origin: bottom;
  animation: nvaBars 6.4s cubic-bezier(.45, 0, .2, 1) infinite
}

@keyframes nvaBars {
  0% { transform: scaleY(.02) }
  27%, 86% { transform: scaleY(1) }
  100% { transform: scaleY(.02) }
}

.nviz--analytics .nva-cols b:nth-child(1) { height: 32% }
.nviz--analytics .nva-cols b:nth-child(2) { height: 48%; animation-delay: .07s }
.nviz--analytics .nva-cols b:nth-child(3) { height: 40%; animation-delay: .14s }
.nviz--analytics .nva-cols b:nth-child(4) { height: 66%; animation-delay: .21s }
.nviz--analytics .nva-cols b:nth-child(5) { height: 58%; animation-delay: .28s }
.nviz--analytics .nva-cols b:nth-child(6) { height: 88%; background: rgba(255, 255, 255, .22); animation-delay: .35s }

.nviz--analytics .nva-line {
  position: absolute;
  z-index: 1;
  inset: 28px 18px 74px;
  width: calc(100% - 36px);
  height: calc(100% - 102px);
  overflow: visible;
  fill: none;
  stroke: #b9f0db;
  stroke-width: 3;
  stroke-linecap: round;
  clip-path: inset(0 100% 0 0);
  animation: nvaDraw 6.4s cubic-bezier(.55, 0, .2, 1) infinite
}

@keyframes nvaDraw {
  0%, 35% { clip-path: inset(0 100% 0 0); opacity: 0 }
  38% { opacity: 1 }
  69%, 86% { clip-path: inset(0 0 0 0); opacity: 1 }
  100% { clip-path: inset(0 0 0 0); opacity: 0 }
}

.nviz--analytics .nva-ping {
  position: absolute;
  right: 12px;
  top: 13%;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .7);
  animation: nvaPing 6.4s ease-out infinite
}

.nviz--analytics .nva-cursor {
  right: 11px;
  top: calc(13% + 17px);
  animation: nvaCursor 6.4s cubic-bezier(.35, 0, .2, 1) infinite
}

@keyframes nvaCursor {
  0%, 57% { transform: translate(38px, 70px); opacity: 0 }
  61% { opacity: 1 }
  70% { transform: translate(0, 0); opacity: 1 }
  73% { transform: scale(.76); opacity: 1 }
  78% { transform: scale(1); opacity: 1 }
  86%, 100% { transform: scale(1); opacity: 0 }
}

@keyframes nvaPing {
  0%, 71% { transform: translate(-50%, -50%) scale(.3); opacity: 0 }
  75% { opacity: .8 }
  84%, 100% { transform: translate(-50%, -50%) scale(2.4); opacity: 0 }
}

.nviz--analytics .nva-event {
  position: absolute;
  z-index: 2;
  left: 14px;
  right: 14px;
  bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 12px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .2);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .26);
  animation: nvaEvent 6.4s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvaEvent {
  0%, 67% { transform: translateY(10px) scale(.94); opacity: 0 }
  76%, 87% { transform: none; opacity: 1 }
  100% { transform: translateY(6px) scale(.98); opacity: 0 }
}

.nviz--analytics .nva-event b {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #b7f0d4;
  flex: none
}

.nviz--analytics .nva-event u {
  height: 6px;
  width: 74px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .55)
}

/* ---------- Performance & SEO: the dial and the three vitals ---------- */
@property --nvp {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

.nviz--perf .nvp-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 18px
}

.nviz--perf .nvp-dial {
  position: relative;
  width: 124px;
  height: 124px;
  border-radius: 50%;
  background: conic-gradient(from -90deg, #8fe3c8 0deg, #d9f3a8 var(--nvp), rgba(255, 255, 255, .16) var(--nvp));
  animation: nvDial 4.2s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvDial {
  0% { --nvp: 0deg; opacity: 0 }
  8% { opacity: 1 }
  45%, 86% { --nvp: 360deg; opacity: 1 }
  100% { --nvp: 360deg; opacity: 0 }
}

.nviz--perf .nvp-core {
  position: absolute;
  inset: 12px;
  border-radius: 50%;
  background: linear-gradient(168deg, #3f8bf2, #1f5cc4);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2)
}

.nviz--perf .nvp-core::before,
.nviz--perf .nvp-core::after {
  position: absolute;
  left: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: var(--font-head)
}

.nviz--perf .nvp-core::before { content: '100'; top: 23px; font-size: 38px; line-height: 1; font-weight: 600 }
.nviz--perf .nvp-core::after { content: 'PERFORMANCE'; top: 66px; font-size: 7px; letter-spacing: .13em }

.nviz--perf .nvp-vitals {
  display: flex;
  gap: 8px
}

.nviz--perf .nvp-vitals b {
  width: 44px;
  height: 23px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .13);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
  color: #b9f0db;
  display: grid;
  place-items: center;
  font-size: 8px;
  font-weight: 700;
  animation: nvVital 4.2s ease-in-out infinite
}

.nviz--perf .nvp-vitals b:nth-child(1)::after { content: 'LCP' }
.nviz--perf .nvp-vitals b:nth-child(2)::after { content: 'INP' }
.nviz--perf .nvp-vitals b:nth-child(3)::after { content: 'CLS' }

@keyframes nvVital {
  0%, 20% { background: rgba(255, 255, 255, .13) }
  36%, 86% { background: rgba(143, 227, 200, .25) }
  100% { background: rgba(255, 255, 255, .13) }
}

.nviz--perf .nvp-vitals b:nth-child(2) { animation-delay: .12s }
.nviz--perf .nvp-vitals b:nth-child(3) { animation-delay: .24s }

/* ---------- Product launch: click, ignition, full-frame ascent ---------- */
.nviz--launch .nvl-page { flex: 1 1 auto }

.nviz--launch .nvl-page::before {
  content: 'PRODUCT READY';
  position: absolute;
  top: 27px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  color: rgba(255, 255, 255, .83);
  font: 700 9px/1 var(--font-head);
  letter-spacing: .13em;
  animation: nvlIntro 6.6s ease-in-out infinite
}

.nviz--launch .nvl-line {
  position: absolute;
  left: 50%;
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .33);
  transform: translateX(-50%);
  animation: nvlIntro 6.6s ease-in-out infinite
}

.nviz--launch .nvl-line--a { top: 61px; width: 68% }
.nviz--launch .nvl-line--b { top: 76px; width: 46% }

@keyframes nvlIntro {
  0%, 25% { opacity: 1 }
  35%, 66% { opacity: 0 }
  84%, 100% { opacity: 1 }
}

.nviz--launch .nvl-cta {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 55%;
  width: 132px;
  height: 42px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .9);
  box-shadow: 0 12px 24px -12px rgba(4, 26, 66, .8);
  display: grid;
  place-items: center;
  animation: nvlButton 6.6s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--launch .nvl-cta::after { content: 'LAUNCH  ↗'; color: #1757ac; font: 700 11px/1 var(--font-head); letter-spacing: .06em }

@keyframes nvlButton {
  0%, 25% { transform: translate(-50%, -50%) scale(1); opacity: 1 }
  29% { transform: translate(-50%, -50%) scale(.91); opacity: 1 }
  35%, 66% { transform: translate(-50%, -50%) scale(.72); opacity: 0 }
  84%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 1 }
}

.nviz--launch .nvl-ping {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 55%;
  width: 54px;
  height: 54px;
  border: 2px solid rgba(185, 240, 219, .85);
  border-radius: 50%;
  animation: nvlClick 6.6s ease-out infinite
}

@keyframes nvlClick {
  0%, 27% { transform: translate(-50%, -50%) scale(.3); opacity: 0 }
  31% { opacity: .8 }
  42%, 100% { transform: translate(-50%, -50%) scale(2.6); opacity: 0 }
}

.nviz--launch .nvl-cursor {
  left: 50%;
  top: 55%;
  animation: nvlCursor 6.6s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvlCursor {
  0% { transform: translate(65px, 76px); opacity: 0 }
  9% { opacity: 1 }
  25% { transform: translate(9px, 5px); opacity: 1 }
  29% { transform: translate(9px, 5px) scale(.78); opacity: 1 }
  34% { transform: translate(9px, 5px); opacity: 1 }
  39%, 100% { transform: translate(9px, 5px); opacity: 0 }
}

.nviz--launch .nvl-rocket {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(100% + 18px);
  width: 72px;
  height: 128px;
  overflow: visible;
  filter: drop-shadow(8px 10px 6px rgba(8, 42, 101, .38));
  animation: nvlFly 6.6s cubic-bezier(.42, 0, .65, 1) infinite
}

.nviz--launch .nvl-body { fill: url(#nvl-hull); stroke: #fff; stroke-width: 1.5 }
.nviz--launch .nvl-fin { fill: url(#nvl-fin); stroke: #d8fff0; stroke-width: 2; stroke-linejoin: round }
.nviz--launch .nvl-window { fill: url(#nvl-glass); stroke: #fff; stroke-width: 3 }
.nviz--launch .nvl-highlight { fill: rgba(255, 255, 255, .38) }
.nviz--launch .nvl-window-glint { fill: rgba(255, 255, 255, .85) }
.nviz--launch .nvl-nozzle { fill: #6596b9; stroke: #e4f4ff; stroke-width: 1.5 }
.nviz--launch .nvl-seam { fill: none; stroke: #90c5f5; stroke-width: 2; stroke-linecap: round }
.nviz--launch .nvl-flame { fill: url(#nvl-fire); transform-origin: 50% 75%; animation: nvlFlame .24s ease-in-out infinite alternate }

@keyframes nvlFlame { from { transform: scaleY(.76) } to { transform: scaleY(1.08) } }

@keyframes nvlFly {
  0%, 35% { top: calc(100% + 18px); transform: translateX(-50%) rotate(-2deg); opacity: 1 }
  60% { top: -150px; transform: translateX(-50%) rotate(2deg); opacity: 1 }
  64%, 100% { top: -150px; transform: translateX(-50%) rotate(2deg); opacity: 0 }
}

/* ---------- Lead generation: the form filling and clearing ---------- */
.nviz--leads .nvf-form {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 11px;
  padding: 22px 18px
}

.nviz--leads .nvf-form::before {
  content: 'NEW LEAD';
  color: rgba(255, 255, 255, .82);
  font: 700 10px/1 var(--font-head);
  letter-spacing: .11em;
  margin-bottom: 4px
}

.nviz--leads .nvf-field {
  position: relative;
  height: 40px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .24);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  padding: 0 10px
}

.nviz--leads .nvf-field::before {
  position: absolute;
  top: 7px;
  left: 10px;
  color: rgba(255, 255, 255, .48);
  font: 700 7px/1 var(--font-head);
  letter-spacing: .1em
}

.nviz--leads .nvf-field--1::before { content: 'NAME' }
.nviz--leads .nvf-field--2::before { content: 'EMAIL' }

.nviz--leads .nvf-field b {
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .7);
  width: 100%;
  margin-bottom: 9px;
  transform-origin: left;
  animation: nvType 5s steps(14, end) infinite
}

@keyframes nvType {
  0% { transform: scaleX(0) }
  22%, 100% { transform: scaleX(1) }
}

.nviz--leads .nvf-field--2 b { animation-delay: .5s; width: 70% }

.nviz--leads .nvf-submit {
  position: relative;
  height: 34px;
  width: 58%;
  border-radius: 999px;
  background: rgba(255, 255, 255, .88);
  margin-top: 4px;
  display: grid;
  place-items: center;
  animation: nvfSend 5s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--leads .nvf-submit::after { content: 'SEND →'; color: #1955a8; font: 700 9px/1 var(--font-head); letter-spacing: .05em }

.nviz--leads .nvf-cursor {
  left: 50%;
  top: 45%;
  animation: nvfCursor 5s cubic-bezier(.35, 0, .2, 1) infinite
}

@keyframes nvfCursor {
  0%, 19% { transform: translate(42px, 48px); opacity: 0 }
  23% { opacity: 1 }
  33% { transform: translate(0, 0); opacity: 1 }
  36% { transform: scale(.76); opacity: 1 }
  42% { transform: scale(1); opacity: 1 }
  51%, 100% { transform: scale(1); opacity: 0 }
}

@keyframes nvfSend {
  0%, 32% { transform: scale(1) }
  36% { transform: scale(.94) }
  45%, 100% { transform: scale(1) }
}

.nviz--leads .nvf-check {
  position: absolute;
  right: 18px;
  bottom: 61px;
  width: 52px;
  height: 34px;
  border-radius: 8px;
  background: rgba(185, 240, 219, .2);
  box-shadow: inset 0 0 0 1px rgba(185, 240, 219, .65);
  display: grid;
  place-items: center;
  color: #b9f0db;
  font: 700 10px/1 var(--font-head);
  animation: nvfSuccess 5s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--leads .nvf-check::after { content: 'CRM ✓' }

@keyframes nvfSuccess {
  0%, 41% { transform: scale(.7); opacity: 0 }
  51%, 84% { transform: scale(1); opacity: 1 }
  100% { transform: scale(.9); opacity: 0 }
}

/* ---------- Waitlist: the queue filling up ---------- */
.nviz--waitlist .nvw-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 13px;
  padding: 16px
}

.nviz--waitlist .nvw-stage::before {
  content: 'EARLY ACCESS';
  color: rgba(255, 255, 255, .82);
  font: 700 10px/1 var(--font-head);
  letter-spacing: .1em
}

.nviz--waitlist .nvw-count {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .2);
  overflow: hidden;
  flex: none
}

.nviz--waitlist .nvw-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(255, 255, 255, .95), rgba(207, 230, 255, .8));
  transform-origin: left;
  animation: nvGrowW 5s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--waitlist .nvw-queue {
  display: flex;
  flex-direction: column;
  gap: 9px
}

.nviz--waitlist .nvw-queue b {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 10px;
  height: 32px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .11);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
  animation: nvSlideIn 5s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--waitlist .nvw-queue b::before {
  content: '';
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, .42)
}

.nviz--waitlist .nvw-queue b::after {
  content: '';
  width: 52%;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .43)
}

.nviz--waitlist .nvw-queue b:nth-child(2)::after { width: 43% }
.nviz--waitlist .nvw-queue b:nth-child(3)::after { width: 61% }
.nviz--waitlist .nvw-queue b:nth-child(4)::after { width: 34% }

@keyframes nvSlideIn {
  0% { opacity: 0; transform: translateX(34px) }
  20%, 86% { opacity: 1; transform: none }
  100% { opacity: 0; transform: translateX(12px) }
}

.nviz--waitlist .nvw-queue b:nth-child(2) { animation-delay: .16s }
.nviz--waitlist .nvw-queue b:nth-child(3) { animation-delay: .32s }
.nviz--waitlist .nvw-queue b:nth-child(4) { animation-delay: .48s }

/* ---------- Site refresh: the new page wiping over the old ---------- */
.nviz--refresh .nvr-stage {
  flex: 1 1 auto
}

.nviz--refresh .nvr-old,
.nviz--refresh .nvr-new {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
  padding: 39px 20px 20px
}

.nviz--refresh .nvr-old::before,
.nviz--refresh .nvr-new::before {
  position: absolute;
  top: 15px;
  left: 20px;
  color: rgba(255, 255, 255, .76);
  font: 700 9px/1 var(--font-head);
  letter-spacing: .12em
}

.nviz--refresh .nvr-old::before { content: 'BEFORE' }
.nviz--refresh .nvr-new::before { content: 'AFTER' }

.nviz--refresh .nvr-old b {
  height: 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .24)
}

.nviz--refresh .nvr-old b:nth-child(1) { width: 84% }
.nviz--refresh .nvr-old b:nth-child(2) { width: 62% }
.nviz--refresh .nvr-old b:nth-child(3) { width: 72% }

.nviz--refresh .nvr-old::after {
  content: '';
  height: 62px;
  border-radius: 6px;
  border: 1px dashed rgba(255, 255, 255, .25);
  background: rgba(255, 255, 255, .07)
}

.nviz--refresh .nvr-old { animation: nvrOld 4.6s cubic-bezier(.16, 1, .3, 1) infinite }

@keyframes nvrOld {
  0%, 8% { opacity: 1 }
  52%, 84% { opacity: 0 }
  100% { opacity: 1 }
}

.nviz--refresh .nvr-new {
  background: linear-gradient(150deg, rgba(185, 240, 219, .15), rgba(255, 255, 255, .04));
  clip-path: inset(0 100% 0 0);
  animation: nvWipe 4.6s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvWipe {
  0%, 8% { clip-path: inset(0 100% 0 0); opacity: 1 }
  52%, 84% { clip-path: inset(0 0 0 0); opacity: 1 }
  100% { clip-path: inset(0 0 0 0); opacity: 0 }
}

.nviz--refresh .nvr-new b {
  border-radius: 6px;
  background: rgba(255, 255, 255, .8)
}

.nviz--refresh .nvr-new b:nth-child(1) { height: 16px; width: 66% }
.nviz--refresh .nvr-new b:nth-child(2) { height: 42px; background: rgba(255, 255, 255, .3) }
.nviz--refresh .nvr-new b:nth-child(3) { height: 26px; width: 52%; border-radius: 999px }

.nviz--refresh .nvr-new::after {
  content: '';
  height: 40px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, .35);
  background: linear-gradient(110deg, rgba(185, 240, 219, .24), rgba(255, 255, 255, .07))
}

.nviz--refresh .nvr-wipe {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: rgba(185, 240, 219, .92);
  box-shadow: 0 0 14px rgba(185, 240, 219, .65);
  animation: nvWipeLine 4.6s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--refresh .nvr-wipe::after {
  content: '‹ ›';
  position: absolute;
  left: -13px;
  top: 50%;
  width: 29px;
  height: 29px;
  border-radius: 50%;
  background: #fff;
  display: grid;
  place-items: center;
  color: #1955a8;
  font: 700 11px/1 var(--font-head)
}

@keyframes nvWipeLine {
  0%, 8% { left: 0; opacity: 0 }
  12% { opacity: 1 }
  52% { left: 100%; opacity: 1 }
  60%, 100% { left: 100%; opacity: 0 }
}

/* ---------- SaaS & software: code resolves into a live product ---------- */
.nviz--saas .nxs-stage {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 6px; padding: 12px
}
.nviz--saas .nxs-code {
  position: relative; display: flex; flex-direction: column; gap: 6px; height: 82px; flex: none;
  padding: 9px 11px; border: 1px solid rgba(255, 255, 255, .22); border-radius: 7px;
  background: rgba(7, 39, 101, .24)
}
.nviz--saas .nxs-codebar { display: flex; align-items: center; gap: 4px; height: 10px; margin-bottom: 2px }
.nviz--saas .nxs-codebar b { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .45) }
.nviz--saas .nxs-codebar::after {
  content: 'app / workspace'; margin-left: auto; color: rgba(255, 255, 255, .67);
  font: 600 7px/1 var(--font-head); letter-spacing: .04em
}
.nviz--saas .nxs-line {
  display: block; height: 6px; width: 68%; border-radius: 3px;
  background: linear-gradient(90deg, #b9f0db 0 28%, rgba(255, 255, 255, .76) 28% 72%, rgba(255, 255, 255, .35) 72%);
  transform-origin: left
}
.nviz--saas .nxs-line--b { width: 82%; background: linear-gradient(90deg, #ffd166 0 18%, rgba(255, 255, 255, .72) 18% 64%, rgba(255, 255, 255, .36) 64%) }
.nviz--saas .nxs-line--c { width: 54% }
.nviz--saas .nxs-line--a { animation: nxsLineA 6.2s cubic-bezier(.16, 1, .3, 1) infinite }
.nviz--saas .nxs-line--b { animation: nxsLineB 6.2s cubic-bezier(.16, 1, .3, 1) infinite }
.nviz--saas .nxs-line--c { animation: nxsLineC 6.2s cubic-bezier(.16, 1, .3, 1) infinite }
.nviz--saas .nxs-transfer { position: relative; display: block; height: 16px; flex: none; align-self: center; width: 2px; background: rgba(255, 255, 255, .3) }
.nviz--saas .nxs-transfer b {
  position: absolute; top: -3px; left: -3px; width: 8px; height: 8px;
  border-radius: 50%; background: #b9f0db; box-shadow: 0 0 0 4px rgba(185, 240, 219, .15);
  animation: nxsPacket 6.2s cubic-bezier(.65, 0, .35, 1) infinite
}
.nviz--saas .nxs-app {
  position: relative; display: flex; flex-direction: column; gap: 7px; flex: 1 1 auto; min-height: 0;
  padding: 0 9px 9px; border: 1px solid rgba(255, 255, 255, .3); border-radius: 7px;
  background: rgba(255, 255, 255, .13); box-shadow: 0 10px 20px -15px rgba(3, 32, 90, .55);
  animation: nxsApp 6.2s cubic-bezier(.16, 1, .3, 1) infinite
}
.nviz--saas .nxs-appbar { display: flex; gap: 4px; align-items: center; height: 21px; border-bottom: 1px solid rgba(255, 255, 255, .2); flex: none }
.nviz--saas .nxs-appbar b { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .55) }
.nviz--saas .nxs-appbar::after {
  content: 'LIVE APP'; margin-left: auto; color: #b9f0db;
  font: 700 7px/1 var(--font-head); letter-spacing: .1em
}
.nviz--saas .nxs-apphero {
  display: block; height: 34%; min-height: 20px; border-radius: 5px;
  background: linear-gradient(125deg, rgba(185, 240, 219, .48), rgba(255, 255, 255, .26));
  transform-origin: left; animation: nxsSurface 6.2s cubic-bezier(.16, 1, .3, 1) infinite
}
.nviz--saas .nxs-widgets { display: flex; gap: 7px; flex: 1 1 auto; min-height: 0 }
.nviz--saas .nxs-widgets b {
  flex: 1; border-radius: 5px; background: rgba(255, 255, 255, .3);
  animation: nxsWidget 6.2s cubic-bezier(.16, 1, .3, 1) infinite
}
.nviz--saas .nxs-widgets b:last-child { background: rgba(185, 240, 219, .35); animation-name: nxsWidgetB }
@keyframes nxsLineA { 0%, 7% { opacity: 0; transform: scaleX(.03) } 19%, 87% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.03) } }
@keyframes nxsLineB { 0%, 17% { opacity: 0; transform: scaleX(.03) } 29%, 87% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.03) } }
@keyframes nxsLineC { 0%, 27% { opacity: 0; transform: scaleX(.03) } 39%, 87% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.03) } }
@keyframes nxsPacket { 0%, 38% { opacity: 0; transform: translateY(-3px) scale(.7) } 43% { opacity: 1 } 57% { opacity: 1; transform: translateY(16px) scale(1) } 65%, 100% { opacity: 0; transform: translateY(16px) scale(.7) } }
@keyframes nxsApp { 0%, 49% { opacity: .2; transform: translateY(10px) scale(.96) } 65%, 88% { opacity: 1; transform: none } 100% { opacity: .2; transform: translateY(10px) scale(.96) } }
@keyframes nxsSurface { 0%, 57% { opacity: 0; transform: scaleX(.04) } 74%, 88% { opacity: 1; transform: scaleX(1) } 100% { opacity: 0; transform: scaleX(.6) } }
@keyframes nxsWidget { 0%, 65% { opacity: 0; transform: translateY(8px) } 78%, 88% { opacity: 1; transform: none } 100% { opacity: 0; transform: translateY(6px) } }
@keyframes nxsWidgetB { 0%, 69% { opacity: 0; transform: translateY(8px) } 82%, 88% { opacity: 1; transform: none } 100% { opacity: 0; transform: translateY(6px) } }

/* ---------- Coaching & services: calendar builds, then a call is booked ---------- */
.nviz--coaching .nvk-cal {
  flex: 1 1 auto;
  padding: 45px 14px 56px;
  min-height: 0
}

.nviz--coaching .nvk-cal::before {
  content: 'SEPTEMBER 2026';
  position: absolute;
  top: 17px;
  left: 14px;
  color: rgba(255, 255, 255, .82);
  font: 700 9px/1 var(--font-head);
  letter-spacing: .1em
}

.nviz--coaching .nvk-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 5px;
  height: 100%;
  counter-reset: day
}

.nviz--coaching .nvk-grid b {
  display: grid;
  place-items: center;
  border-radius: 5px;
  background: rgba(255, 255, 255, .12);
  color: rgba(255, 255, 255, .7);
  font: 500 9px/1 var(--font-head);
  counter-increment: day;
  opacity: 0;
  animation: nvkDay 7.2s cubic-bezier(.16, 1, .3, 1) calc(var(--i) * .065s) infinite backwards
}

.nviz--coaching .nvk-grid b::after { content: counter(day) }

@keyframes nvkDay {
  0%, 2% { opacity: 0; transform: scale(.45) }
  7%, 72% { opacity: 1; transform: scale(1) }
  78%, 100% { opacity: 0; transform: scale(.78) }
}

.nviz--coaching .nvk-grid b:nth-child(13) {
  animation: nvkDay 7.2s cubic-bezier(.16, 1, .3, 1) calc(var(--i) * .065s) infinite backwards,
    nvkPick 7.2s ease-in-out infinite
}

@keyframes nvkPick {
  0%, 49% { background: rgba(255, 255, 255, .12); color: rgba(255, 255, 255, .7); box-shadow: none }
  53%, 75% { background: #fff; color: #1955a8; box-shadow: 0 0 0 3px rgba(185, 240, 219, .45) }
  85%, 100% { background: rgba(255, 255, 255, .12); color: rgba(255, 255, 255, .7); box-shadow: none }
}

.nviz--coaching .nvk-confirm {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  height: 30px;
  border-radius: 8px;
  background: rgba(185, 240, 219, .2);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28);
  display: grid;
  place-items: center;
  color: #b9f0db;
  font: 700 9px/1 var(--font-head);
  letter-spacing: .06em;
  animation: nvkReserve 7.2s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--coaching .nvk-confirm::after { content: 'RESERVE CALL'; animation: nvkLabel 7.2s linear infinite }

@keyframes nvkLabel {
  0%, 72.9% { opacity: 1 }
  73%, 100% { opacity: 0 }
}

.nviz--coaching .nvk-confirm::before {
  content: '✓  CALL BOOKED';
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  background: transparent;
  color: #fff;
  opacity: 0;
  animation: nvkBooked 7.2s linear infinite
}

@keyframes nvkReserve {
  0%, 27% { transform: translateY(8px); opacity: 0; background: rgba(185, 240, 219, .2) }
  34%, 67% { transform: none; opacity: 1; background: rgba(185, 240, 219, .2) }
  71%, 72.9% { transform: scale(.96); opacity: 1; background: rgba(185, 240, 219, .2) }
  73%, 88% { transform: none; opacity: 1; background: #218a50 }
  100% { transform: translateY(7px); opacity: 0; background: #218a50 }
}

@keyframes nvkBooked {
  0%, 72.9% { opacity: 0 }
  73%, 100% { opacity: 1 }
}

.nviz--coaching .nvk-cursor {
  left: 50%;
  top: 55%;
  animation: nvkCursor 7.2s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvkCursor {
  0%, 34% { top: 55%; transform: translate(75px, 90px); opacity: 0 }
  38% { opacity: 1 }
  49% { top: 55%; transform: translate(4px, 4px); opacity: 1 }
  53% { top: 55%; transform: translate(4px, 4px) scale(.75); opacity: 1 }
  57% { top: 55%; transform: translate(4px, 4px); opacity: 1 }
  67% { top: calc(100% - 39px); transform: translate(4px, 0); opacity: 1 }
  71% { top: calc(100% - 39px); transform: translate(4px, 0) scale(.75); opacity: 1 }
  75% { top: calc(100% - 39px); transform: translate(4px, 0); opacity: 1 }
  82%, 100% { top: calc(100% - 39px); transform: translate(4px, 0); opacity: 0 }
}

/* ---------- Conversion Strategy: two versions, one of them wins -------
   Structure, offer and copy are not a matter of taste here — the page is run
   against a second version and the numbers underneath settle it. */
.nviz--strategy .nvs-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  min-height: 0
}

.nviz--strategy .nvs-pair {
  display: flex;
  gap: 12px;
  flex: 1 1 auto;
  min-height: 0
}

.nviz--strategy .nvs-var {
  position: relative;
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 24px 10px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .13);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2)
}

.nviz--strategy .nvs-var::before {
  position: absolute;
  top: 9px;
  left: 10px;
  font: 700 9px/1 var(--font-head);
  letter-spacing: .1em;
  color: rgba(255, 255, 255, .72)
}

.nviz--strategy .nvs-var--a::before { content: 'A / NOW' }
.nviz--strategy .nvs-var--b::before { content: 'B / NEXT' }

.nviz--strategy .nvs-shot {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 5px;
  background: rgba(255, 255, 255, .12)
}

.nviz--strategy .nvs-shot::after {
  content: '';
  position: absolute;
  inset: 20% 19%;
  border-radius: 5px;
  background: rgba(255, 255, 255, .23)
}

.nviz--strategy .nvs-var--b .nvs-shot::after {
  inset: 12% 13% 29%;
  background: linear-gradient(145deg, rgba(185, 240, 219, .55), rgba(255, 255, 255, .12))
}

.nviz--strategy .nvs-var b {
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .42)
}

.nviz--strategy .nvs-var b:nth-of-type(1) { width: 84% }
.nviz--strategy .nvs-var b:nth-of-type(2) { width: 56% }

.nviz--strategy .nvs-var u {
  height: 20px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .3);
  margin-top: 2px
}

/* the winning version lifts and firms up once the numbers are in */
.nviz--strategy .nvs-var--b {
  animation: nvsWin 5.4s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvsWin {
  0%, 44% {
    transform: translateY(0);
    background: rgba(255, 255, 255, .13);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2)
  }

  60%, 86% {
    transform: translateY(-7px);
    background: rgba(255, 255, 255, .3);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .58)
  }

  100% {
    transform: translateY(0);
    background: rgba(255, 255, 255, .13);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2)
  }
}

.nviz--strategy .nvs-var--b u {
  animation: nvsWinCta 5.4s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvsWinCta {
  0%, 44% { background: rgba(255, 255, 255, .3) }
  60%, 86% { background: rgba(255, 255, 255, .82) }
  100% { background: rgba(255, 255, 255, .3) }
}

.nviz--strategy .nvs-flag {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 6px 14px -6px rgba(4, 26, 66, .8);
  animation: nvPop 5.4s cubic-bezier(.16, 1, .3, 1) 3.1s infinite backwards
}

.nviz--strategy .nvs-scores {
  display: flex;
  gap: 12px;
  flex: none
}

.nviz--strategy .nvs-score {
  flex: 1 1 0;
  height: 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .18);
  overflow: hidden
}

.nviz--strategy .nvs-score b {
  height: 100%;
  border-radius: 4px;
  background: rgba(255, 255, 255, .7);
  transform-origin: left
}

.nviz--strategy .nvs-score--a b { animation: nvsScoreA 5.4s cubic-bezier(.16, 1, .3, 1) infinite }
.nviz--strategy .nvs-score--b b { background: #b9f0db; animation: nvsScoreB 5.4s cubic-bezier(.16, 1, .3, 1) infinite }

@keyframes nvsScoreA {
  0% { transform: scaleX(0); opacity: 0 }
  8% { opacity: 1 }
  40%, 86% { transform: scaleX(.4); opacity: 1 }
  98%, 100% { transform: scaleX(.4); opacity: 0 }
}

@keyframes nvsScoreB {
  0% { transform: scaleX(0); opacity: 0 }
  8% { opacity: 1 }
  50%, 86% { transform: scaleX(.94); opacity: 1 }
  98%, 100% { transform: scaleX(.94); opacity: 0 }
}

/* ---------- Motion & Interaction: a row opening under the pointer ------
   The pointer arrives, the row it lands on opens, and the rows below make
   room for it — the motion is doing the explaining, which is the point. */
.nviz--motion .nvm-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  padding: 18px
}

.nviz--motion .nvm-row {
  border-radius: 8px;
  background: rgba(255, 255, 255, .12);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2);
  height: 34px;
  flex: none
}

.nviz--motion .nvm-row--open {
  position: relative;
  overflow: hidden;
  background: rgba(255, 255, 255, .2);
  animation: nvmOpen 4.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--motion .nvm-row--open::after {
  content: '↗';
  position: absolute;
  right: 11px;
  top: 7px;
  color: #b9f0db;
  font: 17px/1 var(--font-head);
  animation: nvmFill 4.4s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvmOpen {
  0%, 26% { height: 34px }
  46%, 76% { height: 96px }
  94%, 100% { height: 34px }
}

.nviz--motion .nvm-head {
  position: absolute;
  left: 12px;
  top: 13px;
  width: 46%;
  height: 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .8)
}

.nviz--motion .nvm-fill {
  position: absolute;
  left: 12px;
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .45);
  opacity: 0;
  animation: nvmFill 4.4s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--motion .nvm-fill--1 { top: 44px; width: 72%; animation-delay: .1s }
.nviz--motion .nvm-fill--2 { top: 64px; width: 52%; animation-delay: .18s }

@keyframes nvmFill {
  0%, 30% { opacity: 0; transform: translateY(8px) }
  50%, 74% { opacity: 1; transform: none }
  90%, 100% { opacity: 0; transform: translateY(8px) }
}

.nviz--motion .nvm-cursor {
  left: calc(22% + 36px);
  top: calc(72% - 82px);
  animation: nvmCursor 4.4s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvmCursor {
  0% { transform: translate(-36px, 82px) scale(1); opacity: 0 }
  10% { opacity: 1 }
  26% { transform: scale(1); opacity: 1 }
  34% { transform: scale(.76) }
  46%, 78% { transform: scale(1); opacity: 1 }
  94%, 100% { transform: translate(-36px, 82px) scale(1); opacity: 0 }
}

/* ---------- Paid traffic: the ad fires, the page assembles under it ----
   One cycle, and the last frame is the first one again, so the loop never
   snaps back. */
.nviz--paid .nvt-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  padding: 13px
}

.nviz--paid .nvt-ad {
  position: relative;
  height: 72px;
  width: 100%;
  flex: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, .2);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .24);
  display: flex;
  align-items: flex-end;
  padding: 9px;
  animation: nvtAd 6s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--paid .nvt-ad::before {
  content: 'AD';
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 3px 5px;
  border-radius: 4px;
  color: #fff;
  background: rgba(255, 255, 255, .18);
  font: 700 8px/1 var(--font-head)
}

@keyframes nvtAd {
  0%, 6% { background: rgba(255, 255, 255, .2) }
  16% { background: rgba(255, 255, 255, .38) }
  34%, 100% { background: rgba(255, 255, 255, .2) }
}

.nviz--paid .nvt-adbar {
  height: 8px;
  width: 56%;
  border-radius: 4px;
  background: rgba(255, 255, 255, .65)
}

.nviz--paid .nvt-pulse {
  position: absolute;
  right: 24px;
  top: 22px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .8);
  animation: nvtClick 6s ease-out infinite
}

.nviz--paid .nvt-cursor {
  right: 19px;
  top: 35px;
  animation: nvtCursor 6s cubic-bezier(.35, 0, .2, 1) infinite
}

@keyframes nvtCursor {
  0% { transform: translate(46px, 45px); opacity: 0 }
  5% { opacity: 1 }
  14% { transform: translate(0, 0); opacity: 1 }
  18% { transform: scale(.76); opacity: 1 }
  23% { transform: scale(1); opacity: 1 }
  31%, 100% { transform: scale(1); opacity: 0 }
}

@keyframes nvtClick {
  0%, 16% { transform: scale(.25); opacity: 0 }
  19% { opacity: .8 }
  31%, 100% { transform: scale(2.2); opacity: 0 }
}

/* the trail that carries the click down to the page */
.nviz--paid .nvt-trail {
  position: relative;
  height: 20px;
  flex: none
}

.nviz--paid .nvt-trail::after {
  content: '↓';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: #b9f0db;
  font: 20px/1 var(--font-head);
  animation: nvtDrop 6s ease-in-out infinite
}

@keyframes nvtDrop {
  0%, 18% { opacity: 0; transform: translate(-50%, -10px) }
  30%, 75% { opacity: 1; transform: translate(-50%, -50%) }
  100% { opacity: 0; transform: translate(-50%, 5px) }
}

.nviz--paid .nvt-page {
  position: relative;
  flex: none;
  height: 112px;
  width: 100%;
  min-height: 0;
  border-radius: 8px;
  background: rgba(255, 255, 255, .14);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 9px;
  padding: 9px;
  animation: nvtLand 6s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--paid .nvt-page::before {
  content: 'LANDING';
  position: absolute;
  top: 9px;
  left: 9px;
  color: rgba(255, 255, 255, .7);
  font: 700 7px/1 var(--font-head);
  letter-spacing: .08em
}

@keyframes nvtLand {
  0%, 10% { transform: translateY(12px); opacity: .32 }
  30%, 86% { transform: none; opacity: 1 }
  100% { transform: translateY(12px); opacity: .32 }
}

.nviz--paid .nvt-pl {
  height: 8px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .5)
}

.nviz--paid .nvt-pl--a { width: 78% }
.nviz--paid .nvt-pl--b { width: 54% }

.nviz--paid .nvt-cta {
  height: 28px;
  width: 90%;
  margin-top: 6px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .22);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3);
  transform-origin: left;
  animation: nvtCta 6s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvtCta {
  0%, 34% { background: rgba(255, 255, 255, .22) }
  52%, 86% { background: rgba(255, 255, 255, .5) }
  100% { background: rgba(255, 255, 255, .22) }
}

/* ---------- E-commerce: the buy button being pressed ------------------- */
.nviz--ecom .nvc-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 14px;
  min-height: 0
}

.nviz--ecom .nvc-shot {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 8px;
  background: linear-gradient(140deg, rgba(159, 212, 255, .19), rgba(255, 255, 255, .06));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
  background-size: 170% 170%;
  animation: nvShot 7s ease-in-out infinite alternate
}

.nviz--ecom .nvc-shot::before {
  content: '';
  position: absolute;
  left: 39%;
  right: 39%;
  top: 22%;
  bottom: 12%;
  border-radius: 18px 18px 10px 10px;
  background: linear-gradient(120deg, rgba(255, 255, 255, .64), rgba(165, 223, 255, .3));
  box-shadow: inset 5px 0 12px rgba(255, 255, 255, .19), 10px 12px 16px -12px rgba(4, 26, 66, .6);
  animation: nvcProduct 5s ease-in-out infinite
}

.nviz--ecom .nvc-shot::after {
  content: '';
  position: absolute;
  left: 43%;
  right: 43%;
  top: 16%;
  height: 6%;
  border-radius: 4px 4px 0 0;
  background: rgba(255, 255, 255, .72);
  animation: nvcProduct 5s ease-in-out infinite
}

@keyframes nvcProduct { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-5px) } }

@keyframes nvShot {
  0% { background-position: 0% 20% }
  100% { background-position: 100% 80% }
}

.nviz--ecom .nvc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex: none
}

.nviz--ecom .nvc-row b {
  height: 8px;
  width: 57%;
  border-radius: 4px;
  background: rgba(255, 255, 255, .45)
}

.nviz--ecom .nvc-row u {
  height: 8px;
  width: 25%;
  border-radius: 4px;
  background: rgba(255, 255, 255, .85)
}

.nviz--ecom .nvc-buy {
  position: relative;
  height: 38px;
  width: 100%;
  flex: none;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: rgba(255, 255, 255, .19);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .34);
  animation: nvcPress 4.2s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvcPress {
  0%, 34% { transform: scale(1); background: rgba(255, 255, 255, .19) }
  42% { transform: scale(.955); background: rgba(185, 240, 219, .38) }
  56%, 100% { transform: scale(1); background: rgba(255, 255, 255, .19) }
}

.nviz--ecom .nvc-buy b {
  color: #fff;
  font: 700 9px/1 var(--font-head);
  letter-spacing: .06em
}

.nviz--ecom .nvc-buy b::after { content: 'ADD TO CART' }

.nviz--ecom .nvc-cart { width: 18px; height: 18px; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }

.nviz--ecom .nvc-ripple {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .55);
  animation: nvcClick 4.2s ease-out infinite
}

.nviz--ecom .nvc-cursor {
  left: calc(50% + 8px);
  bottom: 21px;
  animation: nvcCursor 4.2s cubic-bezier(.16, 1, .3, 1) infinite
}

@keyframes nvcCursor {
  0% { transform: translate(54px, 42px); opacity: 0 }
  12% { opacity: 1 }
  34% { transform: translate(0, 0); opacity: 1 }
  42% { transform: scale(.76); opacity: 1 }
  49% { transform: scale(1); opacity: 1 }
  60%, 100% { transform: scale(1); opacity: 0 }
}

@keyframes nvcClick {
  0%, 39% { transform: translate(-50%, -50%) scale(.25); opacity: 0 }
  43% { opacity: .7 }
  58%, 100% { transform: translate(-50%, -50%) scale(2); opacity: 0 }
}

/* ---------- Local business: the pin, and the ground it covers ---------- */
.nviz--local .nvn-map {
  flex: 1 1 auto;
  background:
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .09) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .09) 0 1px, transparent 1px 34px),
    rgba(255, 255, 255, .06)
}

.nviz--local .nvn-map::after {
  content: '●  OPEN NOW  ·  2 MIN AWAY';
  position: absolute;
  left: 15px;
  right: 15px;
  bottom: 15px;
  padding: 12px 9px;
  border-radius: 8px;
  color: #e8fff5;
  background: rgba(19, 72, 150, .46);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25);
  font: 700 8px/1 var(--font-head);
  letter-spacing: .04em;
  animation: nvRise 4.2s cubic-bezier(.16, 1, .3, 1) infinite .6s
}

/* the rings start from nothing rather than popping in at full size, and the
   first one only leaves once the pin has landed */
@keyframes nvRadar {
  0% { transform: translate(-50%, -50%) scale(.18); opacity: 0 }
  14% { opacity: .6 }
  100% { transform: translate(-50%, -50%) scale(2.5); opacity: 0 }
}

.nviz--local .nvn-ring {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 82px;
  height: 82px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .6);
  opacity: 0;
  animation: nvRadar 4.2s ease-out infinite
}

.nviz--local .nvn-ring--1 { animation-delay: .55s }
.nviz--local .nvn-ring--2 { animation-delay: 1.95s }
.nviz--local .nvn-ring--3 { animation-delay: 3.35s }

.nviz--local .nvn-pin {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 26px;
  height: 26px;
  margin: -23px 0 0 -13px;
  border-radius: 50% 50% 50% 0;
  background: #fff;
  box-shadow: 0 8px 16px -8px rgba(4, 26, 66, .8);
  animation: nvPinDrop 4.2s cubic-bezier(.16, 1, .3, 1) infinite
}

.nviz--local .nvn-pin::after {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: #2d70d1
}

@keyframes nvPinDrop {
  0% { opacity: 0; transform: translateY(-22px) rotate(-45deg) }
  18%, 86% { opacity: 1; transform: translateY(0) rotate(-45deg) }
  100% { opacity: 0; transform: translateY(-10px) rotate(-45deg) }
}

/* ---------- Agencies: one build, every badge --------------------------
   The shell never changes — the same header, the same hero, the same CTA.
   Only the brand running through it does, which is the whole offer. */
@property --nvacc {
  syntax: '<color>';
  inherits: true;
  initial-value: #7fd4ff;
}

.nviz--agency .nvg-stage {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 14px;
  min-height: 0;
  animation: nvgBrand 9s ease-in-out infinite
}

@keyframes nvgBrand {
  0%, 26% { --nvacc: #7fd4ff }
  33%, 59% { --nvacc: #b7e8c8 }
  66%, 92% { --nvacc: #ffc9d6 }
  100% { --nvacc: #7fd4ff }
}

.nviz--agency .nvg-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding-bottom: 11px;
  border-bottom: 1px solid rgba(255, 255, 255, .16)
}

.nviz--agency .nvg-mark {
  width: 22px;
  height: 22px;
  border-radius: 7px;
  background: var(--nvacc);
  flex: none;
  animation: nvgMark 9s ease-in-out infinite
}

@keyframes nvgMark {
  0%, 22% { border-radius: 7px; transform: rotate(0) }
  33%, 55% { border-radius: 50%; transform: rotate(0) }
  66%, 88% { border-radius: 4px; transform: rotate(45deg) }
  100% { border-radius: 7px; transform: rotate(0) }
}

.nviz--agency .nvg-bar b {
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .34)
}

.nviz--agency .nvg-bar b:nth-child(2) { width: 38px }
.nviz--agency .nvg-bar b:nth-child(3) { width: 26px }

.nviz--agency .nvg-hero {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 8px;
  background: linear-gradient(150deg, color-mix(in srgb, var(--nvacc) 30%, transparent), rgba(255, 255, 255, .05));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2)
}

.nviz--agency .nvg-hero::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 68px;
  height: 68px;
  border: 2px solid var(--nvacc);
  border-radius: 18px;
  transform: translate(-50%, -50%) rotate(-12deg);
  animation: nvgFrame 9s ease-in-out infinite
}

.nviz--agency .nvg-hero::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 31px;
  height: 31px;
  border-radius: 50%;
  background: var(--nvacc);
  transform: translate(-50%, -50%);
  box-shadow: 0 0 0 13px rgba(255, 255, 255, .08)
}

@keyframes nvgFrame {
  0%, 26%, 100% { border-radius: 18px; transform: translate(-50%, -50%) rotate(-12deg) }
  33%, 59% { border-radius: 50%; transform: translate(-50%, -50%) rotate(0deg) }
  66%, 92% { border-radius: 10px; transform: translate(-50%, -50%) rotate(45deg) }
}

.nviz--agency .nvg-line {
  height: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .38);
  flex: none
}

.nviz--agency .nvg-line--a { width: 82% }
.nviz--agency .nvg-line--b { width: 56% }

.nviz--agency .nvg-cta {
  height: 30px;
  width: 62%;
  border-radius: 8px;
  flex: none;
  background: color-mix(in srgb, var(--nvacc) 62%, transparent)
}

@media (prefers-reduced-motion: reduce) {
  .nav-sub__preview .nviz * { animation: none !important; transition: none !important }
  .nviz--perf .nvp-dial { --nvp: 360deg }
  .nviz--analytics .nva-line { clip-path: inset(0 0 0 0) }
  .nviz--motion .nvm-row--open { height: 96px }
  .nviz--motion .nvm-fill { opacity: 1 }
  .nviz--launch .nvl-cta { transform: translate(-50%, -50%) }
  .nviz--coaching .nvk-grid b,
  .nviz--coaching .nvk-confirm { opacity: 1; transform: none }
  .nviz--coaching .nvk-grid b:nth-child(13) { background: #fff; color: #1955a8 }
  .nviz--coaching .nvk-confirm::before { display: none }
  .nviz--coaching .nvk-confirm::after { animation: none !important; opacity: 1 }
  .nviz--paid .nvt-trail::after { animation: none !important; opacity: 1; transform: translate(-50%, -50%) }
  .nviz--motion .nvm-cursor,
  .nviz--ecom .nvc-cursor,
  .nviz--analytics .nva-cursor,
  .nviz--leads .nvf-cursor,
  .nviz--paid .nvt-cursor,
  .nviz--saas .nxs-transfer b,
  .nviz--launch .nvl-ping,
  .nviz--launch .nvl-cursor,
  .nviz--launch .nvl-rocket,
  .nviz--coaching .nvk-cursor,
  .nviz--design .nvd-guide,
  .nviz--analytics .nva-ping,
  .nviz--paid .nvt-pulse,
  .nviz--ecom .nvc-ripple,
  .nviz--refresh .nvr-wipe { opacity: 0 }
  .nviz--refresh .nvr-old { opacity: 0 }
  .nviz--refresh .nvr-new { clip-path: inset(0 0 0 0) }
  .nviz--local .nvn-pin { transform: rotate(-45deg) }
}

/* =====================================================================
   Card visualisations — a white panel inside a glass card
   The card itself stays transparent; the study inside it sits on a white
   panel of its own, and everything drawn on that panel is inked in the
   page's midnight blue with the brand accents carrying the detail. Only
   the two frames below turn white — the cards around them are untouched.
   Services and Solutions keep their own palette; none of this reaches them.
   ===================================================================== */
.viz,
.fviz {
  --ink: 11, 45, 92;
  --acc-blue: #2b84ff;
  --acc-lime: #7fc41f;
  --acc-violet: #b18aff;
  --acc-amber: #f0b429;
}

.fviz,
.viz__frame {
  background: linear-gradient(180deg, #fff 0%, #f1f6fd 100%);
  border: 1px solid rgba(var(--ink), .1);
  box-shadow: 0 20px 44px -30px rgba(4, 26, 66, .55)
}

/* ---- the shared pillar primitives, now inked rather than washed ---- */
.viz .vz-line { background: rgba(var(--ink), .22) }
.viz .vz-line--xl { background: rgba(var(--ink), .8) }
.viz .vz-line--lg { background: rgba(var(--ink), .5) }
.viz .vz-line--sm { background: rgba(var(--ink), .24) }
.viz .vz-line--xs { background: rgba(var(--ink), .14) }
.viz .vz-pill { background: var(--acc-blue) }
.viz .vz-pill--sm { background: rgba(var(--ink), .16) }
.viz .vz-square { background: rgba(var(--ink), .1) }

/* ---- Structure: browser chrome, and the colour is in the dots ---- */
.viz--structure .vz-nav { background: rgba(var(--ink), .05) }
.viz--structure .vz-navbar { background: rgba(var(--ink), .16) }
.viz--structure .vz-block { background: rgba(var(--ink), .045) }
.viz--structure .vz-dot:nth-child(1) { background: var(--acc-blue) }
.viz--structure .vz-dot:nth-child(2) { background: var(--acc-lime) }
.viz--structure .vz-dot:nth-child(3) { background: var(--acc-amber) }

/* ---- Design: the swatches were always the colour; the card is real paper now ---- */
.viz--design .vd-type b { color: rgba(var(--ink), .9) }
.viz--design .vd-shape { background: rgba(var(--ink), .09) }
.viz--design .vd-shape--squircle { background: rgba(var(--ink), .07) }
.viz--design .vd-grid i { background: rgba(var(--ink), .12) }
.viz--design .vd-card {
  background: #fff;
  border-color: rgba(var(--ink), .1);
  box-shadow: 0 14px 30px -18px rgba(4, 26, 66, .45)
}

/* ---- Convert: a lime eyebrow, inked copy, and a blue CTA ---- */
.viz--convert .vc-eyebrow { background: var(--acc-lime) }
.viz--convert .vc-head { background: rgba(var(--ink), .82) }
.viz--convert .vc-sub { background: rgba(var(--ink), .24) }
.viz--convert .vc-trust { background: rgba(var(--ink), .14) }
.viz--convert .vc-cta {
  background: var(--acc-blue);
  color: #fff;
  box-shadow: 0 12px 24px -14px rgba(43, 132, 255, .9)
}
.viz--convert .vc-cursor { color: rgba(var(--ink), .85) }
.viz--convert .vc-ripple { border-color: rgba(43, 132, 255, .6) }

/* The unchanged Analytics and Performance studies retain their ink-and-lime palette. */
.fviz--ana .fn-kpi { background: rgba(var(--ink), .75) }
.fviz--ana .fn-chip { background: var(--acc-lime) }
.fviz--ana .fn-bars i { background: linear-gradient(180deg, rgba(var(--ink), .3), rgba(var(--ink), .1)) }
.fviz--ana .fn-bars i:nth-child(6),
.fviz--ana .fn-bars i:nth-child(8) { background: linear-gradient(180deg, var(--acc-lime), rgba(127, 196, 31, .35)) }
.fviz--perf .fp-score { color: rgba(var(--ink), .85) }
.fviz--perf .fp-lab { background: rgba(var(--ink), .16) }
.fviz--perf .fp-track { background: rgba(var(--ink), .09) }
.fviz--perf .fp-arc { background: conic-gradient(from 140deg, var(--acc-lime) 0turn, var(--acc-lime) var(--p, 0turn), rgba(var(--ink), .1) var(--p, 0turn), rgba(var(--ink), .1) .72turn, transparent .72turn) }
.fviz--perf .fp-track b { background: linear-gradient(90deg, var(--acc-blue), var(--acc-lime)) }

/* =====================================================================
   A whisper of shadow under the card copy
   These two card sets sit on the sky, and white type over cloud loses its
   edge wherever a bright cumulus passes behind it. This is deliberately
   almost invisible: one pixel of offset and a short blur, at an opacity
   low enough that you notice the legibility rather than the shadow. The
   cards themselves are untouched — same glass, same transparency.
   ===================================================================== */
.fcard h4,
.fcard p,
.pillar__title,
.pillar__copy,
.pillar__eyebrow {
  text-shadow: 0 1px 2px rgba(4, 26, 66, .2)
}

/* =====================================================================
   Support that stays — the copy reads in order now
   The three lines were within a few points of each other, so nothing led.
   The name leads, the promise sits under it as a clear second voice, and
   the detail steps back to body weight. On a phone the CTA also leaves the
   corner and joins the flow, which is what it was overlapping from.
   ===================================================================== */
.plan__copy h3 {
  font-size: 34px;
  line-height: 1.05;
  margin-bottom: 10px
}

.plan__copy h4 {
  font-size: 19px;
  line-height: 26px;
  font-weight: 500;
  margin-bottom: 12px;
  color: rgba(255, 255, 255, .96)
}

.plan__copy p {
  font-size: 15px;
  line-height: 23px;
  color: rgba(255, 255, 255, .78);
  max-width: 52ch
}

@media (max-width:860px) {

  /* the CTA is in the flow here, so it can never land on the paragraph */
  .plan {
    padding: 26px 22px;
    gap: 18px
  }

  .plan__cta {
    position: static;
    align-self: flex-end;
    height: 44px;
    padding: 0 22px;
    margin-top: 10px
  }

  .plan__copy {
    max-width: none
  }

  .plan__copy h3 {
    font-size: 28px;
    margin-bottom: 8px
  }

  .plan__copy h4 {
    font-size: 17px;
    line-height: 24px;
    margin-bottom: 10px
  }

  .plan__copy p {
    font-size: 14px;
    line-height: 21px
  }
}

/* Keep the compact desktop controls; enlarge only for actual touch input. */
.s--intro .btn--outline { scale: 1 1.26316 }
.s--intro .btn--outline span { scale: 1 .79167 }
@media (hover:none) and (pointer:coarse) {
  .hdr__ctas .btn, .s--intro .btn--white { height: 48px }
  .hdr__ctas .btn--icon { width: 48px }
  /* a touch slot wider than the disc it holds, but nothing like the 48px it
     used to reserve — the rail is a control, not a toolbar */
  .tod { --tod-slot: 36px; --tod-knob: 28px }
}
@media (max-width:860px) and (hover:none) and (pointer:coarse) {
  .tod { --tod-slot: 34px; --tod-knob: 30px }
}
