@font-face {
  font-family: "Grift Variable";
  src: url("https://leadly-website.pages.dev/assets/font-e493ed80f9e4.ttf") format("truetype");
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
}

@font-face {
  font-family: "Grift";
  src: url("https://leadly-website.pages.dev/assets/font-2661be2efdd9.ttf") format("truetype");
  font-style: normal;
  font-weight: 900;
  font-display: swap;
}

@font-face {
  font-family: "Grift";
  src: url("https://leadly-website.pages.dev/assets/font-83181fdc2764.ttf") format("truetype");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Sequel Sans";
  src: url("https://leadly-website.pages.dev/assets/font-6a7ffc8e23e9.otf") format("opentype");
  font-style: normal;
  font-weight: 310;
  font-display: swap;
}

@font-face {
  font-family: "Sequel Sans";
  src: url("https://leadly-website.pages.dev/assets/font-167a2b173473.otf") format("opentype");
  font-style: normal;
  font-weight: 360;
  font-display: swap;
}

@font-face {
  font-family: "Sequel Sans";
  src: url("https://leadly-website.pages.dev/assets/font-05dcb3b87a2d.otf") format("opentype");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

:root {
  --bg: #f6f6f8;
  --surface: rgba(255, 255, 255, 0.58);
  --surface-strong: rgba(255, 255, 255, 0.8);
  --surface-dark: rgba(46, 46, 46, 0.78);
  --text: #2e2e2e;
  --text-soft: rgba(46, 46, 46, 0.72);
  --white: #f4f4f4;
  --pink: #ff0099;
  --purple: #8849fc;
  --border: rgba(46, 46, 46, 0.12);
  --shadow: 0 24px 80px rgba(46, 46, 46, 0.12);
  --shadow-soft: 0 18px 42px rgba(46, 46, 46, 0.08);
  --radius-xl: 34px;
  --radius-lg: 28px;
  --radius-md: 22px;
  --radius-sm: 16px;
  --nav-height: 109px;
  --shell: min(1240px, calc(100vw - 3rem));
  --boxed-guide-width: min(1180px, calc(100vw - 2.5rem));
  --hero-progress: 0;
  --hero-title-opacity: 1;
  --hero-title-scale: 1;
  --hero-cta-progress: 0;
  --hero-cta-travel-fade: 0;
  --travel-dot-width: 44px;
  --travel-dot-height: 44px;
  --travel-dot-radius: 999px;
  --travel-dot-scale: 1;
  --why-cta-reveal: 0;
  --why-cta-content-reveal: 0;
  --services-progress: 0;
  --services-intro-progress: 0;
  --shrink-progress: 1;
  --products-progress: 0;
  --font-display: "Grift Variable", "Grift", "Avenir Next", "Segoe UI", sans-serif;
  --font-body: "Sequel Sans", "Avenir Next", "Segoe UI", sans-serif;
  --font-nav: "Sequel Sans", "Avenir Next", "Segoe UI", sans-serif;
  --body-copy-size: 16px;
  --body-copy-weight: 310;
  --body-copy-letter-spacing: 0;
  --body-copy-line-height: 1.625;
  --ease-standard: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-snappy: cubic-bezier(0.2, 0.8, 0.2, 1);
  /* Slight overshoot — boxes settle rather than glide to a stop. */
  --ease-settle: cubic-bezier(0.22, 1.15, 0.36, 1);
  --motion-fast: 180ms;
  --motion-base: 280ms;
  --motion-slow: 520ms;
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-synthesis-weight: none;
  overflow-x: hidden;
}

body.menu-open {
  overflow: hidden;
}

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

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

button {
  font: inherit;
}

p,
li {
  font-family: var(--font-body);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  letter-spacing: var(--body-copy-letter-spacing);
  line-height: var(--body-copy-line-height);
}

span,
a,
button {
  font-size: 1rem;
  line-height: 1.6;
}

h1,
h2,
h3,
strong,
.brand,
.footer-brand {
  font-family: var(--font-display);
}

h1,
h2,
h3,
p,
ul {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

.page-noise {
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0.02)),
    radial-gradient(circle at 20% 20%, rgba(46, 46, 46, 0.02) 0.05rem, transparent 0.06rem);
  background-size: auto, 1.1rem 1.1rem;
  mix-blend-mode: multiply;
  opacity: 0.18;
  pointer-events: none;
  z-index: 1;
}

.section-shell {
  width: var(--shell);
  margin: 0 auto;
  position: relative;
  z-index: 2;
}

.section-light {
  background: transparent;
}

.section-dark {
  background:
    radial-gradient(circle at 20% 0%, rgba(255, 0, 153, 0.12), transparent 24%),
    radial-gradient(circle at 90% 100%, rgba(136, 73, 252, 0.12), transparent 22%),
    #242424;
  color: var(--white);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(46, 46, 46, 0.6);
}

.eyebrow::before {
  content: "";
  width: 2.4rem;
  height: 0.18rem;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--pink), rgba(255, 0, 153, 0.2));
}

.eyebrow-light {
  color: rgba(244, 244, 244, 0.72);
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 12.5rem;
  min-height: 3.85rem;
  padding: 0.95rem 1.7rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 1rem;
  font-weight: 700;
  transition:
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease,
    background-color var(--motion-fast) ease,
    color var(--motion-fast) ease,
    filter var(--motion-base) ease;
}

.button:hover,
.button:focus-visible {
  transform: translateY(-4px) scale(1.018);
  filter: saturate(1.06) brightness(1.02);
}

.motion-reveal {
  --reveal-delay: 0ms;
  opacity: 0;
  transform: translate3d(0, 28px, 0) scale(0.985);
  filter: blur(10px);
  transition:
    opacity var(--motion-slow) var(--ease-soft),
    transform var(--motion-slow) var(--ease-soft),
    filter var(--motion-base) ease;
  transition-delay: var(--reveal-delay);
  will-change: transform, opacity, filter;
}

.motion-reveal.is-inview {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  filter: blur(0);
}

.button-primary {
  background: linear-gradient(135deg, var(--pink), #ff37a9);
  color: #fff;
  box-shadow: 0 18px 34px rgba(255, 0, 153, 0.24);
  overflow: hidden;
}

.button-primary::before {
  content: "";
  position: absolute;
  top: 0;
  left: -110%;
  width: 56%;
  height: 100%;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.22) 50%,
    transparent 100%
  );
  transform: skewX(-18deg);
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease;
}

.button-primary:hover::before,
.button-primary:focus-visible::before {
  opacity: 1;
  animation: btn-shimmer 0.56s ease forwards;
}

.site-header {
  position: fixed;
  top: 2.3125rem;
  left: 0;
  width: 100%;
  padding: 0 1rem;
  z-index: 30;
  pointer-events: none;
  will-change: transform;
  transition: transform var(--motion-base) var(--ease-standard);
}

.nav-shell {
  position: relative;
  isolation: isolate;
  width: var(--boxed-guide-width);
  min-height: 72px;
  margin: 0 auto;
  padding: 0 18px 0 43px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border: 1px solid rgba(250, 250, 250, 0.9);
  border-radius: 20px;
  overflow: visible;
  -webkit-backdrop-filter: blur(28px) saturate(190%);
  backdrop-filter: blur(28px) saturate(190%);
  background: rgba(242, 242, 242, 0.16);
  box-shadow:
    0 10px 36px rgba(46, 46, 46, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  pointer-events: auto;
  transition:
    background-color var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    color var(--motion-fast) ease,
    box-shadow var(--motion-base) ease,
    transform var(--motion-base) var(--ease-standard);
}

.nav-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.46), rgba(255, 255, 255, 0.1)),
    linear-gradient(90deg, rgba(255, 255, 255, 0.18), transparent 32%, rgba(255, 255, 255, 0.08));
  pointer-events: none;
  z-index: 0;
}

.nav-shell > * {
  position: relative;
  z-index: 1;
}

/* The inner pages open straight into content, with no hero for the nav to
   sit inside, so they hold the compact position from the start instead of
   only after 40px of scroll — otherwise the nav sits lower on faq/contact
   than on the homepage you just came from, which reads as a jump in the
   top gap. Grouped with the scrolled selector rather than given its own
   rule so it inherits the per-breakpoint offsets below (the tuck is
   smaller on narrow screens, where a flat -0.85rem clipped the bar). */
body.nav-scrolled .site-header,
body.contact-page .site-header {
  transform: translateY(-0.85rem);
}

body.nav-scrolled .nav-shell {
  background: rgba(242, 242, 242, 0.22);
  box-shadow:
    0 12px 40px rgba(46, 46, 46, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.74);
}

body[data-nav-theme="dark"] .nav-shell {
  background: rgba(33, 33, 33, 0.42);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--white);
  box-shadow:
    0 14px 42px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

body[data-nav-theme="dark"] .nav-shell::before {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02)),
    linear-gradient(90deg, rgba(255, 255, 255, 0.08), transparent 34%, rgba(255, 255, 255, 0.04));
}

body[data-nav-theme="dark"] .nav-links a,
body[data-nav-theme="dark"] .nav-menu a:not(.nav-cta) {
  color: rgba(244, 244, 244, 0.88);
}

.brand,
.footer-brand {
  display: inline-flex;
  align-items: flex-end;
  gap: 0.08em;
  font-size: clamp(2rem, 2.4vw, 2.55rem);
  font-weight: 900;
  line-height: 0.8;
  letter-spacing: -0.08em;
}

.site-header .brand {
  flex: 0 0 auto;
  font-size: 0;
  line-height: 0;
}

.brand-word,
.footer-brand .brand-word {
  display: inline-block;
}

.brand-logo {
  display: block;
  width: 106px;
  height: auto;
  transform: translateY(2px);
}

.brand-dot,
.footer-brand .brand-dot {
  color: var(--pink);
  font-size: 1.08em;
}

.nav-menu {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  justify-content: space-between;
  gap: 0;
  margin-left: 93px;
  font-family: var(--font-nav);
  overflow: visible;
}

.nav-links {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex: 0 0 auto;
  gap: 18px;
  overflow: visible;
}

.nav-about-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 94px;
  min-height: 70px;
  overflow: visible;
}

.nav-links a,
.nav-menu a {
  font-size: 15.5px;
  font-weight: 360;
  line-height: 24px;
  color: #515151;
}

.nav-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-height: 70px;
  padding: 0;
  white-space: nowrap;
  overflow: hidden;
  transition: color var(--motion-fast) ease;
}

.nav-links a:nth-child(1) {
  width: 94px;
}

.nav-links a:nth-child(2) {
  width: 94px;
}

.nav-links a:nth-child(3) {
  width: 128px;
}

.nav-links a:nth-child(4) {
  width: 88px;
}

.nav-links a:nth-child(5) {
  width: 63px;
}

.nav-links a:nth-child(6) {
  width: 106px;
}

.nav-about-panel {
  position: absolute;
  top: calc(100% - 6px);
  left: -0.4rem;
  width: clamp(19rem, 29vw, 23rem);
  padding: 0.95rem;
  border-radius: 24px;
  border: 1px solid rgba(46, 46, 46, 0.08);
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 22px 46px rgba(46, 46, 46, 0.14);
  backdrop-filter: blur(20px);
  display: grid;
  align-items: center;
  grid-template-columns: minmax(8.5rem, 1.05fr) minmax(0, 1fr);
  gap: 0.9rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(12px) scale(0.985);
  transform-origin: top left;
  transition:
    opacity 220ms ease,
    transform 320ms var(--ease-standard),
    visibility 220ms ease;
  z-index: 15;
}

.nav-about-wrap:hover .nav-about-panel,
.nav-about-wrap:focus-within .nav-about-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}

.nav-about-media {
  position: relative;
  min-height: 0;
  height: 6.95rem;
  border-radius: 18px;
  overflow: hidden;
  background: #111;
}

.nav-about-media::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
  pointer-events: none;
}

.nav-about-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}

.nav-about-media span {
  position: relative;
  z-index: 1;
  color: rgba(255, 255, 255, 0.94);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.nav-about-links {
  display: grid;
  align-content: center;
  gap: 0.65rem;
}

.nav-about-subpage {
  appearance: none;
  border: 1px solid rgba(46, 46, 46, 0.08);
  background: rgba(255, 255, 255, 0.92);
  border-radius: 18px;
  padding: 0.95rem 1rem;
  color: #2e2e2e;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 360;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  transition:
    transform var(--motion-base) var(--ease-standard),
    background-color var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    box-shadow var(--motion-base) ease;
}

.nav-about-subpage:hover,
.nav-about-subpage:focus-visible {
  background: #fff;
  border-color: rgba(255, 0, 153, 0.18);
  box-shadow: 0 12px 24px rgba(46, 46, 46, 0.08);
  transform: translateX(4px);
}

.nav-link-track {
  position: relative;
  display: grid;
  place-items: center;
  /* Tall enough that descenders (the g in Insights) are not clipped. */
  height: 1.3em;
  overflow: hidden;
}

.nav-link-track > span {
  grid-area: 1 / 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1.3;
  white-space: nowrap;
  transition:
    transform 440ms cubic-bezier(0.18, 1, 0.32, 1),
    opacity 240ms ease;
  will-change: transform;
}

.nav-link-track > span:first-child {
  transform: translateY(0);
  opacity: 1;
}

.nav-link-track > span:last-child {
  transform: translateY(110%);
  opacity: 0;
  color: var(--pink);
}

.nav-links a:hover .nav-link-track > span:first-child,
.nav-links a:focus-visible .nav-link-track > span:first-child {
  transform: translateY(-110%);
  opacity: 0;
}

.nav-about-wrap:hover > a .nav-link-track > span:first-child,
.nav-about-wrap:focus-within > a .nav-link-track > span:first-child {
  transform: translateY(-110%);
  opacity: 0;
}

.nav-links a:hover .nav-link-track > span:last-child,
.nav-links a:focus-visible .nav-link-track > span:last-child {
  transform: translateY(0);
  opacity: 1;
}

.nav-about-wrap:hover > a .nav-link-track > span:last-child,
.nav-about-wrap:focus-within > a .nav-link-track > span:last-child {
  transform: translateY(0);
  opacity: 1;
}

.nav-links a:hover,
.nav-links a:focus-visible {
  color: #1a1a1a;
}

.nav-about-wrap:hover > a,
.nav-about-wrap:focus-within > a {
  color: #1a1a1a;
}

body[data-nav-theme="dark"] .nav-links a:hover,
body[data-nav-theme="dark"] .nav-links a:focus-visible {
  color: rgba(255, 255, 255, 1);
}

.nav-links a::after {
  content: "";
  position: absolute;
  bottom: 16px;
  left: 50%;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--pink);
  transform: translateX(-50%) scale(0);
  opacity: 0;
  transition:
    transform 320ms var(--ease-standard),
    opacity 240ms ease;
  pointer-events: none;
}

.nav-links a:hover::after,
.nav-links a:focus-visible::after {
  transform: translateX(-50%) scale(1);
  opacity: 1;
}

.nav-about-wrap:hover > a::after,
.nav-about-wrap:focus-within > a::after {
  transform: translateX(-50%) scale(1);
  opacity: 1;
}

.nav-cta {
  --hover-x: 50%;
  --hover-y: 50%;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 132px;
  min-width: 132px;
  height: 36px;
  padding: 0;
  border-radius: 20px;
  background: var(--pink);
  color: #fff !important;
  -webkit-text-fill-color: #fff;
  font-size: 14.6px;
  font-weight: 310;
  line-height: 22.5px;
  outline: 1px solid rgba(255, 255, 255, 0.08);
  outline-offset: -1px;
  background-image: linear-gradient(135deg, #ff0099 0%, #ff37a9 48%, #ff0099 100%);
  background-size: 180% 180%;
  background-position: 0% 50%;
  overflow: hidden;
  transition:
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease,
    filter var(--motion-base) ease,
    background-position var(--motion-slow) ease,
    letter-spacing var(--motion-fast) ease;
}

.nav-cta::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  background:
    radial-gradient(
      100px circle at var(--hover-x) var(--hover-y),
      rgba(255, 255, 255, 0.48) 0%,
      rgba(255, 255, 255, 0.18) 34%,
      rgba(255, 255, 255, 0) 72%
    );
  opacity: 0;
  transition: opacity 140ms ease;
  pointer-events: none;
}

.nav-cta::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  border: 1px solid rgba(255, 255, 255, 0.12);
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity var(--motion-base) ease,
    transform var(--motion-base) var(--ease-standard);
  pointer-events: none;
}

.nav-menu .nav-cta,
.nav-menu a.nav-cta,
.nav-menu .nav-cta:visited,
.nav-menu .nav-cta:hover,
.nav-menu .nav-cta:focus-visible {
  color: #fff !important;
  -webkit-text-fill-color: #fff;
}

.nav-cta:hover,
.nav-cta:focus-visible {
  transform: translateY(-2.5px) scale(1.035);
  box-shadow:
    0 22px 42px rgba(255, 0, 153, 0.28),
    0 10px 22px rgba(255, 0, 153, 0.12);
  filter: saturate(1.1) brightness(1.04);
  background-position: 100% 50%;
  letter-spacing: 0.01em;
}

.nav-cta:hover::before,
.nav-cta:focus-visible::before {
  opacity: 1;
}

.nav-cta:hover::after,
.nav-cta:focus-visible::after {
  opacity: 1;
  transform: scale(1);
}

.menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  /* No pill behind the bars — the icon stands on its own. The box is
     kept at 44px so the tap target stays a full one even though nothing
     is drawn around it. */
  width: 2.75rem;
  height: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

/* Three bars from one element: the middle is the span itself, the outer
   two are its pseudo-elements. They fold into a cross when the menu is
   open, so the control says what it will do next without a word of
   copy. currentColor, so it follows the nav's light/dark theme. The
   button keeps its accessible name from aria-label. */
.menu-toggle-bars {
  position: relative;
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: background-color 160ms ease;
}

.menu-toggle-bars::before,
.menu-toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: currentColor;
  transition: transform 340ms cubic-bezier(0.22, 1, 0.36, 1);
}

.menu-toggle-bars::before {
  top: -6px;
}

.menu-toggle-bars::after {
  top: 6px;
}

body.menu-open .menu-toggle-bars {
  background: transparent;
}

body.menu-open .menu-toggle-bars::before {
  transform: translateY(6px) rotate(45deg);
}

body.menu-open .menu-toggle-bars::after {
  transform: translateY(-6px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .menu-toggle-bars,
  .menu-toggle-bars::before,
  .menu-toggle-bars::after {
    transition: none;
  }
}

.hero-section {
  min-height: 290vh;
  position: relative;
  overflow: clip;
}

.hero-stage {
  position: sticky;
  top: 0;
  min-height: max(100vh, 862px);
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  overflow: clip;
  display: block;
  padding: 0;
}

.hero-backdrop {
  position: absolute;
  inset: 0;
  background: var(--bg);
}

.hero-copy {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 5;
  width: min(956px, calc(100vw - 3rem));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  text-align: center;
  transform:
    translate(-50%, -50%)
    translateY(calc(var(--hero-progress) * -0.9rem))
    scale(var(--hero-title-scale));
  opacity: var(--hero-title-opacity);
  will-change: transform, opacity;
}

.hero-title {
  position: relative;
  margin: 0;
  font-family: "Grift Variable", "Grift", "Avenir Next", "Segoe UI", sans-serif;
  font-size: 131px;
  line-height: 128px;
  letter-spacing: -3px;
  font-weight: 800;
  font-variation-settings: "wght" 800;
  color: #2e2e2e;
  text-align: center;
}

.hero-subtitle {
  max-width: 720px;
  margin: 1.25rem 0 0;
  color: #2e2e2e;
  font-family: "Sequel Sans", "Avenir Next", "Segoe UI", sans-serif;
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  line-height: 1.35;
  font-weight: 300;
  text-align: center;
}

.hero-line {
  display: block;
  white-space: nowrap;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}

.hero-line:last-child {
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  gap: 0;
}

.hero-dot-anchor {
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  min-width: 0;
  margin-left: -0.015em;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: var(--pink);
}

.hero-cluster {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 7;
}

.hero-card {
  position: absolute;
  left: 50%;
  top: 50%;
  display: block;
  border: 0;
  border-radius: 0;
  box-shadow: 0 22px 44px rgba(46, 46, 46, 0.14);
  backdrop-filter: none;
  overflow: hidden;
  isolation: isolate;
  /* --home-x/--home-y default to 0 (no effect at the reference desktop
     size) and are overridden per breakpoint below. script.js reads the
     current value and folds it into the *converged resting position*
     only (not the entrance path) - see updateHero(). */
  --home-x: 0;
  --home-y: 0;
  transform:
    translate3d(-50%, -50%, 0)
    translate(calc(var(--card-x, 0) * 1vw), calc(var(--card-y, 0) * 1vh))
    rotate(calc(var(--card-rotate, 0) * 1deg))
    scale(var(--card-scale, 1));
  opacity: var(--card-opacity, 0);
  will-change: transform, opacity;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.hero-card-photo {
  border-radius: 1.95rem;
}

.hero-card-asset {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
  transform-origin: center;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: none;
  animation: none;
}

.hero-card.card-photo-smile {
  width: clamp(11.75rem, 13.8vw, 12.9rem);
}

.hero-card.card-photo-street {
  width: clamp(10.6rem, 12.5vw, 11.8rem);
}

.hero-card.card-photo-laptop {
  width: clamp(11.2rem, 13.5vw, 12.5rem);
}

.hero-card-stat {
  width: clamp(12.2rem, 14.1vw, 13.5rem);
  border-radius: 1.8rem;
  background: #2e2e2e;
  /* The figures used to be flattened artwork on a 460x360 frame. They
     are live text now, so the card holds that frame itself and the
     cluster geometry in script.js is unchanged. Type is sized in cqw
     against the card's own width, which is what the artwork's own
     scaling did: one rule covers every breakpoint. */
  aspect-ratio: 460 / 360;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* No padding on the card itself: a percentage would resolve against
     the containing block (the full-width cluster) and a cqw against the
     next container out (the viewport) — both of which measure ~1440px,
     not this card. The label's own max-width does the insetting, and
     the descendants below are free to measure the card in cqw. */
  color: var(--white);
  text-align: center;
}

.hero-card-stat strong {
  font-family: var(--font-display);
  font-size: 17cqw;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
}

/* "Deals and Claims Completed" is short enough to fit the stat card on
   one line, which reads as a cramped single row on phones. There is no
   whitespace between "Claims" and this span, so there is no break
   opportunity here, and the generated non-breaking space is the same
   glyph the markup used to carry — desktop wrapping is unchanged. The
   mobile rule below swaps it for a forced break. */
.stat-line-break::before {
  content: "\00a0";
}

/* Same forced break for the wide stat, but this one replaces an ordinary
   space, so the generated space has to stay breakable on desktop —
   pre-wrap preserves it while still allowing a wrap there. */
.stat-line-break-soft::before {
  content: " ";
  white-space: pre-wrap;
}

.hero-card-stat span {
  margin-top: 0.55em;
  max-width: 84%;
  font-size: 6.4cqw;
  font-weight: 400;
  line-height: 1.28;
  letter-spacing: -0.01em;
}

.hero-card-wide {
  width: clamp(12.2rem, 14.1vw, 13.5rem);
  border-radius: 1.8rem;
  background: #2e2e2e;
}

/* ------------------------------------------------------------------
   Responsive homes for the hero-card cluster
   ------------------------------------------------------------------
   The scroll-driven start/end/converge choreography in script.js is
   untouched at every width. What changes per breakpoint below is:
     1) --home-x/--home-y, a bias script.js folds into the *converged
        resting position only* (not the entrance path - see
        updateHero() in script.js), so the cards settle beside the
        headline instead of on top of it, and
     2) the cards' own size, so their footprint fits the available
        margin.
   This mirrors how large sites (e.g. jeton.com's hero) handle the same
   problem: the entrance animation logic is one piece of code, and only
   the art-directed resting spot is redefined per breakpoint in CSS. */
@media (max-width: 1279px) {
  /* 1280-1535px reverts to the untouched original desktop card
     size/position (same as 1536px+) - this tier only kicks in below a
     common laptop/external-monitor width. */
  .hero-card.card-photo-smile {
    width: clamp(7.5rem, 11vw, 11.75rem);
    --home-x: -13;
    --home-y: -11;
  }

  .hero-card.card-photo-street {
    width: clamp(6.8rem, 10vw, 10.6rem);
    --home-x: 14;
    --home-y: -12;
  }

  .hero-card.card-photo-laptop {
    width: clamp(7.1rem, 10.3vw, 11.2rem);
    --home-x: -3;
    --home-y: 14;
  }

  .hero-card-stat {
    width: clamp(7.6rem, 11vw, 12.2rem);
    --home-x: -14;
    --home-y: 10;
  }

  .hero-card-wide {
    width: clamp(7.6rem, 11vw, 12.2rem);
    --home-x: 13;
    --home-y: 3;
  }
}

@media (max-width: 900px) {
  .hero-card.card-photo-smile {
    width: clamp(5.4rem, 15vw, 7.4rem);
    --home-x: -20;
    --home-y: -16;
  }

  .hero-card.card-photo-street {
    width: clamp(4.9rem, 13.5vw, 6.7rem);
    --home-x: 21;
    --home-y: -18;
  }

  .hero-card.card-photo-laptop {
    width: clamp(5.1rem, 14vw, 7rem);
    --home-x: -4;
    --home-y: 21;
  }

  .hero-card-stat {
    width: clamp(5.5rem, 15vw, 7.6rem);
    --home-x: -21;
    --home-y: 15;
  }

  .hero-card-wide {
    width: clamp(5.5rem, 15vw, 7.6rem);
    --home-x: 20;
    --home-y: 5;
  }
}

@media (max-width: 560px) {
  /* At phone widths the headline wraps onto 3-4 lines and fills nearly
     the whole viewport, so the cards are pushed toward the edges - only
     a sliver peeks in during parts of the entrance, the same "edge
     peek" treatment jeton.com uses at its own smallest breakpoint. */
  .hero-card.card-photo-smile {
    width: 5.2rem;
    --home-x: -16;
    --home-y: -14;
  }

  .hero-card.card-photo-street {
    width: 4.7rem;
    --home-x: 17;
    --home-y: -15;
  }

  .hero-card.card-photo-laptop {
    width: 4.9rem;
    --home-x: -2;
    --home-y: 18;
  }

  .hero-card-stat {
    width: 5.3rem;
    --home-x: -17;
    --home-y: 13;
  }

  .hero-card-wide {
    width: 5.3rem;
    --home-x: 16;
    --home-y: 4;
  }
}

.hero-button {
  --hover-x: 50%;
  --hover-y: 50%;
  position: absolute;
  left: 50%;
  top: clamp(672px, 83.6vh, 721px);
  min-width: 0;
  min-height: 50px;
  width: calc(419px - 369px * var(--hero-cta-progress));
  height: 50px;
  padding: 0;
  transform: translateX(-50%);
  transform-origin: center;
  border-radius: 999px;
  box-shadow: 0 18px 34px rgba(255, 0, 153, 0.22);
  overflow: hidden;
  z-index: 5;
  opacity: calc(1 - var(--hero-cta-travel-fade));
  background-size: 180% 180%;
  background-position: 0% 50%;
  transition:
    box-shadow var(--motion-base) ease,
    filter var(--motion-base) ease,
    background-color var(--motion-fast) ease,
    background-position var(--motion-slow) ease;
}

.hero-button::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      160px circle at var(--hover-x) var(--hover-y),
      rgba(255, 255, 255, 0.32) 0%,
      rgba(255, 255, 255, 0.12) 24%,
      rgba(255, 255, 255, 0) 68%
    );
  opacity: 0;
  transition: opacity var(--motion-fast) ease;
  pointer-events: none;
}

.hero-button::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  border: 1px solid rgba(255, 255, 255, 0.12);
  opacity: 0;
  transform: scale(0.97);
  transition:
    opacity var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard);
  pointer-events: none;
}

.hero-button-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(0.8rem * (1 - var(--hero-cta-progress)));
  width: 100%;
  height: 100%;
  font-family: var(--font-nav);
  font-size: 20px;
  font-weight: 310;
  line-height: 21px;
  color: #fff;
  opacity: calc(1 - var(--hero-cta-progress) * 2.4);
  transition:
    gap var(--motion-fast) ease,
    opacity var(--motion-fast) ease,
    letter-spacing var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard);
}

.hero-button-text {
  max-width: calc(8.6rem * (1 - var(--hero-cta-progress)));
  overflow: hidden;
  white-space: nowrap;
  opacity: 1;
  transform: scale(calc(1 - var(--hero-cta-progress) * 0.1));
  transform-origin: center;
  transition:
    max-width var(--motion-fast) ease,
    opacity var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard),
    text-shadow var(--motion-base) ease,
    letter-spacing var(--motion-fast) ease;
}

.hero-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  opacity: 1;
  transform-origin: center;
  transform:
    translateY(1px)
    rotate(0deg)
    scale(calc(1 - var(--hero-cta-progress) * 0.18));
  transition:
    opacity var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard);
}

.hero-button:hover,
.hero-button:focus-visible {
  transform: translateX(-50%);
  box-shadow:
    0 26px 46px rgba(255, 0, 153, 0.24),
    0 0 0 1px rgba(255, 255, 255, 0.08) inset;
  filter: saturate(1.06) brightness(1.03);
  background-position: 100% 50%;
}

.hero-button:hover::before,
.hero-button:focus-visible::before {
  opacity: 1;
}

.hero-button:hover::after,
.hero-button:focus-visible::after {
  opacity: 1;
  transform: scale(1);
}

.hero-button:hover .hero-button-label,
.hero-button:focus-visible .hero-button-label {
  letter-spacing: 0.01em;
}

.hero-button:hover .hero-button-text,
.hero-button:focus-visible .hero-button-text {
  text-shadow: 0 8px 18px rgba(255, 255, 255, 0.16);
  letter-spacing: 0.01em;
}

.hero-button:hover .hero-button-icon,
.hero-button:focus-visible .hero-button-icon {
  transform:
    translateY(1px)
    translateX(4px)
    rotate(45deg)
    scale(calc(1.05 - var(--hero-cta-progress) * 0.18));
}

.travelling-dot {
  position: fixed;
  left: 0;
  top: 0;
  width: var(--travel-dot-width, 50px);
  height: var(--travel-dot-height, 50px);
  border-radius: var(--travel-dot-radius, 999px);
  /* Solid pink as a dot; eases to a marker tint while it's acting as
     a highlight, so the words stay readable through it. */
  background: color-mix(
    in srgb,
    var(--pink) calc(100% - var(--travel-dot-highlight, 0) * 87%),
    #ffeaf5
  );
  box-shadow: none;
  /* Multiply so the bar behaves like a marker pen: over the light
     page it reads as solid pink, and over the dark copy the words
     stay legible straight through it. */
  mix-blend-mode: multiply;
  /* Driven entirely by transform rather than left/top — those trigger
     layout on every frame, transform stays on the compositor. */
  transform:
    translate3d(var(--travel-dot-x, 0px), var(--travel-dot-y, 0px), 0)
    translate(-50%, -50%)
    rotate(var(--travel-dot-rotate, 0deg))
    scale(var(--travel-dot-scale-x, 1), var(--travel-dot-scale-y, 1));
  z-index: 6;
  pointer-events: none;
  will-change: transform, width, height, opacity;
  backface-visibility: hidden;
}

.travelling-dot.is-hidden {
  opacity: 0;
  transform:
    translate3d(var(--travel-dot-x, 0px), var(--travel-dot-y, 0px), 0)
    translate(-50%, -50%)
    scale(0.3);
}

.why-section {
  padding: 0 0 5.8rem;
}

.why-shell {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  min-height: 1240px;
  display: block;
}

.why-panel {
  position: relative;
  width: 100%;
  min-height: 1240px;
  padding: 0;
  border-radius: 58px;
  background: #2e2e2e;
  color: var(--white);
  box-shadow: 0 24px 56px rgba(46, 46, 46, 0.14);
  overflow: hidden;
}

.section-intro {
  max-width: 44rem;
  display: grid;
  gap: 1rem;
}

.section-intro h2 {
  font-size: clamp(2.7rem, 5vw, 4.8rem);
  line-height: 0.95;
  letter-spacing: -0.06em;
}

.section-intro p:last-child {
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  letter-spacing: var(--body-copy-letter-spacing);
  line-height: var(--body-copy-line-height);
  color: rgba(46, 46, 46, 0.68);
}

.section-dark .section-intro p:last-child {
  color: rgba(244, 244, 244, 0.74);
}

.why-pill {
  position: absolute;
  left: 50%;
  top: 143px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 32px;
  padding: 0 1.2rem;
  border-radius: 36px;
  border: 0.5px solid rgba(255, 255, 255, 0.92);
  color: #fff;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 310;
  line-height: 18px;
  z-index: 8;
}

.why-copy {
  position: absolute;
  left: 50%;
  top: 255px;
  width: min(1036px, calc(100% - 404px));
  transform: translateX(-50%);
  z-index: 8;
}

.why-copy-block {
  width: 100%;
  color: #fff;
  font-family: var(--font-body);
  font-size: 32px;
  font-weight: 320;
  line-height: 43px;
  letter-spacing: 0;
  text-align: center;
  text-wrap: balance;
}

.why-copy-block span {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}

.why-copy-strong {
  color: rgba(255, 255, 255, 0.14);
}

.why-copy-muted {
  color: rgba(255, 255, 255, 0.08);
}

.why-word {
  position: relative;
  display: inline-block;
  z-index: 8;
  color: inherit;
  filter: blur(0.28px);
  transition:
    color var(--motion-base) ease,
    filter var(--motion-base) ease,
    transform 420ms cubic-bezier(0.18, 0.95, 0.24, 1.24);
}

.why-word.is-revealed {
  color: rgba(255, 255, 255, 1);
  filter: blur(0);
}

.why-word.is-active {
  transform: none;
}

.why-button {
  position: absolute;
  left: 50%;
  top: 1054px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 229px;
  min-width: 229px;
  height: 50px;
  min-height: 50px;
  margin-top: 0;
  padding: 0;
  gap: 0.8rem;
  font-family: var(--font-body);
  font-size: 20px;
  font-weight: 310;
  line-height: 21px;
  color: #fff;
  z-index: 8;
  background: #ff0099;
  box-shadow: none;
  transition:
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease,
    filter var(--motion-base) ease;
}

.why-button-text,
.why-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  color: #fff;
  opacity: 1;
  transition: opacity 180ms ease;
}

.why-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  transform: rotate(-45deg);
  transition:
    transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 220ms ease;
}

.why-button:hover,
.why-button:focus-visible {
  transform: translateX(-50%) translateY(-2px) scale(1.02);
  box-shadow: 0 18px 34px rgba(255, 0, 153, 0.18);
  filter: saturate(1.02);
}

.why-button:hover .why-button-icon,
.why-button:focus-visible .why-button-icon {
  transform: translateX(4px) rotate(0deg);
}

.services-section {
  min-height: 760vh;
  position: relative;
  padding-bottom: 0;
}

.services-stage {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 0;
}

.services-header {
  position: absolute;
  top: calc(var(--nav-height) + 1.45rem);
  left: 50%;
  width: var(--shell);
  transform:
    translateX(-50%)
    translateY(calc(var(--services-intro-progress) * -42px));
  margin: 0;
  display: grid;
  justify-items: center;
  gap: 1rem;
  text-align: center;
  z-index: 5;
  opacity: calc(1 - var(--services-intro-progress));
  pointer-events: none;
}

.services-header .section-intro {
  margin: 0 auto;
  max-width: 56rem;
}

.services-header .section-intro h2 {
  max-width: 13ch;
  margin-inline: auto;
}

.services-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 32px;
  padding: 0 1.2rem;
  margin-inline: auto;
  border-radius: 36px;
  border: 0.5px solid rgba(46, 46, 46, 0.88);
  color: #2e2e2e;
  font-size: 16px;
  font-weight: 310;
  line-height: 18px;
}

.services-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.services-summary span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.3rem;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  border: 1px solid rgba(46, 46, 46, 0.08);
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(18px);
  color: rgba(46, 46, 46, 0.72);
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.services-stack {
  position: relative;
  width: var(--boxed-guide-width);
  min-height: min(78vh, 860px);
  margin: 0 auto;
}

.service-card {
  position: absolute;
  inset: 0;
  z-index: var(--service-order, 1);
  display: grid;
  grid-template-columns: minmax(20rem, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(1.2rem, 2vw, 2.1rem);
  align-items: stretch;
  padding: clamp(1.1rem, 1.5vw, 1.35rem);
  border-radius: clamp(2rem, 3vw, 2.8rem);
  border: 1px solid rgba(var(--service-accent-rgb, 46, 46, 46), 0.14);
  background: linear-gradient(135deg, var(--service-tint, #fff7fc), rgba(255, 255, 255, 0.98) 58%);
  box-shadow:
    0 28px 60px rgba(46, 46, 46, 0.1),
    0 16px 36px rgba(var(--service-accent-rgb, 46, 46, 46), 0.08);
  transform:
    translateX(calc(var(--service-shift-x, 0) * 1px))
    translateY(calc(var(--service-translate, 16) * 1px))
    rotate(calc(var(--service-rotate, 0) * 1deg))
    scale(var(--service-scale, 1));
  opacity: var(--service-opacity, 0);
  will-change: transform, opacity;
  transform-origin: var(--service-origin-x, 50%) 100%;
  overflow: hidden;
}

.service-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 0.38rem;
  background: linear-gradient(90deg, var(--service-accent), rgba(var(--service-accent-rgb), 0));
}

.service-card::after {
  content: "";
  position: absolute;
  width: 22rem;
  height: 22rem;
  right: -9rem;
  top: -10rem;
  border-radius: 50%;
  background: rgba(var(--service-accent-rgb, 46, 46, 46), 0.1);
  filter: blur(8px);
  pointer-events: none;
}

.service-visual,
.service-card-body {
  position: relative;
  z-index: 1;
}

.service-visual-panel {
  position: relative;
  min-height: clamp(25rem, 56vh, 35rem);
  height: 100%;
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 1rem;
  padding: clamp(1.5rem, 2vw, 1.9rem);
  border-radius: clamp(1.7rem, 2.5vw, 2.4rem);
  overflow: hidden;
  background:
    radial-gradient(circle at 18% 18%, rgba(255, 255, 255, 0.34), transparent 26%),
    radial-gradient(circle at 84% 22%, rgba(255, 255, 255, 0.18), transparent 28%),
    linear-gradient(155deg, var(--service-accent), var(--service-accent-deep));
  color: var(--white);
}

.service-visual-panel::before {
  content: "";
  position: absolute;
  right: -18%;
  top: 12%;
  width: 15rem;
  height: 15rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  filter: blur(8px);
}

.service-visual-panel::after {
  content: "";
  position: absolute;
  left: -12%;
  bottom: -18%;
  width: 85%;
  height: 48%;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.18);
}

.service-visual-top {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.service-index {
  font-family: var(--font-display);
  font-size: clamp(4rem, 7vw, 6.9rem);
  line-height: 0.78;
  letter-spacing: -0.08em;
  color: rgba(255, 255, 255, 0.28);
}

.service-visual-stage {
  margin-top: 0.35rem;
  padding: 0.5rem 0.85rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.service-visual-rail {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 0.8rem;
  align-self: end;
}

.service-visual-rail span {
  display: block;
  height: clamp(0.9rem, 1.6vw, 1.15rem);
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.82));
}

.service-visual-rail span:nth-child(1) {
  width: 54%;
}

.service-visual-rail span:nth-child(2) {
  width: 81%;
}

.service-visual-rail span:nth-child(3) {
  width: 68%;
}

.service-visual-rail span:nth-child(4) {
  width: 92%;
}

.service-visual-tags {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-self: end;
}

.service-visual-tags span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.15rem;
  padding: 0.45rem 0.75rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-size: 0.84rem;
  font-weight: 700;
}

.service-visual-note {
  position: relative;
  z-index: 1;
  padding: 1rem 1.05rem;
  border-radius: 1.4rem;
  background: rgba(0, 0, 0, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.service-visual-note strong {
  display: block;
  max-width: 15ch;
  font-size: 1.2rem;
  line-height: 1;
  letter-spacing: -0.04em;
}

.service-visual-note p {
  margin-top: 0.55rem;
  max-width: 20rem;
  color: rgba(255, 255, 255, 0.78);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  letter-spacing: var(--body-copy-letter-spacing);
}

.service-card-body {
  display: grid;
  align-content: center;
  gap: 1rem;
  padding: clamp(0.75rem, 1vw, 1.15rem) clamp(0.2rem, 0.6vw, 0.5rem) clamp(0.9rem, 1.4vw, 1.35rem);
  max-width: 42rem;
}

.service-copy-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.service-pill {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  background: rgba(var(--service-accent-rgb, 46, 46, 46), 0.11);
  color: rgba(46, 46, 46, 0.8);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.service-count {
  color: rgba(var(--service-accent-rgb, 46, 46, 46), 0.8);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.service-card-body h3 {
  max-width: 12ch;
  font-size: clamp(2.45rem, 5vw, 4.5rem);
  line-height: 0.92;
  letter-spacing: -0.06em;
  text-wrap: balance;
}

.service-card-body > p {
  color: rgba(46, 46, 46, 0.72);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  letter-spacing: var(--body-copy-letter-spacing);
  max-width: 36rem;
}

.case-section {
  padding: 8.5rem 0 9rem;
}

.case-shell {
  display: grid;
  gap: 2.4rem;
}

.case-intro {
  max-width: 48rem;
}

.case-masonry {
  column-count: 3;
  column-gap: 1.35rem;
}

.case-card {
  break-inside: avoid;
  margin-bottom: 1.35rem;
  padding: 1.55rem;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.76);
  border: 1px solid rgba(46, 46, 46, 0.08);
  box-shadow: var(--shadow-soft);
  backdrop-filter: blur(18px);
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  filter: blur(4px);
  transition:
    opacity 560ms var(--ease-soft),
    transform 560ms var(--ease-soft),
    filter 420ms ease,
    box-shadow var(--motion-base) ease,
    border-color var(--motion-fast) ease;
  transition-delay: var(--card-reveal-delay, 0ms);
  will-change: transform, opacity, filter;
}

.case-card.is-revealed {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
  transition:
    opacity 560ms var(--ease-soft),
    transform 560ms var(--ease-soft),
    filter 420ms ease,
    box-shadow var(--motion-base) ease,
    border-color var(--motion-fast) ease;
  transition-delay: 0ms;
}

.case-card:hover,
.case-card:focus-within {
  transform: translateY(-6px);
  box-shadow:
    0 26px 54px rgba(46, 46, 46, 0.12),
    0 14px 30px rgba(46, 46, 46, 0.06);
  border-color: rgba(46, 46, 46, 0.14);
}

.case-card-dark {
  background:
    radial-gradient(circle at top right, rgba(255, 0, 153, 0.18), transparent 44%),
    #2c2c2c;
  color: var(--white);
}

.case-card-highlight {
  background:
    linear-gradient(135deg, rgba(255, 0, 153, 0.1), rgba(255, 255, 255, 0.9)),
    rgba(255, 255, 255, 0.9);
}

.case-card-stat {
  display: grid;
  gap: 0.55rem;
  background:
    radial-gradient(circle at top left, rgba(255, 0, 153, 0.2), transparent 50%),
    rgba(46, 46, 46, 0.96);
  color: var(--white);
}

.case-card-stat strong {
  font-size: clamp(3rem, 6vw, 4.6rem);
  line-height: 0.88;
  letter-spacing: -0.08em;
}

.case-card h3 {
  margin-bottom: 0.75rem;
  font-size: 2rem;
  line-height: 0.96;
  letter-spacing: -0.05em;
}

.case-label {
  margin-bottom: 0.8rem;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 700;
  color: rgba(46, 46, 46, 0.5);
}

.case-card-dark .case-label,
.case-card-stat .case-label {
  color: rgba(244, 244, 244, 0.6);
}

.case-card p,
.case-card li,
.channel-list strong,
.channel-list span {
  color: inherit;
}

.case-card p:not(.case-label),
.case-card li {
  color: rgba(46, 46, 46, 0.74);
}

.case-card-dark p:not(.case-label),
.case-card-stat span {
  color: rgba(244, 244, 244, 0.78);
}

.case-list {
  display: grid;
  gap: 0.6rem;
  margin: 1rem 0;
}

.case-list li,
.channel-list li {
  padding-left: 1rem;
  position: relative;
}

.case-list li::before,
.channel-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7rem;
  width: 0.38rem;
  height: 0.38rem;
  border-radius: 50%;
  background: var(--pink);
}

.channel-list {
  display: grid;
  gap: 0.95rem;
}

.channel-list li {
  display: grid;
  gap: 0.15rem;
}

.channel-list span {
  font-size: 0.84rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(46, 46, 46, 0.46);
}

.channel-list strong {
  font-size: 1.15rem;
  letter-spacing: -0.02em;
}

.products-section {
  position: relative;
  padding: 5.35rem 0 3.1rem;
  background: #f6f6f8;
}

.products-shell {
  display: grid;
  gap: 1.75rem;
}

.products-intro {
  display: grid;
  justify-items: center;
  gap: 1.15rem;
  text-align: center;
}

.products-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 32px;
  padding: 0 1.2rem;
  border-radius: 36px;
  border: 0.5px solid rgba(46, 46, 46, 0.88);
  color: #2e2e2e;
  font-size: 16px;
  font-weight: 310;
  line-height: 18px;
}

.products-heading {
  max-width: 429px;
  color: #2e2e2e;
  font-size: clamp(2.5rem, 4vw, 55px);
  font-weight: 800;
  line-height: 59px;
  letter-spacing: -0.04em;
}

.products-card {
  width: var(--boxed-guide-width);
  min-height: auto;
  margin: 0 auto;
  padding: 28px 28px 26px;
  border-radius: 32px;
  background: #fff;
  box-shadow: 0 26px 54px rgba(46, 46, 46, 0.08);
  display: grid;
  gap: 1.35rem;
  transition:
    transform var(--motion-slow) var(--ease-soft),
    box-shadow var(--motion-slow) ease,
    border-color var(--motion-fast) ease;
}

.products-tabs {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  align-items: center;
  gap: 0.95rem;
  padding-inline: 0.1rem;
}

.product-tab {
  width: 100%;
  min-height: 62px;
  border-radius: 16px;
  border: 0;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  transition:
    background-color var(--motion-fast) ease,
    box-shadow var(--motion-base) ease,
    transform var(--motion-base) var(--ease-standard);
}

.product-tab-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(184px, calc(100% - 1rem));
  height: 30px;
}

.product-tab img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  opacity: 1 !important;
  filter: brightness(0) saturate(100%) invert(78%) !important;
  transition:
    filter var(--motion-base) ease,
    transform var(--motion-base) var(--ease-standard);
}

.product-tab:hover,
.product-tab:focus-visible {
  transform: none;
}

.product-tab:not(.is-active):hover img,
.product-tab:not(.is-active):focus-visible img {
  opacity: 1 !important;
  filter: brightness(0) saturate(100%) invert(70%) !important;
}

.product-tab.is-active {
  background: var(--pink);
  box-shadow: 0 18px 32px rgba(255, 0, 153, 0.18);
  transform: none;
}

.product-tab.is-active img {
  opacity: 1 !important;
  filter: brightness(0) saturate(100%) invert(100%) !important;
}

.product-tab img.product-tab-logo-reduced {
  height: 22px;
  transform: translateY(-5px);
}

.products-frame {
  display: grid;
  grid-template-columns: minmax(24rem, 0.98fr) minmax(30rem, 1.12fr);
  gap: 1.8rem;
  align-items: center;
  min-height: 0;
}

.product-panel {
  position: relative;
  overflow: hidden;
  padding: 1rem 1.4rem 0.65rem;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  background: transparent;
  min-height: 0;
  transition:
    opacity var(--motion-base) var(--ease-soft),
    transform var(--motion-base) var(--ease-soft),
    filter var(--motion-base) ease;
}

.product-panel.is-switching,
.product-panel.is-entering {
  opacity: 0;
  transform: translate3d(0, 18px, 0) scale(0.985);
  filter: blur(10px);
}

.product-label {
  margin-bottom: 1rem;
  padding: 0.1rem 0.95rem;
  border-radius: 10px;
  background: #ffeffa;
  color: rgba(46, 46, 46, 0.72);
  font-size: 14px;
  font-weight: 310;
  line-height: 22.5px;
}

.product-title {
  max-width: 405px;
  color: #000;
  font-size: clamp(2rem, 2.6vw, 32px);
  font-weight: 800;
  line-height: 42px;
  letter-spacing: -0.02em;
}

.product-copy {
  max-width: 471px;
  margin-top: 1.1rem;
  color: rgba(0, 0, 0, 0.74);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  letter-spacing: var(--body-copy-letter-spacing);
}

.product-link {
  margin-top: 1.55rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-width: 362px;
  min-height: 53px;
  padding: 0.8rem 1.8rem;
  border-radius: 30.5px;
  border: 1px solid #ff0099;
  color: var(--pink);
  font-size: 20px;
  font-weight: 310;
  line-height: 21px;
  text-decoration: none;
  transition:
    border-color var(--motion-fast) ease,
    background-color var(--motion-fast) ease,
    color var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease;
}

.product-link:hover,
.product-link:focus-visible {
  border-color: #ff0099;
  background: rgba(255, 0, 153, 0.06);
  transform: translateY(-3px);
  box-shadow: 0 16px 32px rgba(255, 0, 153, 0.08);
}

.product-link-label {
  white-space: nowrap;
}

.product-link-arrow {
  display: inline-flex;
  transition: transform var(--motion-base) var(--ease-standard);
}

.product-link:hover .product-link-arrow,
.product-link:focus-visible .product-link-arrow {
  transform: translateX(2px) rotate(44deg);
}

.product-showcase {
  position: relative;
  min-height: 35.5rem;
  overflow: visible;
  background: transparent;
  isolation: isolate;
}

.product-showcase-bloom {
  position: absolute;
  top: -1.25rem;
  right: -0.4rem;
  width: min(28rem, 88%);
  aspect-ratio: 1 / 1;
  border-top-right-radius: 32px;
  background:
    radial-gradient(circle at 27% 26%, rgba(255, 255, 255, 0.96) 0, rgba(255, 255, 255, 0.72) 31%, rgba(255, 255, 255, 0) 60%),
    linear-gradient(135deg, rgba(247, 220, 238, 0.88), rgba(255, 255, 255, 0.08) 72%);
  opacity: 0.95;
  pointer-events: none;
  z-index: 0;
}

.product-showcase-pattern {
  position: absolute;
  top: -0.45rem;
  right: 0.35rem;
  width: min(28.5rem, 92%);
  height: auto;
  opacity: 0.16;
  pointer-events: none;
  z-index: 1;
}

.product-showcase-stage {
  position: relative;
  width: min(100%, 31.75rem);
  min-height: 35rem;
  aspect-ratio: 569 / 640;
  margin-left: auto;
  z-index: 2;
}

.product-stat-card {
  position: absolute;
  margin: 0;
  transform-origin: center;
}

.product-stat-card img {
  display: block;
  width: 100%;
  height: auto;
}

.product-stat-card-top {
  top: 4.22%;
  left: 0;
  width: 40.42%;
  z-index: 1;
  animation: product-float-soft 9.6s var(--ease-soft) infinite;
}

.product-stat-card-main {
  top: 20.31%;
  right: 0;
  width: 76.27%;
  z-index: 2;
  animation: product-float-main 11.8s var(--ease-soft) infinite;
  animation-delay: -2.4s;
}

.product-stat-card-bottom {
  top: 55.47%;
  left: 11.78%;
  width: 40.25%;
  z-index: 3;
  animation: product-float-soft 10.4s var(--ease-soft) infinite;
  animation-delay: -4.1s;
}

.cta-section {
  padding: 0.85rem 0 0;
  position: relative;
  padding-bottom: 5rem;
  margin-bottom: -88px;
  background: #f6f6f8;
  border-top-left-radius: 42px;
  border-top-right-radius: 42px;
  border-bottom-left-radius: 42px;
  border-bottom-right-radius: 42px;
  box-shadow: none;
  z-index: 4;
  overflow: hidden;
}

.cta-shell {
  min-height: 72rem;
  display: grid;
  align-content: start;
  text-align: center;
  overflow: visible;
  gap: 100px;
  padding-bottom: 4.5rem;
}

.cta-copy {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: none;
  display: grid;
  justify-items: center;
  gap: 1.8rem;
  margin: 3.8rem auto 0;
  transform: translateX(-106px);
}

.cta-type-heading {
  width: min(860px, calc(100vw - 2rem));
  max-width: none;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #000;
  text-align: center;
  font-size: 73px;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 73px;
  letter-spacing: -0.02em;
}

.cta-type-line {
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  gap: 0;
  white-space: nowrap;
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}

.cta-typeword,
.cta-type-dot,
.cta-cursor {
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}

/* Same no-whitespace-in-markup trick as .cta-typeword below: the space
   before these words comes from this margin, so it survives
   .cta-type-line being a flex row on desktop (which trims whitespace in
   an anonymous item) and an inline flow on mobile. */
.cta-type-thats {
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  margin-left: 0.24em;
}

.cta-type-build {
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  margin-left: 0.24em;
}

.cta-typeword {
  color: #000;
  /* The gap before the animated word comes from here and nowhere
     else. The markup deliberately has no whitespace before this span:
     .cta-type-line is a flex row on desktop, where trailing whitespace
     in an anonymous item is trimmed, but a block below 860px, where it
     is not — so a markup space plus this margin gave a single gap on
     desktop and a double one on mobile. */
  margin-left: 0.24em;
}

.cta-cursor {
  display: inline-block;
  width: 0.08em;
  height: 0.88em;
  margin-left: 0.06em;
  margin-right: 0.03em;
  background: currentColor;
  vertical-align: -0.08em;
  animation: blink-cursor 0.95s steps(1, end) infinite;
}

.cta-type-dot {
  color: var(--pink);
}

.cta-hero-button {
  --hero-cta-progress: 0;
  --hero-cta-travel-fade: 0;
  position: static;
  top: auto;
  left: auto;
  transform: none;
  width: min(419px, calc(100vw - 2rem));
  height: 50px;
  min-height: 50px;
  margin-inline: auto;
}

.cta-hero-button .hero-button-label {
  gap: 0.8rem;
  opacity: 1;
  color: #fff;
  font-size: 19px;
  line-height: 20px;
}

.cta-hero-button .hero-button-text {
  max-width: none;
  opacity: 1;
  transform: none;
  text-shadow: none;
}

.cta-hero-button .hero-button-icon {
  opacity: 1;
  transform: translateY(1px) rotate(0deg) scale(1);
}

.cta-hero-button:hover,
.cta-hero-button:focus-visible {
  transform: none;
  box-shadow: 0 20px 38px rgba(255, 0, 153, 0.18);
  filter: none;
  background-position: 0% 50%;
}

.cta-hero-button:hover::before,
.cta-hero-button:focus-visible::before,
.cta-hero-button:hover::after,
.cta-hero-button:focus-visible::after {
  opacity: 0;
  transform: scale(0.97);
}

.cta-hero-button:hover .hero-button-label,
.cta-hero-button:focus-visible .hero-button-label,
.cta-hero-button:hover .hero-button-text,
.cta-hero-button:focus-visible .hero-button-text {
  letter-spacing: 0;
  text-shadow: none;
}

.cta-hero-button:hover .hero-button-icon,
.cta-hero-button:focus-visible .hero-button-icon {
  transform: translateY(1px) translateX(4px) rotate(45deg) scale(1.05);
}

.cta-art {
  position: relative;
  width: min(100vw, 1440px);
  height: clamp(30rem, 50vw, 44rem);
  margin: 0 auto;
  isolation: isolate;
}

.cta-ground-shadow {
  position: absolute;
  left: 50%;
  bottom: 6%;
  width: min(90%, 76rem);
  height: clamp(2.4rem, 4vw, 3.5rem);
  transform: translateX(-50%);
  border-radius: 999px;
  background: radial-gradient(circle, rgba(46, 46, 46, 0.18) 0%, rgba(46, 46, 46, 0.08) 42%, transparent 76%);
  filter: blur(24px);
  opacity: 0.34;
}

/* Keeps <picture> out of the layout so the <img> inside it stays the
   grid item .cta-scene centres. */
.cta-scene picture {
  display: contents;
}

.cta-scene {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  will-change: transform;
  animation: float-scene 8.4s ease-in-out infinite;
}

.cta-scene img {
  display: block;
  width: min(112%, 1520px);
  max-width: none;
  height: auto;
  transform: translateX(-6.2%);
  filter: drop-shadow(0 28px 34px rgba(46, 46, 46, 0.18));
}

.site-footer {
  position: relative;
  padding: 2.3rem 0 0;
  min-height: 1122px;
  background: linear-gradient(180deg, #343333 0%, #111111 100%);
  border-top-left-radius: 58px;
  border-top-right-radius: 58px;
  overflow: visible;
  z-index: 1;
}

.footer-shell {
  display: grid;
  grid-template-columns: 1fr 0.55fr minmax(34rem, 40rem);
  gap: 0;
  align-items: start;
  padding-top: 250px;
  padding-bottom: 0;
}

.footer-mark {
  grid-column: 1;
  justify-self: start;
  display: inline-flex;
  width: 39px;
  margin: 0;
}

.footer-mark img {
  display: block;
  width: 100%;
  height: auto;
}

.footer-links {
  grid-column: 3;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.1rem 3.7rem;
  width: 100%;
  justify-self: end;
}

.footer-column {
  display: grid;
  align-content: start;
  gap: 0.95rem;
}

.footer-title {
  margin-bottom: 0.5rem;
  color: rgba(244, 244, 244, 1);
  font-size: 1rem;
  font-weight: 330;
  line-height: 1.40625rem;
}

.footer-link-row {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.footer-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 1rem;
  padding: 0.08rem 0.38rem;
  border-radius: 999px;
  background: var(--pink);
  color: #fff;
  font-size: 0.55rem;
  line-height: 1;
  white-space: nowrap;
}

.footer-links a {
  color: rgba(244, 244, 244, 0.7);
  font-size: 0.875rem;
  font-weight: 315;
  line-height: 1.25rem;
  transition:
    color var(--motion-fast) ease,
    opacity var(--motion-fast) ease,
    transform var(--motion-base) var(--ease-standard);
}

.footer-links a:hover,
.footer-links a:focus-visible {
  color: rgba(255, 255, 255, 1);
  transform: translateX(6px);
}

.footer-mark,
.footer-next-page,
.footer-chip {
  transition:
    transform var(--motion-base) var(--ease-standard),
    filter var(--motion-base) ease,
    opacity var(--motion-fast) ease,
    box-shadow var(--motion-base) ease;
}

.footer-mark:hover,
.footer-mark:focus-visible {
  transform: translateY(-2px);
  filter: brightness(1.08);
}

.footer-chip:hover,
.footer-chip:focus-visible {
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 10px 16px rgba(255, 0, 153, 0.24);
}

.footer-wordmark-shell {
  position: relative;
  z-index: 1;
  width: min(1180px, calc(100vw - 260px));
  margin-top: 72px;
  margin-left: auto;
  margin-right: auto;
  padding-bottom: 104px;
}

.footer-wordmark-shell::after {
  content: "";
  position: absolute;
  right: 12.1%;
  bottom: 1.35rem;
  width: clamp(4.8rem, 7.8vw, 6.9rem);
  height: clamp(1.8rem, 3.1vw, 2.9rem);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  filter: blur(0.6px);
  opacity: 0.2;
}

.footer-wordmark {
  display: block;
  width: 100%;
  margin-left: 0;
}

.footer-wordmark img {
  display: block;
  width: 100%;
  height: auto;
}

.footer-bottom {
  /* Pinned to the foot of the screen while the footer scrolls past, so the
     progress bar is on screen for the whole of the footer and fills as the
     visitor scrolls through it. It settles at the end of the page. */
  position: sticky;
  bottom: 0;
  z-index: 3;
  margin-top: -136px;
  margin-bottom: 0;
  background: rgba(32, 32, 32, 0.71);
  backdrop-filter: blur(16px);
}

.footer-bottom-shell {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  justify-content: space-between;
  gap: 1.15rem;
  min-height: 76px;
}

.footer-bottom-copy,
.footer-bottom-label {
  color: rgba(244, 244, 244, 0.96);
  font-size: 16px;
  line-height: 34px;
}

.footer-bottom-copy {
  font-family: var(--font-display);
  font-weight: 800;
}

.footer-next-page {
  display: inline-grid;
  grid-template-columns: auto auto;
  align-items: center;
  gap: 0.95rem;
  justify-self: end;
  color: inherit;
  text-decoration: none;
}

/* Only the page name reacts to hover; the bar stays put */
.footer-next-page:hover,
.footer-next-page:focus-visible {
  transform: none;
}

.footer-bottom-label {
  transition:
    transform var(--motion-base) var(--ease-standard),
    color var(--motion-fast) ease;
}

.footer-bottom-label:hover,
.footer-next-page:focus-visible .footer-bottom-label {
  color: var(--pink);
  transform: translateX(-6px);
}

/* The bar never moves or changes on hover */
.footer-next-page:hover .footer-progress,
.footer-next-page:focus-visible .footer-progress {
  transform: none;
  box-shadow: none;
}

.footer-bottom-label {
  justify-self: end;
  font-family: var(--font-display);
  font-weight: 400;
  color: rgba(244, 244, 244, 0.84);
}

.footer-progress {
  position: relative;
  width: 228px;
  height: 7px;
  justify-self: end;
  border-radius: 999px;
  background: rgba(217, 217, 217, 0.92);
  overflow: hidden;
}

.footer-progress span {
  position: absolute;
  inset: 0;
  transform-origin: left center;
  transform: scaleX(var(--footer-progress-fill, 0));
  border-radius: inherit;
  background: var(--pink);
  /* Slow, so a quick scroll still shows the bar filling rather than jumping */
  transition: transform 1100ms cubic-bezier(0.22, 0.8, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  .footer-progress span {
    transition: none;
  }
}

.contact-page {
  background: #f6f6f8;
}

.contact-page .motion-reveal {
  opacity: 1;
  transform: none;
  filter: none;
}

.contact-page .nav-links a.is-active .nav-link-track > span:first-child {
  color: var(--pink);
}

.contact-hero {
  position: relative;
  min-height: 100vh;
  padding: 10.4rem 0 6.2rem;
  overflow: clip;
}

.contact-hero::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 2.5rem;
  width: min(1180px, calc(100vw - 2.5rem));
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(46, 46, 46, 0.16), transparent);
}

.contact-hero-shell {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(22rem, 0.75fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 5.5rem);
}

.contact-hero-copy {
  max-width: 48rem;
}

.contact-hero-copy h1 {
  margin-top: 1.2rem;
  font-size: clamp(4.2rem, 8.4vw, 8.55rem);
  line-height: 0.88;
  letter-spacing: 0;
}

.contact-hero-copy h1::after {
  content: ".";
  color: var(--pink);
}

.contact-hero-copy p:not(.eyebrow) {
  max-width: 40rem;
  margin-top: 1.45rem;
  color: var(--text-soft);
  font-size: clamp(1.08rem, 1.55vw, 1.35rem);
  line-height: 1.48;
}

.contact-hero-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 2.25rem;
}

.contact-primary-button,
.contact-secondary-button,
.contact-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3.65rem;
  border-radius: 999px;
  font-family: var(--font-nav);
  line-height: 1;
  transition:
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease,
    background-position var(--motion-slow) ease,
    border-color var(--motion-fast) ease;
}

.contact-primary-button,
.contact-submit {
  padding: 1rem 1.75rem;
  border: 0;
  background: linear-gradient(135deg, #ff0099 0%, #ff37a9 50%, #ff0099 100%);
  background-size: 180% 180%;
  color: #fff;
  box-shadow: 0 18px 34px rgba(255, 0, 153, 0.22);
  cursor: pointer;
}

.contact-secondary-button {
  padding: 0.95rem 1.45rem;
  border: 1px solid rgba(46, 46, 46, 0.12);
  background: rgba(255, 255, 255, 0.48);
  color: rgba(46, 46, 46, 0.78);
}

.contact-primary-button:hover,
.contact-primary-button:focus-visible,
.contact-secondary-button:hover,
.contact-secondary-button:focus-visible,
.contact-submit:hover,
.contact-submit:focus-visible {
  transform: translateY(-4px);
  background-position: 100% 50%;
}

.contact-hero-art {
  position: relative;
  min-height: clamp(28rem, 43vw, 38rem);
}

.contact-art-card {
  position: absolute;
  overflow: hidden;
  background: #191919;
  box-shadow: 0 28px 70px rgba(46, 46, 46, 0.18);
}

.contact-art-card-main {
  inset: 2rem 1rem auto auto;
  width: min(28rem, 92%);
  aspect-ratio: 0.82;
  border-radius: 34px;
  transform: rotate(3deg);
}

.contact-art-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.contact-float-pill,
.contact-float-stat {
  position: absolute;
  z-index: 2;
  border: 1px solid rgba(255, 255, 255, 0.72);
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(18px);
  box-shadow: 0 18px 38px rgba(46, 46, 46, 0.12);
}

.contact-float-pill {
  min-height: 3.25rem;
  padding: 0.8rem 1.15rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 760;
}

.contact-float-pill-one {
  top: 1rem;
  left: 0;
  transform: rotate(-7deg);
}

.contact-float-pill-two {
  right: 0;
  bottom: 7.6rem;
  color: var(--pink);
  transform: rotate(5deg);
}

.contact-float-stat {
  left: 0.9rem;
  bottom: 2rem;
  width: min(17.5rem, 70%);
  padding: 1.05rem 1.2rem;
  border-radius: 26px;
}

.contact-float-stat strong {
  display: block;
  font-size: 3.2rem;
  line-height: 0.9;
}

.contact-float-stat span {
  display: block;
  margin-top: 0.55rem;
  color: rgba(46, 46, 46, 0.72);
  font-size: 0.98rem;
  line-height: 1.3;
}

.contact-proof {
  padding: 7.5rem 0 8rem;
  border-radius: 54px;
  overflow: hidden;
  scroll-margin-top: 7rem;
}

.contact-proof-shell {
  display: grid;
  gap: 3.3rem;
}

.contact-proof-intro {
  max-width: 50rem;
}

.contact-proof-intro h2,
.contact-form-copy h2 {
  margin-top: calc(1rem + 250px);
  font-size: clamp(3rem, 6vw, 6.35rem);
  line-height: 0.92;
  letter-spacing: 0;
}

.contact-benefits {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.contact-benefit {
  min-height: 23rem;
  padding: 1.3rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.055);
  display: grid;
  align-content: space-between;
  transition:
    transform var(--motion-base) var(--ease-standard),
    background-color var(--motion-base) ease,
    border-color var(--motion-base) ease;
}

.contact-benefit:hover {
  transform: translateY(-8px);
  border-color: rgba(255, 0, 153, 0.36);
  background: rgba(255, 255, 255, 0.085);
}

.contact-benefit span {
  width: fit-content;
  padding: 0.45rem 0.75rem;
  border-radius: 999px;
  background: rgba(255, 0, 153, 0.16);
  color: rgba(244, 244, 244, 0.86);
  font-size: 0.82rem;
  line-height: 1;
}

.contact-benefit h3 {
  max-width: 14rem;
  margin-top: 3.6rem;
  color: #fff;
  font-size: clamp(1.55rem, 2.2vw, 2.35rem);
  line-height: 1;
  letter-spacing: 0;
}

.contact-benefit p {
  margin-top: 1.15rem;
  color: rgba(244, 244, 244, 0.68);
}

.contact-form-section {
  padding: 8rem 0 6.6rem;
  scroll-margin-top: 7rem;
}

.contact-form-shell {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(27rem, 0.78fr);
  gap: clamp(2rem, 5vw, 5.5rem);
  align-items: start;
}

.contact-form-copy {
  position: sticky;
  top: 9rem;
}

.contact-form-copy p:not(.eyebrow) {
  max-width: 34rem;
  margin-top: 1.2rem;
  color: var(--text-soft);
  font-size: 1.08rem;
}

.contact-next-steps {
  display: grid;
  gap: 0.75rem;
  margin-top: 2.2rem;
}

.contact-next-steps div {
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr);
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid rgba(46, 46, 46, 0.1);
}

.contact-next-steps strong {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  background: var(--text);
  color: #fff;
  font-size: 0.9rem;
}

.contact-next-steps span {
  color: rgba(46, 46, 46, 0.74);
  font-size: 1rem;
}

.contact-form {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.05rem;
  padding: clamp(1.05rem, 2.4vw, 1.55rem);
  border: 1px solid rgba(255, 255, 255, 0.86);
  border-radius: 28px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.7)),
    rgba(255, 255, 255, 0.72);
  box-shadow:
    0 28px 78px rgba(46, 46, 46, 0.11),
    inset 0 1px 0 rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(24px) saturate(160%);
}

.contact-form::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid rgba(46, 46, 46, 0.05);
  pointer-events: none;
}

.contact-field {
  display: grid;
  gap: 0.5rem;
}

.contact-field-full,
.contact-submit {
  grid-column: 1 / -1;
}

.contact-field label {
  color: rgba(46, 46, 46, 0.58);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.1;
  text-transform: uppercase;
}

.contact-field input,
.contact-field select,
.contact-field textarea {
  width: 100%;
  min-height: 3.45rem;
  border: 1px solid rgba(46, 46, 46, 0.08);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.76);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.3;
  padding: 0.95rem 1rem;
  outline: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
  transition:
    border-color var(--motion-fast) ease,
    box-shadow var(--motion-fast) ease,
    background-color var(--motion-fast) ease;
}

.contact-field textarea {
  resize: vertical;
  min-height: 9.6rem;
}

.contact-field input:focus,
.contact-field select:focus,
.contact-field textarea:focus {
  border-color: rgba(255, 0, 153, 0.45);
  background: #fff;
  box-shadow:
    0 0 0 4px rgba(255, 0, 153, 0.09),
    inset 0 1px 0 rgba(255, 255, 255, 0.88);
}

.contact-field input::placeholder,
.contact-field textarea::placeholder {
  color: rgba(46, 46, 46, 0.36);
}

.contact-submit {
  width: 100%;
  min-height: 4rem;
  font-size: 1rem;
  border-radius: 999px;
  box-shadow:
    0 22px 44px rgba(255, 0, 153, 0.24),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.contact-footer.site-footer {
  margin-top: clamp(3.5rem, 7vw, 6rem);
  min-height: 760px;
}

.contact-footer .footer-shell {
  padding-top: 150px;
}

@media (max-width: 1024px) {
  .contact-hero-shell,
  .contact-form-shell {
    grid-template-columns: 1fr;
  }

  .contact-hero-copy {
    max-width: none;
  }

  .contact-hero-art {
    min-height: 32rem;
  }

  .contact-art-card-main {
    left: 50%;
    right: auto;
    transform: translateX(-50%) rotate(2deg);
  }

  .contact-form-copy {
    position: static;
  }

  .contact-benefits {
    grid-template-columns: 1fr;
  }

  .contact-benefit {
    min-height: 17rem;
  }
}

@media (max-width: 720px) {
  .contact-hero {
    min-height: auto;
    padding: 8.4rem 0 4.6rem;
  }

  .contact-hero-copy h1 {
    font-size: clamp(3.5rem, 15vw, 5.15rem);
    line-height: 0.94;
  }

  .contact-hero-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .contact-primary-button,
  .contact-secondary-button {
    width: 100%;
  }

  .contact-hero-art {
    min-height: 26rem;
  }

  .contact-art-card-main {
    width: min(21rem, 86vw);
    border-radius: 26px;
  }

  .contact-float-pill {
    font-size: 0.88rem;
  }

  .contact-float-stat {
    width: min(15rem, 78%);
  }

  .contact-proof,
  .contact-form-section {
    padding-block: 5rem;
  }

  .contact-proof {
    border-radius: 34px;
  }

  .contact-proof-intro h2,
  .contact-form-copy h2 {
    font-size: clamp(2.7rem, 12vw, 4.2rem);
  }

  .contact-form {
    grid-template-columns: 1fr;
  }

  .contact-page .nav-menu {
    background: rgba(255, 255, 255, 0.97);
  }

  .contact-page[data-nav-theme="dark"] .nav-menu {
    background: rgba(33, 33, 33, 0.96);
  }
}

.contact-main {
  position: relative;
  min-height: 100svh;
  padding: clamp(9.8rem, 16vh, 12.8rem) 0 clamp(2.4rem, 5vh, 4.2rem);
  overflow: clip;
}

.contact-main .section-shell {
  width: var(--boxed-guide-width);
}

.contact-layout {
  position: relative;
  min-height: calc(100svh - clamp(11rem, 17vh, 15rem));
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(24rem, 0.74fr);
  grid-template-areas: "copy form";
  align-items: start;
  gap: clamp(0.95rem, 2.2vw, 2rem) clamp(2rem, 5vw, 5.4rem);
}

.contact-copy {
  grid-area: copy;
  align-self: start;
  max-width: 43rem;
  /* Pulls the cap height of the h1 level with the top of the form box
     (the font carries ~10px of space above its capitals). */
  margin-top: -0.6rem;
  position: relative;
  z-index: 2;
  transform: none;
}

.contact-copy h1 {
  max-width: 8.6em;
  font-size: clamp(3.15rem, 5.15vw, 5.35rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

.contact-title-dot {
  display: inline;
  color: var(--pink);
  font: inherit;
  line-height: inherit;
}

.contact-copy p:not(.eyebrow) {
  max-width: 34rem;
  margin-top: 1.05rem;
  color: var(--text-soft);
  font-size: clamp(1.02rem, 1.32vw, 1.18rem);
  line-height: 1.52;
}

.contact-mini-points {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: 1.4rem;
}

.contact-mini-points span {
  display: inline-flex;
  align-items: center;
  min-height: 2.45rem;
  padding: 0.62rem 0.9rem;
  border: 1px solid rgba(46, 46, 46, 0.09);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.62);
  color: rgba(46, 46, 46, 0.72);
  font-size: 0.92rem;
  line-height: 1;
  backdrop-filter: blur(14px);
}

.contact-object {
  position: absolute;
  z-index: 1;
  top: calc(54% - 50px);
  left: calc((100vw - var(--boxed-guide-width)) / -2 - 1.2rem + 180px);
  width: clamp(24.625rem, calc(54vw - 150px), 38.625rem);
  filter: drop-shadow(0 28px 34px rgba(46, 46, 46, 0.16));
  opacity: 0.42;
  transform: translateY(-24%);
  animation: none;
  pointer-events: none;
}

.contact-object img {
  width: 100%;
  height: auto;
  object-fit: contain;
  object-position: center;
  animation: contact-float 4.9s ease-in-out infinite alternate;
}

.contact-main .contact-form {
  grid-area: form;
  align-self: start;
  position: relative;
  z-index: 2;
  padding: clamp(1rem, 2vw, 1.35rem);
}

.contact-main .contact-submit {
  margin-top: 0.25rem;
}

.faq-page {
  background: #f6f6f8;
}

.faq-main {
  min-height: 100svh;
  padding: clamp(9.7rem, 15vh, 12rem) 0 clamp(3.2rem, 7vh, 5.8rem);
  overflow: clip;
}

.faq-main .section-shell {
  width: var(--boxed-guide-width);
}

.faq-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.58fr) minmax(28rem, 0.82fr);
  grid-template-areas:
    "copy list"
    "cta list";
  align-items: start;
  gap: 1.25rem clamp(2rem, 5vw, 5rem);
}

.faq-copy {
  grid-area: copy;
  max-width: 34rem;
}

.faq-copy h1 {
  max-width: 7.6em;
  font-size: clamp(3rem, 5vw, 5.05rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

.faq-copy p {
  max-width: 21rem;
  margin-top: 1rem;
  color: var(--text-soft);
  font-size: clamp(1.02rem, 1.28vw, 1.16rem);
  line-height: 1.52;
}

.faq-accordion {
  grid-area: list;
  display: grid;
  gap: 0.55rem;
}

.faq-item {
  border: 1px solid rgba(255, 255, 255, 0.86);
  border-radius: 28px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.72)),
    rgba(255, 255, 255, 0.74);
  box-shadow:
    0 18px 46px rgba(46, 46, 46, 0.07),
    inset 0 1px 0 rgba(255, 255, 255, 0.84);
  backdrop-filter: blur(18px) saturate(145%);
  overflow: hidden;
}

.faq-question {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2rem;
  align-items: center;
  gap: 0.8rem;
  width: 100%;
  min-height: 4.15rem;
  padding: 0.95rem 1.1rem 0.9rem 1.25rem;
  border: 0;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.22vw, 1.18rem);
  font-weight: 620;
  line-height: 1.08;
  text-align: left;
  list-style: none;
}

.faq-question::after {
  content: "+";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 999px;
  background: rgba(255, 0, 153, 0.1);
  color: var(--pink);
  font-family: var(--font-nav);
  font-size: 1.15rem;
  font-weight: 500;
  line-height: 1;
  transition:
    transform var(--motion-base) var(--ease-standard),
    background-color var(--motion-fast) ease;
}

.faq-item.is-open .faq-question::after {
  transform: rotate(45deg);
  background: var(--pink);
  color: #fff;
}

.faq-answer {
  overflow: hidden;
  opacity: 0;
  height: auto;
}

.faq-item.is-open .faq-answer {
  opacity: 1;
}

.faq-answer p {
  max-width: 42rem;
  padding: 0 3.6rem 1.15rem 1.25rem;
  color: rgba(46, 46, 46, 0.62);
  font-size: 1rem;
  font-weight: var(--body-copy-weight);
  line-height: 1.56;
}

.faq-cta {
  grid-area: cta;
  display: grid;
  gap: 1rem;
  max-width: 26rem;
  margin-top: 1.1rem;
  padding: 1.1rem;
  border: 1px solid rgba(46, 46, 46, 0.06);
  border-radius: 28px;
  background: rgba(255, 255, 255, 0.62);
  box-shadow: 0 22px 58px rgba(46, 46, 46, 0.08);
}

.faq-cta p {
  color: rgba(46, 46, 46, 0.5);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.1;
  text-transform: uppercase;
}

.faq-cta h2 {
  max-width: 18rem;
  font-size: clamp(1.65rem, 2.4vw, 2.15rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.faq-cta .contact-primary-button {
  width: fit-content;
  min-height: 3.35rem;
  padding-inline: 1.35rem;
}

@keyframes contact-float {
  from {
    transform: translate3d(0, 0, 0);
  }

  to {
    transform: translate3d(0, -28px, 0);
  }
}

@media (max-width: 1024px) {
  .contact-layout {
    min-height: auto;
    grid-template-columns: 1fr;
    grid-template-areas:
      "copy"
      "form";
  }

  .contact-copy {
    max-width: none;
  }

  .contact-object {
    top: calc(56% - 50px);
    left: 50%;
    width: min(32.625rem, calc(124vw - 150px));
    opacity: 0.24;
    transform: translate(calc(-62% + 180px), -12%);
  }

  .faq-layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "copy"
      "list"
      "cta";
  }

  .faq-copy,
  .faq-cta {
    max-width: none;
  }
}

@media (max-width: 900px) {
  .contact-main .section-shell,
  .faq-main .section-shell {
    width: calc(100vw - 1.6rem);
  }
}

@media (max-width: 720px) {
  .contact-main .section-shell,
  .faq-main .section-shell {
    width: var(--shell);
  }

  .contact-main,
  .faq-main {
    min-height: auto;
    padding: 7.55rem 0 2.2rem;
  }

  .contact-layout {
    gap: 1.35rem;
  }

  .contact-copy h1 {
    max-width: 8.2em;
    font-size: clamp(2.7rem, 10.4vw, 3.65rem);
    line-height: 0.98;
  }

  .contact-mini-points {
    gap: 0.45rem;
  }

  .contact-mini-points span {
    min-height: 2.15rem;
    font-size: 0.82rem;
  }

  /* Out of the absolute layer and into the flow, as the last row of
     the layout, so it sits centred under the form and the section
     grows to make room for it. Absolutely positioned it ran from x188
     to x533 — 158px past the viewport, saved only by .contact-main's
     overflow:clip — and sat across the form. */
  .contact-layout {
    grid-template-areas:
      "copy"
      "form"
      "object";
  }

  /* .contact-main clips both axes, which would cut the object off at
     the section edge. Clipping x only keeps it from bleeding sideways
     while letting it hang below (clip is the one value that may pair
     with visible), and the stacking context puts it over the panel. */
  .contact-main {
    overflow-x: clip;
    overflow-y: visible;
    position: relative;
    z-index: 3;
  }

  .contact-object {
    grid-area: object;
    /* Breaking out of the 335px copy column symmetrically. Neither
       auto margins nor justify-self will centre an item that is wider
       than its own grid track — auto margins resolve to zero there and
       take precedence over justify-self, so both left-anchored it and
       left it 8px off centre. Measuring the overhang off the track
       itself does work: 50% of the track minus 50vw is exactly half
       the difference, whatever the viewport. */
    width: calc(100vw - 1.5rem);
    margin: 0.25rem calc(50% - 50vw + 0.75rem) 0;
    /* Pushed down past the end of the section and over the review panel
       below. translate rather than margin so the section keeps the
       height it grew, and z-index so it sits in front of the dark panel
       rather than disappearing behind it.

       inset:auto matters — the base rule positions this absolutely with
       its own left/top offsets, and those are only inert while it is
       static. Switching to relative for the z-index brought them back
       and threw it 167px off centre and past the right edge. */
    position: relative;
    inset: auto;
    z-index: 4;
    /* Offset with top, not transform: .motion-reveal owns transform for
       this element's reveal and overwrites anything set here. With
       position:relative, top shifts it visually without disturbing the
       layout the section already grew for it. */
    top: 0;
  }

  .contact-object img {
    width: 100%;
    height: auto;
  }


  .contact-main .contact-form {
    padding: 0.95rem;
  }

  .faq-layout {
    gap: 0.7rem;
  }

  .faq-copy h1 {
    font-size: clamp(2.35rem, 9.4vw, 3.15rem);
    line-height: 0.98;
  }

  .faq-copy p {
    max-width: none;
    margin-top: 0.55rem;
    font-size: 0.98rem;
    line-height: 1.42;
  }

  .faq-item {
    border-radius: 22px;
  }

  .faq-accordion {
    gap: 0.42rem;
    /* Was height:25.45rem with overflow-y:auto — a fixed-height inner
       scroller. Opening an answer grew the item past that height, so
       the list scrolled inside its own box and the page never made
       room: the answer read as cropped with the footer still sitting
       where it was. Letting the list size to its content is what makes
       the page expand as an item opens. */
    height: auto;
    overflow-y: visible;
    padding-right: 0.1rem;
  }

  .faq-accordion::-webkit-scrollbar {
    display: none;
  }

  .faq-question {
    min-height: 3.15rem;
    padding: 0.62rem 0.78rem 0.58rem 0.9rem;
    font-size: 0.92rem;
  }

  .faq-question::after {
    width: 1.55rem;
    height: 1.55rem;
    font-size: 1rem;
  }

  .faq-item p {
    padding: 0 1.1rem 1.2rem;
  }

  .faq-cta {
    border-radius: 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .contact-object,
  .contact-object img {
    animation: none;
  }
}

@keyframes btn-shimmer {
  0% {
    left: -110%;
    opacity: 1;
  }

  100% {
    left: 160%;
    opacity: 0.6;
  }
}

@keyframes float-pawn {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }

  35% {
    transform: translate3d(-0.18rem, -0.85rem, 0) rotate(-1.1deg);
  }

  50% {
    transform: translate3d(-0.32rem, -1.15rem, 0) rotate(-1.75deg);
  }

  75% {
    transform: translate3d(0.08rem, -0.42rem, 0) rotate(0.65deg);
  }
}

@keyframes drift-soft {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }

  22% {
    transform: translate3d(0.18rem, -0.52rem, 0) rotate(0.55deg) scale(1.012);
  }

  50% {
    transform: translate3d(0.08rem, -1rem, 0) rotate(0.22deg) scale(1.018);
  }

  72% {
    transform: translate3d(-0.14rem, -0.68rem, 0) rotate(-0.42deg) scale(1.01);
  }
}

@keyframes drift-card {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }

  24% {
    transform: translate3d(0.2rem, -0.56rem, 0) rotate(0.8deg) scale(1.008);
  }

  48% {
    transform: translate3d(-0.14rem, -1.1rem, 0) rotate(-0.7deg) scale(1.014);
  }

  72% {
    transform: translate3d(0.1rem, -0.38rem, 0) rotate(0.32deg) scale(1.005);
  }
}

@keyframes drift-wide {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }

  28% {
    transform: translate3d(-0.22rem, -0.58rem, 0) rotate(-0.52deg) scale(1.01);
  }

  55% {
    transform: translate3d(0.24rem, -1.05rem, 0) rotate(0.58deg) scale(1.016);
  }

  80% {
    transform: translate3d(-0.1rem, -0.42rem, 0) rotate(-0.2deg) scale(1.006);
  }
}

@keyframes product-float-soft {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }

  30% {
    transform: translate3d(0.1rem, -0.28rem, 0) rotate(0.45deg);
  }

  62% {
    transform: translate3d(-0.08rem, -0.56rem, 0) rotate(-0.35deg);
  }
}

@keyframes product-float-main {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }

  34% {
    transform: translate3d(-0.14rem, -0.32rem, 0) rotate(-0.28deg) scale(1.003);
  }

  68% {
    transform: translate3d(0.12rem, -0.64rem, 0) rotate(0.22deg) scale(1.006);
  }
}

@keyframes float-scene {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }

  35% {
    transform: translate3d(0.2rem, -0.7rem, 0);
  }

  65% {
    transform: translate3d(-0.18rem, -1.05rem, 0);
  }
}

@keyframes blink-cursor {
  0%,
  46% {
    opacity: 1;
  }

  50%,
  100% {
    opacity: 0;
  }
}

@keyframes float-laptop {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }

  30% {
    transform: translate3d(0.32rem, -0.45rem, 0) rotate(0.35deg);
  }

  50% {
    transform: translate3d(0.55rem, -1rem, 0) rotate(0.85deg);
  }

  76% {
    transform: translate3d(-0.22rem, -0.35rem, 0) rotate(-0.3deg);
  }
}

@keyframes float-graph {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }

  25% {
    transform: translate3d(0.1rem, -0.55rem, 0) rotate(0.55deg);
  }

  50% {
    transform: translate3d(0.28rem, -0.92rem, 0) rotate(1deg);
  }

  80% {
    transform: translate3d(-0.12rem, -0.28rem, 0) rotate(-0.25deg);
  }
}

@keyframes float-dice {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg);
  }

  28% {
    transform: translate3d(0.24rem, -0.58rem, 0) rotate(0.95deg);
  }

  50% {
    transform: translate3d(0.42rem, -1.05rem, 0) rotate(1.5deg);
  }

  78% {
    transform: translate3d(-0.14rem, -0.36rem, 0) rotate(-0.4deg);
  }
}

@media (max-width: 1080px) {
  .site-footer {
    min-height: auto;
  }

  .case-masonry {
    column-count: 2;
  }

  .products-frame,
  .footer-shell {
    grid-template-columns: 1fr;
  }

  .products-card {
    min-height: auto;
    padding: 1.6rem;
    gap: 1.5rem;
  }

  .products-tabs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem;
  }

  .product-tab-logo {
    width: min(184px, calc(100% - 1.4rem));
  }

  .product-showcase {
    min-height: 37rem;
  }

  .product-showcase-pattern {
    width: min(31rem, 96%);
  }

  .product-showcase-stage {
    margin-inline: auto;
  }

  .products-heading {
    line-height: 1.05;
  }

  .cta-shell {
    min-height: 60rem;
    gap: 100px;
  }

  .cta-section {
    margin-bottom: -72px;
    border-top-left-radius: 34px;
    border-top-right-radius: 34px;
    border-bottom-left-radius: 34px;
    border-bottom-right-radius: 34px;
  }

  .cta-copy {
    margin-top: 3rem;
    /* The desktop -106px nudge is a subtle compositional offset, but the
       heading is nearly as wide as the viewport at this range, so any
       leftward shift pushes it off the left edge - drop it here. */
    transform: none;
  }

  /* The base 73px size only has room to breathe at full desktop widths -
     between here and the 720px breakpoint below, the second line (which
     cycles through several words via JS, some longer than "ambitious")
     was overflowing past the right edge. */
  .cta-type-heading {
    width: min(860px, calc(100vw - 2rem));
    font-size: clamp(1.9rem, 4.6vw, 2.9rem);
    line-height: 1.05;
  }

  .cta-type-line {
    /* Swap the row-flex layout for a plain inline flow so the cycling
       word (which can be longer than "ambitious") wraps as one
       continuous line of text instead of each flex child wrapping
       independently into its own side-by-side column. */
    display: inline;
    white-space: normal;
    text-align: center;
  }

  .cta-art {
    width: min(100vw, 72rem);
    height: clamp(24rem, 52vw, 38rem);
  }

  .footer-links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer-mark {
    grid-column: auto;
    width: 32px;
    margin-top: 0;
    margin-left: 0.2rem;
  }

  .footer-links {
    grid-column: auto;
    justify-self: start;
    width: min(34rem, 100%);
  }

  .footer-shell {
    padding-top: 6rem;
  }

  .footer-wordmark-shell {
    width: min(100%, 52rem);
    margin-top: 3.5rem;
    padding-bottom: 92px;
  }

  .footer-wordmark {
    width: min(100%, 52rem);
    margin-left: 0;
  }

  .footer-wordmark-shell::after {
    right: 8%;
  }

  /* Stays a single row down to the phone tier below. Stacking the copy
     over the link was what gave this bar its height. */
  .footer-bottom-shell {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 0.9rem;
    min-height: 0;
    padding-block: 1.1rem;
  }

  .footer-next-page {
    justify-self: end;
  }
}

@media (max-width: 1240px) {
  /* The inline desktop nav (logo + links + CTA pill) needs ~1180px of
     breathing room and stops fitting the nav pill well before the 900px
     content breakpoint below - e.g. iPad landscape at 1024px was
     clipping the "Let's Talk" button off the edge. This block switches
     to the compact hamburger nav earlier, independent of the 900px
     breakpoint used for hero/section content sizing. */
  .menu-toggle {
    display: inline-flex;
  }

  .nav-menu {
    position: absolute;
    top: calc(100% + 0.65rem);
    left: 0;
    right: 0;
    padding: 1rem;
    border-radius: 28px;
    background: rgba(255, 255, 255, 0.97);
    border: 1px solid rgba(46, 46, 46, 0.08);
    box-shadow: 0 18px 40px rgba(46, 46, 46, 0.12);
    backdrop-filter: blur(22px);
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-left: 0;
  }

  body[data-nav-theme="dark"] .nav-menu {
    background: rgba(28, 28, 28, 0.97);
    border-color: rgba(255, 255, 255, 0.08);
  }

  .nav-links {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .nav-about-wrap {
    width: auto;
    min-height: 0;
    display: block;
  }

  /* The hover panels can't work on a touch device, so on mobile the
     "+" links expand their sub-pages inline instead — see the toggle in
     script. Collapsed by default; the open state below out-specifies
     this rule. */
  .nav-about-panel {
    display: none;
  }

  .nav-about-wrap.is-open .nav-about-panel {
    display: block;
    position: static;
    width: auto;
    padding: 0.15rem 0 0.55rem 0.9rem;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }

  /* The panel photograph is desktop garnish; in a stacked menu it just
     pushes the links off the screen. */
  .nav-about-wrap.is-open .nav-about-media {
    display: none;
  }

  .nav-about-wrap.is-open .nav-about-links {
    gap: 0.3rem;
  }

  .nav-links a,
  .nav-menu a {
    min-height: 0;
    width: auto;
    padding: 0.9rem 0.35rem;
    color: inherit;
  }

  /* The desktop nav gives each link a fixed width by position (the fifth is
     63px), which clips "Contact us" to "Contac" in the stacked menu. */
  .nav-links a:nth-child(n) {
    width: auto;
  }

  .nav-links a {
    justify-content: flex-start;
    min-height: 0;
  }

  .nav-link-track {
    place-items: start;
  }

  .nav-link-track > span {
    justify-content: flex-start;
  }

  .nav-cta {
    width: 100%;
    min-width: 0;
    margin-top: 0.5rem;
  }
}

@media (max-width: 900px) {
  :root {
    /* 1.4rem left an 11px gutter each side — tighter than the 24px the
       desktop shell uses, so every section sat harder against the phone
       edge than it does on a laptop. 2.5rem gives a 20px gutter. */
    --shell: min(100vw - 2.5rem, 760px);
  }

  .site-header {
    top: 1rem;
    padding-inline: 0.8rem;
  }

  body.nav-scrolled .site-header,
body.contact-page .site-header {
    transform: translateY(-0.45rem);
  }

  .nav-shell {
    width: calc(100vw - 1.6rem);
    padding-inline: 1rem;
    border-radius: 22px;
  }

  .brand-logo {
    width: 92px;
  }

  .hero-copy {
    top: 13.4rem;
    width: min(92vw, 780px);
  }

  .hero-title {
    font-size: clamp(4rem, 10.4vw, 6.5rem);
    line-height: 0.98;
  }

  .hero-button {
    top: auto;
    bottom: 2rem;
  }

  .why-panel {
    min-height: auto;
    padding: 6rem 3rem 6.25rem;
    border-radius: 42px;
  }

  .why-shell {
    width: var(--shell);
    max-width: none;
    min-height: auto;
    margin-left: auto;
    margin-right: auto;
  }

  .why-pill,
  .why-copy,
  .why-button {
    position: static;
    left: auto;
    top: auto;
    transform: none;
  }

  .why-copy {
    margin-top: 3rem;
    width: 100%;
  }

  .why-copy-block {
    font-size: 1.7rem;
    line-height: 2.9rem;
    text-wrap: pretty;
  }

  .why-button {
    margin-top: 4.5rem;
  }

  body.menu-open .nav-menu {
    display: flex;
  }

  .services-section {
    min-height: 640vh;
  }

  .service-card {
    grid-template-columns: 1fr;
    padding: 1rem;
  }

  .service-visual-panel {
    min-height: 20rem;
  }

  .service-card-body {
    max-width: none;
    padding: 0.25rem 0.35rem 0.65rem;
  }

  .service-card-body h3 {
    max-width: none;
  }

  .service-index {
    font-size: 3rem;
  }
}

@media (max-width: 720px) {
  .site-header {
    top: 0.7rem;
    padding-inline: 0.7rem;
  }

  body.nav-scrolled .site-header,
body.contact-page .site-header {
    transform: translateY(-0.3rem);
  }

  .nav-shell {
    /* Matches the content gutter, so the pill's edge lines up with the
       sections under it instead of sitting 9px proud of them. */
    width: calc(100vw - 2.5rem);
    padding-inline: 1rem;
    min-height: 64px;
  }

  .hero-section {
    min-height: 260vh;
  }

  .hero-stage {
    min-height: max(100vh, 760px);
  }

  /* The copy block's centre sits on this value. At 15.5rem it rode high
     — centre 248 against a viewport centre of 406 — which read as
     top-weighted once the headline came down to three lines. */
  /* The copy block's centre sits on this value. The headline is four
     lines at its full size, so the block is ~274px tall; 17.8rem puts
     its centre at 285 against a viewport centre of 406, which is as far
     down as it can go while still clearing the card cluster below. */
  /* The copy + button group is centred on the viewport as a unit: the
     block is ~383px tall (274 copy + 53 gap + 56 button), so on an
     812px screen it starts at 215 and this value puts the copy's own
     centre at 352. */
  .hero-copy {
    top: 22rem;
    width: min(92vw, 560px);
  }


  .hero-title {
    font-size: clamp(3.55rem, 16vw, 5rem);
    line-height: 0.98;
    letter-spacing: -0.05em;
  }

  .hero-subtitle {
    max-width: 22rem;
    margin-top: 1rem;
    font-size: 1.05rem;
  }

  .hero-line {
    white-space: normal;
  }

  /* The headline splits in two so the intro's closing circle can sit in
     the gap: "We run" slides left and "campaigns." slides right. That
     works on desktop where both sit on one line — but here the line
     wraps, so the two halves are on separate lines and the split just
     shunted them in opposite directions for no visible reason. Only the
     first half moves now; "campaigns." stays centred. */
  .hero-line-part-end {
    transform: none;
  }

  .section-intro p:last-child,
  .why-copy-block,
  .service-card-body > p,
  .cta-copy p:last-of-type {
    font-size: 1rem;
  }

  .why-panel {
    min-height: auto;
    padding: 4.6rem 1.35rem 4.8rem;
    border-radius: 30px;
  }

  .why-shell {
    width: var(--shell);
    max-width: none;
    min-height: auto;
    margin-left: auto;
    margin-right: auto;
  }

  .why-pill {
    width: fit-content;
    min-height: 2rem;
    padding-inline: 1.2rem;
    font-size: 1rem;
    line-height: 1.125rem;
  }

  .why-copy {
    margin-top: 2rem;
  }

  .why-copy-block {
    font-size: 1.28rem;
    line-height: 2.1rem;
    text-wrap: pretty;
  }

  .why-button {
    width: min(14.3rem, 100%);
    min-width: 0;
    margin-top: 3rem;
    font-size: 1rem;
    line-height: 1.2;
  }

  .why-button-icon {
    font-size: 0.95rem;
  }

  .hero-card-photo {
    border-radius: 24px;
  }

  /* Sizing is handled in cqw on the base rule, so the phone tier only
     needs the tighter corner. */
  .hero-card-stat {
    border-radius: 24px;
  }

  .why-section,
  .case-section,
  .cta-section {
    padding-block: 6rem;
  }

  /* Lifts the button off the bottom edge: at 1.2rem its centre sat at
     94% of the screen, past where a thumb comfortably reaches. 5.25rem
     puts it around 86%, inside the reach zone and still clear of the
     card cluster above it. */
  /* Anchored under the copy, not to the bottom of the stage. Pinning it
     to `bottom` left a ~220px void between the subtitle and the button
     on first view — that band is where the cards land, but they only
     arrive on scroll, so the hero opened on a hole. The cluster now
     sits below the button instead (see the home-y values above). */
  .hero-button {
    top: 43.33rem;
    bottom: auto;
    /* Ends at 3.5rem, matching the height — at 12rem it shrank to 4rem
       wide against a 3.5rem height, so the "dot" was a 64x56 ellipse
       rather than a circle. */
    width: calc(16rem - 12.5rem * var(--hero-cta-progress));
    height: 3.5rem;
    min-height: 3.5rem;
    /* The shadow tightens into a symmetric glow as the button collapses.
       At full size an 18px drop with 34px blur is right; on the dot it
       reached ~52px below a button that sits 15px off the bottom of the
       stage, and .hero-stage is overflow:clip — so the lower half was
       sliced off. Ending at 0 offset / 14px blur keeps it inside. */
    box-shadow:
      0 calc(18px * (1 - var(--hero-cta-progress)))
      calc(34px - 20px * var(--hero-cta-progress))
      rgba(255, 0, 153, 0.22);
  }

  .hero-button-label {
    gap: 0.55rem;
    font-size: 0.92rem;
  }

  .services-section {
    min-height: auto;
    padding: 5rem 0 4rem;
  }

  .services-stage {
    position: static;
    min-height: auto;
    padding: 0;
  }

  .services-header {
    position: static;
    top: auto;
    left: auto;
    width: var(--shell);
    transform: none;
    margin: 0 auto 1.5rem;
  }

  .services-summary {
    gap: 0.55rem;
  }

  .services-summary span {
    min-height: 2rem;
    padding-inline: 0.8rem;
    font-size: 0.72rem;
  }

  .services-pill {
    width: fit-content;
    min-height: 32px;
    padding-inline: 1.2rem;
    margin-inline: auto;
    font-size: 16px;
    line-height: 18px;
  }

  .services-stack {
    width: var(--shell);
    min-height: auto;
    display: grid;
    gap: 1rem;
  }

  .service-card {
    position: static;
    transform: none !important;
    opacity: 1 !important;
    min-height: auto;
    grid-template-columns: 1fr;
    padding: 0.9rem;
  }

  .service-visual-panel {
    min-height: 18rem;
    padding: 1.2rem;
  }

  .service-visual-note strong {
    font-size: 1.02rem;
  }

  .service-card-body {
    padding: 0.25rem 0.2rem 0.35rem;
  }

  .service-copy-top {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.7rem;
  }

  .service-card-body h3 {
    max-width: none;
    font-size: 1.95rem;
    line-height: 0.98;
  }

  .service-card-body > p {
    max-width: none;
  }

  .case-masonry {
    column-count: 1;
  }

  .products-section {
    padding: 4.7rem 0 2.8rem;
  }

  .products-frame {
    gap: 1rem;
  }

  .products-tabs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
  }

  /* The CTA has to sit under the showcase on a phone, but it lives
     inside .product-panel and the tab script rewrites that panel's
     innerHTML on every switch — so it cannot just be moved in the
     markup, and a duplicate would go stale (the label is per-product).

     display:contents promotes the panel's own children into the frame's
     grid, where `order` can place the link after the image. It is all
     class-based, so it survives the innerHTML rewrite. The panel's box
     disappears with it, so its padding is re-applied to the children
     that needed it. */
  .product-panel {
    display: contents;
  }

  /* minmax(0,1fr), not 1fr: the Swoppa / qa.ai / Loaneo showcases size
     their stage at min(100%, 32rem), and against a plain `1fr` track
     that 32rem counts as max-content — so the track grew to 487px
     inside a 335px card and every child stretched with it. A 0 minimum
     stops the track being pushed out by its own contents, and the
     stages' 100% then resolves against the real width. */
  .products-frame {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0;
    justify-items: start;
  }

  .product-tag,
  .product-label {
    order: 1;
    margin-top: 1.4rem;
  }

  .product-title {
    order: 2;
  }

  .product-copy {
    order: 3;
  }

  .product-showcase {
    order: 4;
    justify-self: stretch;
  }

  .product-link {
    order: 5;
    justify-self: stretch;
    margin-bottom: 0.4rem;
  }

  /* The card was sized off the viewport rather than its shell, so it
     stretched the shell's auto track to 359px inside a 335px container
     and took the intro and overview out with it. */
  .products-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  .products-card {
    width: 100%;
    max-width: 40rem;
    padding: 1rem;
    border-radius: 24px;
  }

  .product-tab {
    min-height: 3.55rem;
    border-radius: 14px;
  }

  .product-tab-logo {
    width: min(100%, 7.7rem);
    height: 1.25rem;
  }

  .products-pill {
    width: fit-content;
    min-height: 32px;
    padding-inline: 1.2rem;
    font-size: 16px;
    line-height: 18px;
  }

  .products-heading {
    max-width: 17rem;
    font-size: clamp(2.25rem, 9vw, 3rem);
    line-height: 1.03;
  }

  .product-title {
    max-width: 100%;
    font-size: 1.5rem;
    line-height: 1.25;
  }

  .product-copy {
    max-width: 100%;
    margin-top: 1.15rem;
    font-size: var(--body-copy-size);
    line-height: var(--body-copy-line-height);
  }

  .product-link {
    min-width: min(100%, 18rem);
    width: 100%;
    min-height: 3rem;
    font-size: 1rem;
  }

  .product-showcase {
    min-height: auto;
  }

  .product-showcase-bloom {
    width: min(18rem, 94%);
    top: -0.85rem;
  }

  .product-showcase-pattern {
    top: -0.35rem;
    right: 50%;
    width: min(19rem, 100%);
    transform: translateX(50%);
  }

  .product-showcase-stage {
    width: min(100%, 20rem);
    min-height: auto;
  }

  /* 100px of grid gap plus the copy's own 2rem top margin left 145px
     of blank between the artwork and the headline, so the block read as
     two unrelated halves rather than one CTA. */
  .cta-shell {
    min-height: 34rem;
    gap: 44px;
    padding-bottom: 3rem;
  }

  .cta-section {
    margin-bottom: -56px;
    border-top-left-radius: 28px;
    border-top-right-radius: 28px;
    border-bottom-left-radius: 28px;
    border-bottom-right-radius: 28px;
  }

  .cta-copy {
    margin-top: 0.75rem;
    transform: none;
  }

  /* 100vw measured past the shell's own inset and pushed the artwork
     22px off the right edge of the card; 100% is the figure wanted. */
  /* Sized to the mobile artwork's own 1.9:1 proportions, so the frame
     ends where the collage does instead of leaving dead air under it.
     A little taller than the image itself to leave headroom — see the
     float note below. */
  .cta-art {
    width: min(100%, 34rem);
    height: 13.75rem;
  }

  /* The float stays. It peaks at 0.7rem (11.2px) of upward drift, and
     .cta-section is overflow:hidden for its rounded corners — the top
     of the collage used to sit only 5px inside that boundary, so every
     drift clipped it. The taller frame above gives 17px of headroom,
     which clears the peak. */

  /* The ground shadow is a separate blurred ellipse element, not part of
     the artwork. The mobile collage is cut out with its own soft
     contact shadows, so this reads as a stray grey smudge under it. */
  .cta-ground-shadow {
    display: none;
  }

  .cta-ground-shadow {
    width: 86%;
    bottom: 8%;
  }

  /* line-height was 0.98 — tighter than the type is tall, so the two
     lines closed up on each other. The 19rem cap also held the heading
     ~30px narrower than the shell it sits in, forcing an extra wrap. */
  /* Block, not column-flex. The 1080px rule already sets
     .cta-type-line to display:inline so the sentence flows as one
     string, but a flex container blockifies its children, so the two
     lines stayed separate and "build" could never sit beside
     "something" — the first line always broke after "build". As a plain
     block the spans really are inline and the copy wraps to the width
     it has. */
  /* Sized so "build something that's" fits on one line at every phone
     width: that string is 9.19x the font-size, against a width of
     100vw - 2.5rem capped at 24rem. The cap and the clamp floor are
     both set by that constraint (430px and 320px respectively). */
  .cta-type-heading {
    display: block;
    width: min(24rem, calc(100vw - 2.5rem));
    max-width: none;
    font-size: clamp(1.8rem, 9.2vw, 2.9rem);
    line-height: 1.06;
    letter-spacing: -0.04em;
  }

  /* Greedy wrapping fills the first line to "If you're ready to build"
     (314px at 375px) and can never put "build" with "something",
     because "build something that's" is wider still (317px). Only a
     forced break gets the split asked for. */
  .cta-type-build::before,
  .cta-type-thats::before {
    content: "\A";
    white-space: pre;
  }

  .cta-type-build,
  .cta-type-thats {
    margin-left: 0;
  }

  /* Two lines in the stat card on phones. */
  .stat-line-break::before {
    content: "\A";
    white-space: pre;
  }

  /* ...and "in 12 Months" kept whole on the line below. */
  .stat-line-break-soft::before {
    content: "\A";
    white-space: pre;
  }

  /* The stat caption is small enough on a phone to read as fine print;
     6.4cqw of a ~128px card is 8.2px, so this is roughly +2px. */
  .hero-card-stat span {
    font-size: 8cqw;
  }

  /* The cycled words are very different lengths ("bold" vs "built to
     last"), so the headline kept reflowing between line counts and the
     button under it jumped — 37px at 375px, 42px at 430px. A reserved
     min-height cannot fix this, because the number of lines needed
     differs per width. Breaking before the word instead puts it on a
     line of its own, so the line count stops depending on which word is
     being typed and the block holds still at every width. */
  /* No break here any more: the word shares line three with "that's",
     which is what keeps the line count fixed at three while the word
     cycles. */
  .cta-typeword::before {
    content: none;
  }

  .cta-hero-button {
    bottom: auto;
    width: min(17rem, calc(100vw - 2.5rem));
    height: 3.4rem;
    min-height: 3.4rem;
  }

  /* The label's font-size never reached the two spans inside it: a
     global span rule pins .hero-button-text to 16px, and
     .hero-button-icon carries a hard 18px of its own — so the arrow
     rendered larger than the words it follows. Both are set explicitly
     here, with the arrow at ~80% of the text, which is where a trailing
     glyph sits without drawing attention to itself. */
  .cta-hero-button .hero-button-label {
    font-size: 1rem;
    gap: 0.5rem;
  }

  .cta-hero-button .hero-button-text {
    font-size: 1rem;
  }

  .cta-hero-button .hero-button-icon {
    font-size: 0.8rem;
  }

  /* Same mismatch on the hero's own button. */
  .hero-button .hero-button-text {
    font-size: 0.95rem;
  }

  .hero-button .hero-button-icon {
    font-size: 0.76rem;
  }

  /* Mobile uses its own three-object artwork (see the <picture> in the
     markup), so there is nothing to crop or offset — it is simply sized
     to the full width of the screen.

     No filter here. .cta-scene runs an 8.4s infinite float animation, and
     a drop-shadow on top of that forces the browser to re-rasterise the
     whole bitmap every frame — which is what made the artwork slow to
     appear and then stutter on a phone. */
  .cta-scene img {
    width: 112%;
    max-width: none;
    transform: none;
    filter: none;
  }

  /* Two columns: the long list on the left with the two short groups
     stacked beside it. One column left this as a single tall
     left-aligned rag with nothing on the right half of the screen. */
  .footer-links {
    grid-template-columns: 1fr 1fr;
    gap: 1.9rem 1.25rem;
    padding-bottom: 2rem;
  }

  .footer-column:nth-child(1) {
    grid-column: 1;
    grid-row: 1 / span 2;
  }

  .footer-column:nth-child(2) {
    grid-column: 2;
    grid-row: 1;
  }

  .footer-column:nth-child(3) {
    grid-column: 2;
    grid-row: 2;
  }

  /* 8px between links, groups held apart by the grid gap above — the
     rhythm has to carry the grouping since the titles are small. */
  .footer-column {
    gap: 0.5rem;
  }

  .footer-title {
    margin-bottom: 0.3rem;
  }

  /* The mark was sitting 1px off "The Good", reading as a bullet on the
     list rather than as the brand mark above it. The lift itself is set
     further down, after the 1024px page-v2 block that would otherwise
     win on source order. */
  .footer-mark {
    width: 30px;
    margin-top: 0;
    margin-bottom: 3.25rem;
  }

  /* 58px on a 375px-wide block is an enormous curve. */
  .site-footer {
    border-top-left-radius: 26px;
    border-top-right-radius: 26px;
  }

  .footer-shell {
    padding-top: 1.5rem;
  }

  .footer-wordmark-shell {
    width: 100%;
    margin-top: 3.4rem;
    padding-bottom: 4.25rem;
    /* The shell is exactly the viewport width here, so clipping on it
       trims the wordmark's deliberate bleed at the screen edges instead
       of letting it widen the document — the 105vw mark was adding 8px
       of horizontal scroll. */
    overflow: hidden;
  }

  /* Sized off the dot rather than off the container. In the artwork the
     dot's centre sits at 97.84% of the width, so at 105vw wide and
     -2.73vw of left offset that centre lands exactly on the right edge
     of the screen — the dot is always half off — while the "l" loses a
     sliver on the left. Both figures are in vw, so the crop holds at
     every phone width. Going much past 105vw would eat the "l" whole:
     it is only 7.5% of the artwork. */
  .footer-wordmark {
    width: 98vw;
    max-width: none;
    /* Keeps the dot's centre on the right edge at the smaller size:
       0.9784 * 98 + 4.12 = 100vw, less 10px of nudge to the left.
       Shrinking the mark is what trades away the left-hand crop. */
    margin-left: calc(4.12vw - 10px);
  }

  .footer-wordmark-shell::after {
    right: 5%;
    bottom: 0.85rem;
    width: 3.8rem;
    height: 1.2rem;
  }

  /* One row: the copy, then the label and its progress bar. These three
     used to stack, which is what made the bar 151px tall on a phone.
     The sizes below fit 375px on a single line with the bar taking
     whatever is left; flex-wrap is the safety net for anything narrower,
     where it drops to two rows rather than overflowing. */
  .footer-bottom-shell {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.45rem 0.6rem;
    min-height: 0;
    padding-block: 0.95rem;
  }

  .footer-bottom-copy {
    flex: 0 1 auto;
    min-width: 0;
  }

  .footer-next-page {
    /* Basis kept under what is actually spare next to the copy — at an
       8rem basis the two together asked for 340px of a 335px shell and
       the row wrapped. */
    flex: 1 1 6.5rem;
    width: auto;
    grid-template-columns: auto minmax(2.25rem, 1fr);
    align-items: center;
    gap: 0.5rem;
  }

  .footer-bottom-copy,
  .footer-bottom-label {
    font-size: 0.72rem;
    line-height: 1.4;
    white-space: nowrap;
  }

  .footer-bottom-label {
    justify-self: start;
  }

  .footer-progress {
    width: auto;
    /* The base rule pins this to the end of its track, which with an
       auto width collapses it to 0 — its fill span is absolutely
       positioned, so there is no content to size it. Stretch fills the
       track instead. */
    justify-self: stretch;
    height: 5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .hero-copy,
  .hero-card,
  .travelling-dot,
  .service-card,
  .product-stat-card,
  .motion-reveal {
    transform: none !important;
  }

  .hero-button-label {
    opacity: 1 !important;
  }

  .motion-reveal {
    filter: none !important;
    opacity: 1 !important;
  }
}

/* ============================================================
   SERVICES (homepage) — sits under the showreel.
   Copy left, horizontal card slider right. Prefix: .srv-
   Card accent colours are the originals from the previous
   services section, passed in as --srv-accent / --srv-wash.
   ============================================================ */

.srv-section {
  position: relative;
  padding: 6.5rem 0 4.5rem;
  scroll-margin-top: var(--nav-height);
  overflow: hidden;
}

/* Same content rail as the testimonial section and products card
   (--boxed-guide-width), so the headline lines up with every other
   section title on the page. */
.srv-section .section-shell {
  width: var(--boxed-guide-width);
}

.srv-layout {
  display: grid;
  grid-template-columns: minmax(300px, 30%) minmax(0, 1fr);
  column-gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}

/* ---- Left column ---- */

.srv-intro {
  display: grid;
  justify-items: start;
  gap: 1.25rem;
}

.srv-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 32px;
  margin: 0;
  padding: 0 1.2rem;
  border-radius: 36px;
  border: 0.5px solid rgba(46, 46, 46, 0.88);
  color: #2e2e2e;
  font-size: 16px;
  font-weight: 310;
  line-height: 18px;
}

.srv-heading {
  margin: 0;
  color: #2e2e2e;
  font-family: var(--font-display);
  /* Runs large now the Services label above it has gone — the two
     words stack, so the column carries the section on its own. */
  font-size: clamp(2.9rem, 5.6vw, 80px);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.045em;
}

/* Type has to be inherited explicitly — the global span rule sets its
   own font-size, and any explicit declaration beats inheritance. */
.srv-heading-line {
  display: block;
  font: inherit;
  letter-spacing: inherit;
}

.srv-controls {
  display: flex;
  gap: 0.65rem;
  margin-top: 0.75rem;
}

.srv-nav-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(46, 46, 46, 0.16);
  background: transparent;
  color: #2e2e2e;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    color var(--motion-fast) ease,
    opacity var(--motion-fast) ease;
}

.srv-nav-btn:hover:not(:disabled),
.srv-nav-btn:focus-visible:not(:disabled) {
  background: var(--pink);
  border-color: var(--pink);
  color: #fff;
}

.srv-nav-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

/* ---- Slider ---- */

.srv-track-wrap {
  --srv-fade-left: 0px;
  --srv-fade-right: 0px;
  min-width: 0;
  /* Negative margins cancel the track's padding, which exists only
     so the card shadows aren't clipped by the scroll container. */
  margin-top: -1rem;
  margin-right: calc((var(--boxed-guide-width) - 100vw) / 2);
  margin-bottom: -2.75rem;
  margin-left: -1.25rem;
  scroll-padding-inline-start: 1.25rem;
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--srv-fade-left),
    #000 calc(100% - var(--srv-fade-right)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--srv-fade-left),
    #000 calc(100% - var(--srv-fade-right)),
    transparent 100%
  );
  transition:
    --srv-fade-left var(--motion-base) ease,
    --srv-fade-right var(--motion-base) ease;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
}

.srv-track-wrap::-webkit-scrollbar {
  display: none;
}

/* Faded edges so cards ease out of view instead of being cut off.
   Set by the slider script as the track scrolls. */
.srv-track-wrap.has-prev {
  --srv-fade-left: 72px;
}

.srv-track-wrap.has-next {
  --srv-fade-right: 72px;
}

.srv-track {
  display: flex;
  gap: 1.25rem;
  margin: 0;
  /* Generous top/bottom padding gives the card shadows (and the
     4px hover lift) room inside the clipped scroll container. */
  padding: 1rem 0 4.75rem 1.25rem;
  list-style: none;
}

/* Trailing space as a flex item rather than padding — a flex scroll
   container drops its end padding from the scrollable area, so the
   last card would otherwise stop hard against the screen edge. Sized
   so the card comes to rest on the same rail as the nav box (the
   flex gap makes up the remainder). */
.srv-track::after {
  content: "";
  flex: 0 0 calc((100vw - var(--boxed-guide-width)) / 2 - 1.25rem);
}

/* ---- Cards — all identical in size ---- */

.srv-card {
  flex: 0 0 auto;
  width: 340px;
  scroll-snap-align: start;
}

.srv-card-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 470px;
  padding: 1.5rem 1.5rem 1.5rem;
  border-radius: 28px;
  border: 1px solid rgba(46, 46, 46, 0.06);
  background: #fff;
  box-shadow: 0 22px 48px rgba(46, 46, 46, 0.07);
  color: inherit;
  text-decoration: none;
  transition:
    transform var(--motion-base) var(--ease-standard),
    box-shadow var(--motion-base) ease,
    border-color var(--motion-fast) ease;
}

.srv-card-inner:hover,
.srv-card-inner:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(var(--srv-accent-rgb, 255, 0, 153), 0.2);
  box-shadow: 0 30px 60px rgba(46, 46, 46, 0.1);
}

.srv-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.15rem;
}

.srv-card-label {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 0.85rem;
  border-radius: 999px;
  background: rgba(46, 46, 46, 0.06);
  color: rgba(46, 46, 46, 0.78);
  font-size: 0.8rem;
  font-weight: 310;
  line-height: 1;
}

.srv-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 28px;
  padding: 0 0.8rem 0 0.7rem;
  border-radius: 999px;
  background: var(--pink);
  color: #fff;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.04em;
}

.srv-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
  animation: srv-badge-pulse 2.4s var(--ease-soft) infinite;
}

@keyframes srv-badge-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(255, 255, 255, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
  }
}

.srv-card-arrow {
  flex: 0 0 auto;
  color: rgba(46, 46, 46, 0.5);
  font-size: 1.05rem;
  line-height: 1;
  transition:
    transform var(--motion-base) var(--ease-standard),
    color var(--motion-fast) ease;
}

.srv-card-inner:hover .srv-card-arrow,
.srv-card-inner:focus-visible .srv-card-arrow {
  transform: translate(2px, -2px);
  color: var(--srv-accent, var(--pink));
}

.srv-card-title {
  margin: 0 0 0.65rem;
  color: #2e2e2e;
  font-family: var(--font-display);
  font-size: 1.85rem;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.srv-card-copy {
  margin: 0 0 1.4rem;
  color: rgba(46, 46, 46, 0.7);
  font-size: 0.95rem;
  font-weight: var(--body-copy-weight);
  line-height: 1.55;
  letter-spacing: var(--body-copy-letter-spacing);
}

/* Image placeholder — the accent block. Drop an <img> in here
   and it will cover the box. */
.srv-card-media {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  margin-top: auto;
  aspect-ratio: 1 / 1;
  border-radius: 20px;
  background: var(--srv-wash, #f0f0f2);
}

.srv-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.srv-card-media-mark {
  width: 42%;
  aspect-ratio: 1 / 1;
  border-radius: 26% 26% 26% 6%;
  background: var(--srv-accent, var(--pink));
  opacity: 0.9;
  transition: transform var(--motion-slow) var(--ease-soft);
}

.srv-card-inner:hover .srv-card-media-mark,
.srv-card-inner:focus-visible .srv-card-media-mark {
  transform: rotate(-8deg) scale(1.06);
}

/* ---- Growth Studio nav item ---- */

/* Registered so the conic-gradient angle can be animated smoothly.
   Without @property support the ring renders static. */
@property --shine-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

/* Growth Studio is the emphasised item in the Services dropdown.
   A soft pink chip carries the emphasis on its own; the shine is a
   single highlight travelling around a continuous pink stroke, so
   the border always reads as a complete ring rather than a wedge
   appearing and disappearing. */
.nav-about-subpage-new {
  position: relative;
  border-color: transparent;
  background: rgba(255, 0, 153, 0.05);
  color: var(--pink);
  font-weight: 600;
}

.nav-about-subpage-new:hover,
.nav-about-subpage-new:focus-visible {
  border-color: transparent;
  background: rgba(255, 0, 153, 0.09);
  color: var(--pink);
  box-shadow: 0 10px 22px rgba(255, 0, 153, 0.14);
}

/* The conic-gradient fills the box, then the mask punches out the
   middle so only the 1.25px ring is painted. Every stop is pink —
   the sweep only varies its brightness. */
.nav-about-subpage-new::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: 1.25px;
  border-radius: inherit;
  background: conic-gradient(
    from var(--shine-angle),
    rgba(255, 0, 153, 0.34) 0deg,
    rgba(255, 0, 153, 0.34) 46deg,
    rgba(255, 92, 188, 0.72) 84deg,
    rgba(255, 168, 219, 0.95) 104deg,
    rgba(255, 92, 188, 0.72) 124deg,
    rgba(255, 0, 153, 0.34) 165deg,
    rgba(255, 0, 153, 0.34) 360deg
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
  animation: nav-shine-rotate 5s linear infinite;
}

@keyframes nav-shine-rotate {
  to {
    --shine-angle: 360deg;
  }
}

/* Notification dot — absolutely positioned so this item stays
   exactly the same size as the other service links. */
.nav-about-subpage-new {
  position: relative;
}

.nav-about-subpage-dot {
  position: absolute;
  top: 9px;
  right: 9px;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--pink);
  box-shadow: 0 0 0 0 rgba(255, 0, 153, 0.5);
  animation: srv-badge-pulse-pink 2.6s var(--ease-soft) infinite;
}

@keyframes srv-badge-pulse-pink {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 0, 153, 0.5);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(255, 0, 153, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 0, 153, 0);
  }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- Responsive ---- */

@media (max-width: 1024px) {
  .srv-section {
    padding: 5rem 0 3.5rem;
  }

  .srv-layout {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 2.5rem;
  }

  .srv-track-wrap {
    margin-inline: calc((var(--shell) - 100vw) / 2);
  }

  .srv-track-wrap {
    margin-left: calc((var(--boxed-guide-width) - 100vw) / 2);
    scroll-padding-inline: calc((100vw - var(--boxed-guide-width)) / 2);
  }

  /* The right padding was 0, so scrolled fully right the last card's
     edge sat flush against the screen edge with no gutter at all.
     Mirroring the left gutter gives the row the same margin on both
     sides and lets it travel that bit further right. */
  .srv-track {
    padding-left: calc((100vw - var(--boxed-guide-width)) / 2);
    padding-right: calc((100vw - var(--boxed-guide-width)) / 2);
  }
}

@media (max-width: 768px) {
  .srv-section {
    padding: 4rem 0 3rem;
  }

  .srv-card {
    width: min(300px, 78vw);
  }

  /* Swiping is the affordance on a phone, and the next card's edge
     already shows there is more to come — the arrows just took up room
     under the heading. Hidden rather than removed from the markup so
     the track's own JS keeps its references. They stay on desktop,
     where there is no swipe. */
  .srv-controls {
    display: none;
  }

  .srv-card-inner {
    min-height: 430px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .srv-track-wrap {
    scroll-behavior: auto;
  }

  .srv-badge::before,
  .nav-about-subpage-dot,
  .nav-about-subpage-new::before {
    animation: none;
  }

  .srv-card-inner,
  .srv-card-media-mark,
  .srv-card-arrow {
    transition: none;
  }

  .srv-card-inner:hover {
    transform: none;
  }

  .srv-card-inner:hover .srv-card-media-mark {
    transform: none;
  }
}

/* ============================================================
   CONTACT PAGE — social proof band under the form.
   Full-bleed dark band, centred Brocar review.
   ============================================================ */

/* The panel starts full-bleed and contracts into a rounded box as
   the section scrolls in. --review-progress (0 = full bleed,
   1 = boxed) is written by the scroll handler in script.js; it
   defaults to 1 so the boxed state is what renders without JS. */
.contact-review {
  /* Same cap as the homepage case study: the band steps in a little
     rather than contracting all the way to the content rail. */
  --cr-inset-max: clamp(0.75rem, 2.75vw, 2.75rem);
  position: relative;
  margin-top: clamp(3rem, 6vw, 5.5rem);
  padding-inline: calc(
    var(--shrink-progress) *
      min(
        var(--cr-inset-max),
        max(0px, (100% - var(--boxed-guide-width))) / 2
      )
  );
  color: var(--white);
}

.contact-review-panel {
  position: relative;
  overflow: hidden;
  padding: clamp(4rem, 8vw, 6.5rem) 0;
  /* The radius ramps ~8x faster than the inset, so the corners are
     fully round almost as soon as the panel starts contracting
     rather than squaring off through the first half of the move. */
  border-radius: calc(min(var(--shrink-progress) * 8, 1) * 42px);
  background: #2e2e2e;
  will-change: border-radius;
}

.contact-review .section-shell {
  width: min(50rem, calc(100% - 3rem));
}

.contact-review-card {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 2rem;
  max-width: 50rem;
  margin: 0 auto;
  padding: 0;
  text-align: center;
}

.contact-review-logo {
  width: auto;
  height: 32px;
  object-fit: contain;
}

.contact-review-quote {
  display: grid;
  gap: 1rem;
  margin: 0;
}

.contact-review-quote p {
  margin: 0;
  color: rgba(244, 244, 244, 0.74);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  letter-spacing: var(--body-copy-letter-spacing);
}

.contact-review-quote p:first-child {
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.6vw, 1.45rem);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.02em;
}

.contact-review-source {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  padding-top: 0.5rem;
}

.contact-review-photo {
  width: 64px;
  height: 64px;
  border-radius: 999px;
  object-fit: cover;
  object-position: center 20%;
  border: 2px solid rgba(244, 244, 244, 0.24);
}

.contact-review-meta {
  display: grid;
  gap: 0.2rem;
}

.contact-review-meta strong {
  color: var(--white);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.2;
}

.contact-review-meta span {
  color: rgba(244, 244, 244, 0.6);
  font-size: 0.88rem;
  font-weight: 310;
  line-height: 1.2;
}

@media (max-width: 768px) {
  .contact-review-card {
    gap: 1.6rem;
  }

  .contact-review-logo {
    height: 26px;
  }
}


/* ------------------------------------------------------------
   Contact page CTA — same block as the homepage, minus the 3D
   scene. Collapses the space the artwork used to occupy.
   ------------------------------------------------------------ */

.contact-page .cta-section {
  margin-bottom: 0;
  padding: clamp(6rem, 11vw, 10rem) 0 clamp(3rem, 6vw, 5rem);
  border-radius: 0;
  background: transparent;
}

.contact-page .cta-shell {
  min-height: 0;
  gap: 0;
  padding-bottom: 0;
}

.contact-page .cta-copy {
  margin: 0 auto;
  transform: none;
}

/* ============================================================
   CASE STUDY — Motormoolah (homepage)
   Full-bleed dark band. Left column holds who + the lifetime
   outcome and stays put while the chronology scrolls past on the
   right, so the payoff is always on screen while you read the
   story. Reveal/counter classes are set by script.js.
   ============================================================ */

/* The panel arrives full-bleed and contracts into a rounded box as
   the section scrolls in, same mechanism as the contact page review
   (--shrink-progress, written by script.js, defaults to the boxed
   state so it degrades to a static rounded box without JS).
   The panel only insets as far as the content rail plus its own
   gutter, so the headline stays aligned to the rail throughout. */
.cs-section {
  --cs-gutter: clamp(1.25rem, 3vw, 3rem);
  /* How far the box is allowed to pull in from the viewport edge.
     Capped so it only steps in a little rather than shrinking all
     the way to the content rail. */
  --cs-inset-max: clamp(0.75rem, 2.75vw, 2.75rem);
  position: relative;
  margin-bottom: clamp(3rem, 6vw, 5.5rem);
  padding: clamp(5rem, 9vw, 8rem) 0;
  color: var(--white);
}

/* The dark box is its own absolutely-positioned layer, so the panel
   can contract and round without reflowing the section's content on
   every scroll frame. The content sits on the rail throughout; the
   box never insets past the rail plus its gutter. */
.cs-panel {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(
    var(--shrink-progress) *
      min(
        var(--cs-inset-max),
        max(0px, (100% - var(--boxed-guide-width) - 2 * var(--cs-gutter))) / 2
      )
  );
  right: calc(
    var(--shrink-progress) *
      min(
        var(--cs-inset-max),
        max(0px, (100% - var(--boxed-guide-width) - 2 * var(--cs-gutter))) / 2
      )
  );
  border-radius: calc(min(var(--shrink-progress) * 8, 1) * 42px);
  background: #2e2e2e;
  pointer-events: none;
}

.cs-section .section-shell {
  position: relative;
  z-index: 1;
  width: min(var(--boxed-guide-width), 100%);
  margin-inline: auto;
}

/* On a phone the inset above always resolved to 0, so the box stayed
   edge to edge however far the shrink ran: it is computed from the room
   left once the content rail and its gutters are placed, and at 375px
   the rail (100vw - 2.5rem = 335px) plus 2x20px of gutter comes to
   exactly the viewport. No spare, no inset.

   Fixed by narrowing the rail rather than by overriding the inset
   formula, so the box steps in and the copy still clears its edge by a
   proper margin (20px each side at 375px). */
@media (max-width: 768px) {
  .cs-panel {
    left: calc(var(--shrink-progress) * 0.75rem);
    right: calc(var(--shrink-progress) * 0.75rem);
    border-radius: calc(min(var(--shrink-progress) * 8, 1) * 28px);
  }

  .cs-section .section-shell {
    width: calc(100% - 4rem);
  }
}

.cs-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  column-gap: clamp(2.5rem, 5vw, 5.5rem);
  align-items: start;
}

/* ---- Left column ---- */

.cs-head {
  display: grid;
  justify-items: start;
  gap: 0.95rem;
  position: sticky;
  top: calc(var(--nav-height) + 1.25rem);
}

.cs-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 32px;
  margin: 0;
  padding: 0 1.2rem;
  border-radius: 36px;
  border: 0.5px solid rgba(244, 244, 244, 0.42);
  color: rgba(244, 244, 244, 0.86);
  font-size: 16px;
  font-weight: 310;
  line-height: 18px;
}

/* Motormoolah's mark is supplied white on transparent, so it sits
   directly on the dark band. */
.cs-logo {
  width: auto;
  height: clamp(2.1rem, 3vw, 2.8rem);
  margin: 0.2rem 0 0.1rem;
  object-fit: contain;
}

.cs-heading {
  margin: 0;
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(2rem, 3vw, 42px);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.035em;
}

.cs-heading-line {
  display: block;
  font: inherit;
  letter-spacing: inherit;
}

.cs-intro {
  max-width: 36ch;
  margin: 0;
  color: rgba(244, 244, 244, 0.72);
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  letter-spacing: var(--body-copy-letter-spacing);
}

/* ---- Lifetime figures (left column, under the intro) ---- */

.cs-summary {
  width: 100%;
  margin-top: 0.45rem;
  padding-top: 1.15rem;
  border-top: 1px solid rgba(244, 244, 244, 0.16);
}

.cs-summary-label {
  margin: 0 0 0.9rem;
  color: rgba(244, 244, 244, 0.5);
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cs-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.15rem 1.6rem;
  margin: 0;
}

.cs-stat {
  display: grid;
  gap: 0.45rem;
}

.cs-stat:nth-child(even) {
  padding-left: 1.6rem;
  border-left: 1px solid rgba(244, 244, 244, 0.14);
}

/* The label is a caption, not a peer of the figure: small, tracked and
   uppercase, it steps out of the way so the number reads first. Same
   treatment as .cs-summary-label above, so the block reads as one set
   of instruments rather than four stray lines. */
.cs-stat dt {
  color: rgba(244, 244, 244, 0.5);
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: 0.085em;
  text-transform: uppercase;
}

.cs-stat dd {
  display: grid;
  gap: 0.2rem;
  margin: 0;
}

.cs-stat-figure {
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(2.05rem, 2.75vw, 2.55rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.045em;
}

.cs-stat-note {
  color: rgba(244, 244, 244, 0.56);
  font-size: 0.8rem;
  font-weight: 310;
  line-height: 1.2;
}

/* ---- Timeline ---- */

.cs-timeline {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cs-milestone {
  position: relative;
  padding: 0 0 clamp(2.4rem, 3.6vw, 3.25rem) 2.15rem;
}

.cs-milestone:last-child {
  padding-bottom: 0;
}

/* Connector line — drawn downward as each milestone arrives. */
.cs-milestone::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0.6rem;
  bottom: 0;
  width: 1px;
  background: rgba(244, 244, 244, 0.18);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 900ms var(--ease-soft) 120ms;
}

.cs-milestone:last-child::before {
  display: none;
}

/* Dot */
.cs-milestone::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0.3rem;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: rgba(244, 244, 244, 0.35);
  transform: scale(0);
  transition: transform 460ms var(--ease-standard);
}

.cs-milestone.is-figure::after {
  background: var(--pink);
}

/* The month worth shouting about gets a ring. */
.cs-milestone.is-peak::after {
  box-shadow: 0 0 0 4px rgba(255, 0, 153, 0.22);
}

/* The closing card is a nod to what comes next rather than a result:
   a hollow dot, and a connector that fades out instead of stopping
   dead at the end of the run. */
.cs-milestone.is-next {
  padding-bottom: clamp(2.4rem, 3.6vw, 3.25rem);
}

.cs-milestone.is-next::before {
  display: block;
  background: linear-gradient(
    180deg,
    rgba(244, 244, 244, 0.18),
    rgba(244, 244, 244, 0)
  );
}

.cs-milestone.is-next::after {
  background: transparent;
  box-shadow: inset 0 0 0 2px rgba(255, 0, 153, 0.7);
}

.cs-milestone.is-in::before {
  transform: scaleY(1);
}

.cs-milestone.is-in::after {
  transform: scale(1);
}

.cs-milestone-body {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 620ms var(--ease-soft),
    transform 620ms var(--ease-soft);
}

.cs-milestone.is-in .cs-milestone-body {
  opacity: 1;
  transform: none;
}

.cs-milestone-date {
  margin: 0 0 0.55rem;
  color: rgba(244, 244, 244, 0.5);
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cs-milestone-figure {
  margin: 0 0 0.2rem;
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(2.3rem, 3.4vw, 3.1rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.035em;
}

.cs-milestone-title {
  margin: 0 0 0.5rem;
  color: var(--white);
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
}

/* Milestones without a headline number lead on the title instead,
   so the rhythm doesn't sag where there's no figure to show. */
.cs-milestone:not(.is-figure) .cs-milestone-title {
  font-size: clamp(1.5rem, 2vw, 1.8rem);
  font-weight: 800;
  letter-spacing: -0.03em;
}

.cs-milestone-copy {
  max-width: 46ch;
  margin: 0;
  color: rgba(244, 244, 244, 0.74);
  font-size: 1rem;
  font-weight: var(--body-copy-weight);
  line-height: 1.6;
  letter-spacing: var(--body-copy-letter-spacing);
}

/* ---- Reveals for the left column ---- */

[data-cs-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 620ms var(--ease-soft),
    transform 620ms var(--ease-soft);
}

[data-cs-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* ---- Responsive ---- */

@media (max-width: 1024px) {
  .cs-layout {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(2.5rem, 5vw, 3.5rem);
  }

  .cs-head {
    position: static;
  }

  .cs-intro {
    max-width: 52ch;
  }

  .cs-stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .cs-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.35rem 1rem;
  }

  .cs-milestone {
    padding-left: 1.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cs-milestone::before,
  .cs-milestone::after,
  .cs-milestone-body,
  [data-cs-reveal] {
    transition: none;
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   SECTION BROW PILLS
   One size for every section brow so they can't drift apart:
   Services, Case study, Our Products. Slightly smaller than the
   original 16px/32px. Colour is the only thing that varies, by
   whether the pill sits on a light or dark section.
   ============================================================ */

.products-pill,
.srv-pill,
.cs-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-height: 29px;
  padding: 0 1rem;
  border-radius: 999px;
  border-width: 0.5px;
  border-style: solid;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 310;
  line-height: 1;
}

.products-pill,
.srv-pill {
  border-color: rgba(46, 46, 46, 0.88);
  color: #2e2e2e;
}

.cs-pill {
  border-color: rgba(244, 244, 244, 0.42);
  color: rgba(244, 244, 244, 0.86);
}

/* ============================================================
   TEXT WRAPPING
   text-wrap: pretty stops the browser leaving a single word on the
   last line of a paragraph. Non-breaking spaces in the markup are
   the guaranteed fallback where a specific orphan must never
   appear (browsers without support just wrap as before).
   ============================================================ */

.srv-summary,
.srv-card-copy,
.cs-intro,
.cs-milestone-copy,
.contact-review-quote p,
.faq-copy p,
.faq-answer p,
.contact-copy p,
.products-overview,
.product-copy,
.reveal-text {
  text-wrap: pretty;
}

/* ============================================================
   SHOWREEL → SERVICES SPACING
   Tightens the void between the film and the services section.
   body.page-v2 prefix is needed to out-specify the padding on
   .video-reveal in styles-staging-overrides.css, which loads after
   this file.
   ============================================================ */

body.page-v2 .video-reveal {
  padding-bottom: clamp(1.75rem, 3.5vh, 3rem);
}

.srv-section {
  padding-top: 3.5rem;
}

@media (max-width: 1024px) {
  .srv-section {
    padding-top: 3rem;
  }
}

@media (max-width: 768px) {
  body.page-v2 .video-reveal {
    padding-bottom: clamp(1.25rem, 2.5vh, 2rem);
  }

  /* On phones the film card is only ~190px tall but the sticky stage
     is a full viewport, so centring left ~330px of dead air under
     it. A shorter stage closes that without touching the morph — the
     falling dot is already disabled below 720px. */
  body.page-v2 .video-reveal-pin {
    height: 62vh;
  }

  .srv-section {
    padding-top: 2.5rem;
  }
}

/* ============================================================
   FAQ — floating 3D asterisk
   Sits low on the left, under the copy column, drifting slowly.
   Decorative only: aria-hidden, no pointer events, and it never
   overlaps the accordion. Hidden on small screens where there is
   no clear space beside the content.
   ============================================================ */

.faq-main {
  position: relative;
}

.faq-floater {
  position: absolute;
  /* Pushed out past the right edge — the section clips its overflow,
     so the object bleeds off the frame deliberately. */
  right: clamp(-3.5rem, -2.25vw, -0.75rem);
  bottom: clamp(3.5rem, 5.5vw, 6rem);
  width: clamp(10rem, 16vw, 15.5rem);
  height: auto;
  /* Behind everything in the section — the shell sits on z-index 2. */
  z-index: 0;
  pointer-events: none;
  user-select: none;
  animation: faq-floater-drift 17s ease-in-out infinite;
  transform-origin: center center;
  will-change: transform;
}

@keyframes faq-floater-drift {
  0%,
  100% {
    transform: translate3d(0, 0, 0) rotate(-16deg) scale(1);
  }
  20% {
    transform: translate3d(-34px, -46px, 0) rotate(-6deg) scale(1.04);
  }
  40% {
    transform: translate3d(-8px, -78px, 0) rotate(9deg) scale(1.07);
  }
  60% {
    transform: translate3d(30px, -54px, 0) rotate(18deg) scale(1.04);
  }
  80% {
    transform: translate3d(40px, -20px, 0) rotate(6deg) scale(1);
  }
}

/* Keep the copy above the object. */
.faq-main .section-shell {
  position: relative;
  z-index: 2;
}

/* Homepage FAQ — reuses the FAQ page layout, sized as a normal section. */
.faq-home {
  min-height: 0;
  padding: clamp(5rem, 11vh, 8.5rem) 0 clamp(2.25rem, 5vh, 3.75rem);
}

/* Body copy matches the rest of the homepage. */
.faq-copy p,
.faq-answer p {
  font-size: var(--body-copy-size);
  font-weight: var(--body-copy-weight);
  line-height: var(--body-copy-line-height);
  color: rgba(46, 46, 46, 0.68);
}

.faq-copy p {
  max-width: 24rem;
}

/* Anchor the asterisk from the top so opening an answer (which grows the
   section) never moves it. */
.faq-home .faq-floater {
  top: clamp(14rem, 24vw, 22rem);
  bottom: auto;
}

.faq-copy h2 {
  max-width: 7.6em;
  font-size: clamp(3rem, 5vw, 5.05rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

@media (max-width: 979px) {
  .faq-floater {
    right: clamp(-2.5rem, -2vw, -0.5rem);
    bottom: clamp(2rem, 4vw, 3.5rem);
    width: clamp(8rem, 18vw, 11rem);
  }
}

@media (max-width: 720px) {
  /* .faq-main clips on both axes, which kept the object inside the
     section. Clipping x only still stops any horizontal bleed from the
     negative right offset (clip is the one value that may pair with
     visible), while letting it hang past the section's bottom edge and
     under the footer. */
  .faq-main {
    overflow-x: clip;
    overflow-y: visible;
  }

  /* Was display:none. Sits low enough to run behind the last couple of
     question boxes and carry on under the top of the footer; z-index 0
     against the shell's z-index 2 keeps it behind them, and the footer
     paints over it as a later sibling. */
  .faq-floater {
    display: block;
    right: clamp(-3rem, -6vw, -1rem);
    bottom: -9rem;
    width: clamp(9rem, 46vw, 13rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .faq-floater {
    animation: none;
  }
}

/* ============================================================
   CASE STUDY — cursor-following media
   One square follows the pointer while a milestone is hovered.
   Shows data-cs-media if the milestone has one, otherwise the
   placeholder. Pointer devices only; skipped under reduced motion.
   ============================================================ */

.cs-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  border-radius: 6px;
  border: 1px solid rgba(244, 244, 244, 0.16);
  background: rgba(244, 244, 244, 0.07);
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.28);
  overflow: hidden;
  pointer-events: none;
  transform: translate3d(-50%, -50%, 0);
  /* Uncovered by a mask sweeping left to right rather than scaled or
     faded in — the same left-to-right motion as the marker highlight
     further up the page. Short: a follower that lingers reads as lag. */
  clip-path: inset(0 100% 0 0 round 6px);
  visibility: hidden;
  transition:
    clip-path 210ms var(--ease-standard),
    visibility 210ms var(--ease-standard);
  will-change: translate, clip-path;
}

.cs-cursor.is-visible {
  visibility: visible;
  clip-path: inset(0 0 0 0 round 6px);
}

/* Leaving is quicker than arriving, and wipes back the way it came. */
.cs-cursor:not(.is-visible) {
  transition:
    clip-path 130ms var(--ease-standard),
    visibility 130ms var(--ease-standard);
}

/* The box takes the picture's shape rather than the other way round:
   equal caps on width and height mean a landscape image is limited by
   its width and a portrait one by its height, so each keeps its own
   proportions while occupying a similar area. */
.cs-cursor-img {
  display: block;
  width: auto;
  height: auto;
  max-width: clamp(10rem, 15vw, 15rem);
  max-height: clamp(10rem, 15vw, 15rem);
  opacity: 0;
}

/* Only the placeholder needs a shape of its own. */
.cs-cursor:not(.has-image) {
  width: clamp(9rem, 12vw, 12rem);
  aspect-ratio: 1 / 1;
}

.cs-cursor.has-image .cs-cursor-label {
  display: none;
}

.cs-cursor.has-image .cs-cursor-img {
  opacity: 1;
}

.cs-cursor-label {
  color: rgba(244, 244, 244, 0.62);
  font-family: var(--font-display);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.cs-cursor.has-image .cs-cursor-label {
  opacity: 0;
}

/* The hovered milestone lifts slightly out of the list. */
.cs-milestone-body {
  transition:
    opacity 620ms var(--ease-soft),
    transform 620ms var(--ease-soft),
    color 200ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .cs-milestone.is-in .cs-milestone-body {
    transition:
      opacity 620ms var(--ease-soft),
      transform 260ms var(--ease-standard);
  }

  .cs-milestone[data-cs-media]:hover .cs-milestone-body {
    transform: translateX(6px);
  }

  .cs-milestone[data-cs-media] {
    cursor: default;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cs-cursor {
    display: none;
  }

  .cs-milestone[data-cs-media]:hover .cs-milestone-body {
    transform: none;
  }
}

/* ============================================================
   CASE STUDY — typographic pass on the milestone titles
   The titles were carrying display tracking (-0.02em / -0.03em) at
   text sizes, which closes up the counters and makes runs like
   "500+" and "SEO" collide. Tracking now scales inversely with
   size: near-zero at 18px, tighter only where the type is set
   large enough to need optical compensation. Kerning pairs and
   standard ligatures are switched on explicitly rather than left
   to the browser default.
   ============================================================ */

.cs-heading,
.cs-milestone-title,
.cs-milestone-figure,
.cs-milestone-date,
.cs-stat-figure,
.cs-summary-label {
  font-kerning: normal;
  font-feature-settings: "kern" 1, "liga" 1;
}

/* Text-size titles: effectively no tracking, a touch more leading. */
.cs-milestone-title {
  letter-spacing: -0.005em;
  line-height: 1.3;
}

/* Display-size titles (the milestones with no headline number) can
   carry real negative tracking without losing their counters. */
.cs-milestone:not(.is-figure) .cs-milestone-title {
  letter-spacing: -0.022em;
  line-height: 1.15;
}

/* Figures mix currency marks, numerals and a plus sign — pulled back
   from -0.045em so "£2.44" and "900+" don't crowd at the joins. */
.cs-milestone-figure,
.cs-stat-figure {
  letter-spacing: -0.032em;
}

/* The uppercase labels are the one place that wants positive
   tracking — caps set solid need opening up, not closing. */
.cs-milestone-date,
.cs-summary-label {
  letter-spacing: 0.09em;
}

/* ============================================================
   CASE STUDY — tracking across the rest of the section
   The whole band is reversed out (light type on dark), which
   optically thickens and tightens the letterforms. Small text and
   low-contrast text get a touch of positive tracking to give it
   back; the display sizes keep their negative tracking, because at
   47px the letterforms need closing up, not opening.
   ============================================================ */

.cs-intro,
.cs-milestone-copy,
.cs-stat dt,
.cs-stat-note,
.cs-cursor-label,
.cs-pill {
  font-kerning: normal;
  font-feature-settings: "kern" 1, "liga" 1;
}

/* Reversed body copy — a hair open. */
.cs-intro,
.cs-milestone-copy {
  letter-spacing: 0.004em;
}

/* Small, low-contrast supporting text needs the most help. */
.cs-stat dt,
.cs-stat-note {
  letter-spacing: 0.011em;
}

.cs-pill {
  letter-spacing: 0.012em;
}

/* Display heading: hairline tighter now kerning pairs are on, so the
   "M" and the comma close up properly. */
.cs-heading {
  letter-spacing: -0.038em;
}

/* Short laptop viewports: the left column is sticky, so the whole
   stack — headline, intro and the four figures — has to fit between
   the nav and the bottom of the screen. On a 700px-tall window the
   figures were landing just past the fold, which made you scroll to
   read numbers that are meant to be read alongside the timeline.
   Tighten the rhythm rather than drop anything out. */
@media (max-height: 780px) {
  .cs-head {
    top: calc(var(--nav-height) + 0.5rem);
    gap: 0.7rem;
  }

  .cs-summary {
    padding-top: 0.8rem;
  }

  .cs-summary-label {
    margin-bottom: 0.7rem;
  }

  .cs-stats {
    gap: 0.85rem 1.6rem;
  }
}

/* ============================================================
   PRODUCTS — room for the card's shadow
   The section clips its overflow (to contain the floating racket),
   which was cutting the card's 80px shadow off at 49px and leaving
   a hard line across the page. The extra bottom padding gives the
   shadow room; the matching negative margin hands the space back so
   nothing below moves.
   ============================================================ */

body.page-v2 .products-section.section-light {
  padding-bottom: 5.5rem;
  margin-bottom: -2.65rem;
}

/* Display figures use proportional numerals. Tabular figures exist to
   line numbers up in columns and give every digit the same advance —
   which leaves a "1" floating in a slot far wider than it needs, so
   "516" reads with a hole in the middle. Nothing here is a column of
   numbers, so proportional is correct. */
.cs-milestone-figure,
.cs-stat-figure {
  font-variant-numeric: proportional-nums;
  font-feature-settings: "kern" 1, "liga" 1, "pnum" 1;
}

/* ============================================================
   TRAVELLING HIGHLIGHT — the line already crossed
   Holds the marker on a line the bar has finished, so both closing
   lines read as highlighted at once before the bar collapses back
   into a dot. Same fill and blend as the bar itself.
   ============================================================ */

.travelling-highlight {
  position: fixed;
  left: 0;
  top: 0;
  width: var(--hl-width, 0px);
  height: var(--hl-height, 0px);
  border-radius: 4px;
  background: color-mix(in srgb, var(--pink) 13%, #ffeaf5);
  mix-blend-mode: multiply;
  transform: translate3d(var(--hl-x, 0px), var(--hl-y, 0px), 0)
    translate(-50%, -50%);
  opacity: var(--hl-opacity, 0);
  z-index: 5;
  pointer-events: none;
  will-change: transform, width, opacity;
}

@media (prefers-reduced-motion: reduce) {
  .travelling-highlight {
    display: none;
  }
}

/* ============================================================
   SERVICES CARDS — staggered rise
   Each card lifts into place from below, straightening out of a
   slight tilt, one after another rather than as a block. Pivoting
   from the base makes the rotation read as the card settling onto
   the row instead of spinning in mid-air.
   ============================================================ */

.srv-card {
  opacity: 0;
  transform: translate3d(0, 70px, 0) rotate(var(--srv-tilt, -5deg)) scale(1.06);
  transform-origin: 50% 100%;
  transition:
    opacity 700ms var(--ease-soft),
    transform 950ms var(--ease-soft);
  transition-delay: var(--srv-delay, 0ms);
  will-change: transform, opacity;
}

.srv-card.is-in {
  opacity: 1;
  transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
}

/* Alternating tilts so the row looks dealt rather than stamped. */
.srv-card:nth-child(1) {
  --srv-tilt: -5deg;
  --srv-delay: 0ms;
}

.srv-card:nth-child(2) {
  --srv-tilt: 4deg;
  --srv-delay: 130ms;
}

.srv-card:nth-child(3) {
  --srv-tilt: -3.5deg;
  --srv-delay: 260ms;
}

.srv-card:nth-child(4) {
  --srv-tilt: 5deg;
  --srv-delay: 390ms;
}

/* A tilted card reaches higher than an upright one — give the track
   the headroom so the corners aren't clipped on the way in. */
.srv-track {
  padding-top: 2.25rem;
}

.srv-track-wrap {
  margin-top: -2.25rem;
}

@media (prefers-reduced-motion: reduce) {
  .srv-card {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* ============================================================
   WATCH THE FILM — glowing pink stroke
   A gradient stroke travels around the button with a soft glow
   behind it, to pull the eye to the one thing on the film that is
   clickable. body.page-v2 prefix is needed to out-specify the
   button's own rule in styles-staging-overrides.css, which loads
   after this file.

   The glow is a box-shadow rather than a blurred pseudo-element:
   a negative-z-index child paints above its parent's background as
   soon as the parent makes a stacking context — which this button
   does whenever its opacity is mid-fade — so a pseudo-element halo
   washes over the label instead of sitting behind it.
   ============================================================ */

body.page-v2 .video-reveal-play {
  position: absolute;
  box-shadow:
    0 0 0 1px rgba(255, 0, 153, 0.25),
    0 0 16px 1px rgba(255, 0, 153, 0.5),
    0 0 34px 6px rgba(255, 0, 153, 0.28);
  animation: play-glow-pulse 2.8s ease-in-out infinite;
  transition:
    background-color 0.3s ease,
    transform 0.3s ease,
    box-shadow 0.3s ease;
}

/* The stroke: a conic gradient filling the box with the middle masked
   out, so only the rim paints. Two white specular passes against pink
   read as light travelling around a polished edge rather than a flat
   pink outline.

   It sits just OUTSIDE the button (negative inset) on purpose — the
   button's own fill is near-white, so a white highlight drawn on the
   button's edge would disappear into it. Out here it plays against
   the film instead, where both the white and the pink read. */
body.page-v2 .video-reveal-play::before {
  content: "";
  position: absolute;
  inset: -2.5px;
  padding: 1.75px;
  border-radius: 999px;
  background: conic-gradient(
    from var(--shine-angle),
    rgba(255, 255, 255, 0.32) 0deg,
    rgba(255, 0, 153, 0.9) 38deg,
    rgba(255, 255, 255, 0.98) 66deg,
    rgba(255, 0, 153, 0.9) 96deg,
    rgba(255, 255, 255, 0.3) 148deg,
    rgba(255, 255, 255, 0.22) 196deg,
    rgba(255, 0, 153, 0.62) 244deg,
    rgba(255, 255, 255, 0.92) 280deg,
    rgba(255, 0, 153, 0.62) 314deg,
    rgba(255, 255, 255, 0.32) 360deg
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
  animation: nav-shine-rotate 4.5s linear infinite;
}

@keyframes play-glow-pulse {
  0%,
  100% {
    box-shadow:
      0 0 0 1px rgba(255, 0, 153, 0.22),
      0 0 14px 1px rgba(255, 0, 153, 0.42),
      0 0 30px 5px rgba(255, 0, 153, 0.22);
  }
  50% {
    box-shadow:
      0 0 0 1px rgba(255, 0, 153, 0.3),
      0 0 20px 2px rgba(255, 0, 153, 0.62),
      0 0 44px 9px rgba(255, 0, 153, 0.34);
  }
}

body.page-v2 .video-reveal-play:hover {
  box-shadow:
    0 0 0 1px rgba(255, 0, 153, 0.36),
    0 0 24px 3px rgba(255, 0, 153, 0.7),
    0 0 52px 11px rgba(255, 0, 153, 0.4);
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  body.page-v2 .video-reveal-play,
  body.page-v2 .video-reveal-play::before {
    animation: none;
  }
}


/* ============================================================
   SETTLE — boxes arrive a touch oversized and settle to size
   Any [data-settle] box lands slightly larger than its resting
   size and eases down to it, with a small overshoot so it reads
   as settling rather than sliding. Uses the standalone `scale`
   property, not `transform`, so it layers cleanly over reveals
   that already animate transform. Without JS the box simply
   sits at --settle-from, which is harmless.
   ============================================================ */

[data-settle] {
  scale: var(--settle-from, 1.06);
  transition: scale 900ms var(--ease-settle);
  transition-delay: var(--settle-delay, 0ms);
  will-change: scale;
}

[data-settle].is-settled {
  scale: 1;
}

/* Stagger a run of boxes so they settle one after another. */
[data-settle]:nth-of-type(2) {
  --settle-delay: 70ms;
}

[data-settle]:nth-of-type(3) {
  --settle-delay: 140ms;
}

[data-settle]:nth-of-type(4) {
  --settle-delay: 210ms;
}

[data-settle]:nth-of-type(5) {
  --settle-delay: 280ms;
}

[data-settle]:nth-of-type(n + 6) {
  --settle-delay: 350ms;
}

@media (prefers-reduced-motion: reduce) {
  [data-settle] {
    scale: 1;
    transition: none;
  }
}


/* ==========================================================
   MOBILE TYPE SCALE
   One place, last in the cascade, because these sizes were set
   across several competing blocks (a 768px rule for the section
   headings sat before a base rule that outranked it on source
   order, so .srv-heading still resolved to 40px).

   Measured at 375px before this block: hero 60, section headings
   40 / 36 / 32, card headings 29.6 / 24, CTA 34.5. That is a
   desktop scale shrunk a little, not a phone scale — the section
   headings alone ran a third larger than the 28-30px a 375px
   screen normally carries. Body copy was already right at 16px
   and is deliberately left alone.
   ========================================================== */
@media (max-width: 720px) {
  /* The hero headline is deliberately oversized and is NOT part of this
     scale — it keeps its own clamp() further up the file. */

  .srv-heading,
  .products-heading,
  .cs-heading {
    font-size: clamp(1.75rem, 8vw, 2rem);
    line-height: 1.08;
  }

  /* Three lines: "If you're ready to" / "build something" /
     "that's <word>". Moving "that's" down to join the cycling word
     changed which line is widest — it was "build something that's" at
     9.19x the font-size, now it is "that's built to last." at 7.23x, so
     the same width carries type ~27% larger. */
  /* Halfway between the 9.2vw it was and the 11.5vw the three-line
     split allowed — 11.5 read as oversized on a phone. */
  .cta-type-heading {
    font-size: clamp(1.9rem, 10.3vw, 3rem);
  }

  .reveal-text-intro .reveal-text {
    font-size: clamp(1.6rem, 7.4vw, 1.85rem);
    line-height: 1.25;
  }

  .srv-card-title,
  .product-title {
    font-size: 1.375rem;
    line-height: 1.18;
  }

  .cs-milestone h3 {
    font-size: 1.25rem;
    line-height: 1.2;
  }
}


/* ==========================================================
   MOBILE SECTION RHYTHM
   The whitespace between blocks was 60 / 48 / 123 / 142 / 88px —
   a 3x spread, because each section carried its own padding and a
   couple of legacy negative margins pulled neighbours together on
   top of that. One 80px gap everywhere instead.

   Where a section is a coloured box (case studies, footer) the whole
   gap comes from the plain section beside it, since the box's own
   padding is interior and reads as part of the box.
   ========================================================== */
@media (max-width: 720px) {
  /* These carry body.page-v2 and the section-light class deliberately:
     the per-section spacing they replace is set at that specificity
     elsewhere in the file, so a bare .products-section rule loses no
     matter how late it appears. */
  /* This boundary is the exception to the 80px rhythm. The film is
     centred in a 100vh sticky pin, so ~160px of that pin sits below it
     before the section even ends — the gap you see is that 160 plus
     whatever padding is added here. Trimmed to bring the perceived gap
     down without touching the pin, which has to stay 100vh for the
     morph's progress maths to stay in sync. */
  body.page-v2 .video-reveal {
    padding-bottom: 0.5rem;
  }

  body.page-v2 .srv-section.section-light {
    padding-top: 1.5rem;
    padding-bottom: 5rem;
  }

  body.page-v2 .cs-section {
    margin-bottom: 2.5rem;
  }

  /* The 80px gap between these two is split unevenly on purpose. The
     nav is fixed and sits 11-75px down the viewport, and the CTA
     artwork used to start 57px into its section — so whenever the
     section top reached the top of the screen, the nav covered the top
     of the collage (the pink ball and the reaching arm). Pushing the
     CTA's own padding to 68px puts the artwork 85px in, clear of the
     nav, and taking the difference off the products section keeps the
     gap between them at the same 80px as everywhere else. */
  body.page-v2 .products-section.section-light {
    padding-top: 2.5rem;
    padding-bottom: 0.75rem;
    margin-bottom: 0;
    /* The card inside casts a 0 26px 54px shadow, reaching ~80px below
       itself — but this section is overflow:hidden and ends 15px under
       the card, so the shadow was being sliced off square and read as a
       hard rule across the page. Nothing here needs clipping now that
       the showcase track is minmax(0,1fr), so the shadow is simply left
       to fade out across the boundary. */
    overflow: visible;
  }

  body.page-v2 .cta-section.section-light {
    padding-top: 4.25rem;
    padding-bottom: 5rem;
    /* Transparent, not the page colour. The products card above casts a
       0 26px 54px shadow that reaches ~80px below it — further than the
       12px of padding under it — so this section's opaque background was
       painting over the shadow from its own top edge down and slicing it
       into a hard horizontal line. The colour was identical to the page
       behind it, so dropping it changes nothing except letting the
       shadow fade out properly. */
    background: transparent;
  }
}


/* ==========================================================
   SERVICES INTRO — centred on mobile
   ========================================================== */
@media (max-width: 720px) {
  .srv-intro {
    justify-items: center;
    text-align: center;
  }

  .srv-pill {
    justify-self: center;
  }
}

/* ============================================================
   NAV SUBMENU LINKS
   The Services sub-pages are real links now, so the top-level
   ".nav-links a" rules (fixed widths by position, 70px height,
   nowrap, the hover dot, the light-on-dark colour) reach them as
   well. Put them back to the submenu-item look they had as
   buttons. Specificity has to clear
   body[data-nav-theme="dark"] .nav-menu a:not(.nav-cta).
   The panel stays white in both nav themes, so the text stays dark.
   ============================================================ */
body .site-header .nav-links a.nav-about-subpage {
  display: block;
  width: auto;
  min-height: 0;
  padding: 0.7rem 0.85rem;
  overflow: visible;
  color: #2e2e2e;
  font-size: 0.86rem;
  line-height: 1.2;
  white-space: normal;
  text-align: left;
  transition:
    transform var(--motion-base) var(--ease-standard),
    background-color var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    box-shadow var(--motion-base) ease;
}

body .site-header .nav-links a.nav-about-subpage::after {
  content: none;
}

body .site-header .nav-links a.nav-about-subpage:hover,
body .site-header .nav-links a.nav-about-subpage:focus-visible {
  color: #1a1a1a;
}

body .site-header .nav-links a.nav-about-subpage-new,
body .site-header .nav-links a.nav-about-subpage-new:hover,
body .site-header .nav-links a.nav-about-subpage-new:focus-visible,
body .site-header .nav-links a.nav-about-subpage[aria-current="page"] {
  color: var(--pink);
}

body .site-header .nav-links a.nav-about-subpage[aria-current="page"] {
  border-color: rgba(255, 0, 153, 0.24);
  background: #fff;
}

@media (max-width: 1240px) {
  body .site-header .nav-links a.nav-about-subpage {
    padding: 0.8rem 0.95rem;
    font-size: 0.95rem;
  }
}

/* Services dropdown on desktop: six sub-pages in two columns
   beside the photo, rather than one tall stack. Below 1241px the
   menu is the stacked mobile list, which keeps one column. */
@media (min-width: 1241px) {
  .site-header .nav-services-wrap .nav-about-panel {
    width: clamp(31rem, 40vw, 34rem);
    grid-template-columns: minmax(7rem, 0.72fr) minmax(0, 1.6fr);
  }

  .site-header .nav-services-wrap .nav-about-links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    align-content: stretch;
  }

  body .site-header .nav-links .nav-services-wrap a.nav-about-subpage {
    display: flex;
    align-items: center;
    justify-content: flex-start;
  }
}


/* Contact page: the man on the rocket. A tall, narrow cut-out, so it is
   sized by its height rather than the wide width the old artwork used. */
.contact-object.contact-rocket {
  top: calc(54% - 20px);
  left: calc((100vw - var(--boxed-guide-width)) / -2 + 7rem);
  width: clamp(11rem, 16vw, 15.5rem);
  opacity: 1;
  filter: drop-shadow(0 24px 28px rgba(46, 46, 46, 0.18));
  transform: translateY(-20%);
}

@media (max-width: 1024px) {
  .contact-object.contact-rocket {
    top: calc(56% - 20px);
    left: 50%;
    width: min(13rem, 38vw);
    opacity: 1;
    transform: translate(-50%, -12%);
  }
}

@media (max-width: 768px) {
  .contact-object.contact-rocket {
    grid-area: object;
    top: 0;
    left: auto;
    width: min(12rem, 52vw);
    margin: 0.25rem auto 0;
    transform: none;
  }
}


/* ============================================================
   CONTACT: OFFICE STICKER
   The office (REB'S corner) as a big die-cut sticker in place of the
   hero artwork, peeling like the HR sticker on the team page
   (company-pages.css, .cp-join). White stroke baked into the image,
   made in ChatGPT from the office photo.
   It slaps on as the page loads, then the top corner slowly peels
   back. The peel works like the team one: .contact-building-fold is
   turned so its right-hand side points up; the stuck sticker is
   clipped --cb-fold% short of that side, and a copy, clipped to the
   strip past the fold, is mirrored back across it and turned white,
   so the flap is the building's outline in sticker backing.
   .motion-reveal owns transform on .contact-object, so all motion
   lives on the children.
   ============================================================ */
@property --cb-lift {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --cb-wiggle {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

.contact-object.contact-building {
  top: calc(54% - 70px);
  left: calc((100vw - var(--boxed-guide-width)) / -2 + 14rem);
  width: clamp(20rem, 30vw, 29rem);
  opacity: 1;
  filter: none;
  transform: translateY(-20%);
}

.contact-building-sticker {
  --cb-fold: calc(11 + var(--cb-lift) * 6 + var(--cb-wiggle));
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  container-type: inline-size;
  rotate: 12deg;
  /* One soft shadow on the whole sticker, flap included. A filter on
     the clipped layers inside gets cut off by their clip-path. */
  filter: drop-shadow(0 6px 10px rgba(46, 46, 46, 0.12));
  animation:
    contact-building-on 700ms cubic-bezier(0.5, 1.8, 0.62, 1) 300ms both,
    contact-building-peel 1100ms cubic-bezier(0.33, 0, 0.2, 1) 900ms both;
}

@keyframes contact-building-on {
  from {
    opacity: 0;
    scale: 1.12;
    rotate: 22deg;
  }
  to {
    opacity: 1;
    scale: 1;
    rotate: 12deg;
  }
}

@keyframes contact-building-peel {
  from { --cb-lift: 0; }
  to { --cb-lift: 1; }
}

@keyframes contact-building-wiggle {
  0%,
  100% { --cb-wiggle: 0; }
  50% { --cb-wiggle: 2.6; }
}

.contact-building-fold {
  position: absolute;
  inset: 0;
  transform: rotate(-90deg);
}

.contact-building-unpeeled,
.contact-building-peeled {
  position: absolute;
  inset: 0;
}

.contact-building-unpeeled {
  clip-path: inset(0 calc(var(--cb-fold) * 1%) 0 0);
}

.contact-building-peeled {
  clip-path: inset(0 0 0 calc(100% - var(--cb-fold) * 1%));
  transform-origin: calc(100% - var(--cb-fold) * 1%) 50%;
  transform: scaleX(-1);
  filter: brightness(0) invert(1);
}

/* The team page's rough-edged paper bubble, up by the roof on the
   left. It pops out as the sticker lands. */
.contact-building-bubble {
  position: absolute;
  left: -4%;
  top: 13%;
  z-index: 2;
  width: 34%;
  transform-origin: 90% 100%;
  animation: contact-building-bubble 600ms cubic-bezier(0.5, 1.8, 0.62, 1)
    400ms both;
}

@keyframes contact-building-bubble {
  from {
    opacity: 0;
    transform: scale(0.2) rotate(-40deg);
  }
  to {
    opacity: 1;
    transform: scale(1) rotate(-24deg);
  }
}

.contact-building-bubble svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: var(--pink, #ff0099);
  /* Flipped, so the tail points right, down to the roof. */
  transform: scaleX(-1);
}

.contact-building-bubble span {
  position: absolute;
  left: 0;
  right: 0;
  top: 37%;
  color: #ffffff;
  font: 700 4.4cqi/1 var(--font-display);
  letter-spacing: -0.02em;
  text-align: center;
  white-space: nowrap;
  transform: translateY(-50%);
}

/* The sticker itself, turned back upright inside the turned fold box. */
.contact-building-face {
  position: absolute;
  inset: 0;
  background: url("https://leadly-website.pages.dev/assets/contact-office-sticker.webp") center / contain
    no-repeat;
  transform: rotate(90deg);
}

/* The section clips on both axes, which cut the sticker and its shadow
   off in a straight line where it hangs past the bottom. Clip sideways
   only here. */
.contact-main:has(.contact-building) {
  overflow-x: clip;
  overflow-y: visible;
}

@media (hover: hover) and (pointer: fine) {
  .contact-object.contact-building {
    pointer-events: none;
  }

  .contact-building-sticker {
    pointer-events: auto;
  }

  /* On the wrapper, so it never replaces (and replays) the sticker's
     own load animations. */
  .contact-building:has(.contact-building-sticker:hover) {
    animation: contact-building-wiggle 1300ms ease-in-out infinite;
  }
}

@media (max-width: 1024px) {
  .contact-object.contact-building {
    top: calc(56% - 40px);
    left: 50%;
    width: min(24rem, 52vw);
    transform: translate(-30%, -12%);
  }
}

@media (max-width: 768px) {
  .contact-object.contact-building {
    grid-area: object;
    top: 0;
    left: auto;
    width: min(20rem, 78vw);
    margin: 0.5rem auto 0;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .contact-building-sticker {
    animation: none;
    --cb-lift: 1;
  }

  .contact-building-bubble {
    animation: none;
    transform: rotate(-24deg);
  }

  .contact-building:has(.contact-building-sticker:hover) {
    animation: none;
  }
}
