* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  background: var(--bg-white);
}

body {
  min-width: 320px;
  margin: 0;
  overflow-x: hidden;
  color: var(--text-body);
  background: var(--bg-white);
  font-family: var(--font-base);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  font: inherit;
}

a {
  color: inherit;
}

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

h1,
h2,
h3,
p,
figure {
  margin-top: 0;
}

h1,
h2,
h3 {
  color: var(--text-heading);
  font-weight: var(--fw-normal);
}

.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link:focus {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100;
  width: auto;
  height: auto;
  padding: 10px 14px;
  margin: 0;
  overflow: visible;
  clip: auto;
  color: white;
  background: var(--brand-black);
}

.site-header {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  padding: 0 clamp(24px, 5vw, 72px);
  border-bottom: 1px solid var(--border-base);
  background: white;
}

.site-brand {
  display: block;
  width: 148px;
  height: 58px;
  overflow: hidden;
}

.site-brand img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.site-navigation {
  display: flex;
  align-items: center;
  gap: 28px;
}

.site-navigation a {
  color: var(--text-body);
  font-size: 14px;
  font-weight: var(--fw-medium);
  text-decoration: none;
  transition: color 180ms ease;
}

.site-navigation a:hover,
.site-navigation a:focus-visible {
  color: var(--brand-blue);
}

/* The page you are already on. Shared by every page, so it lives here rather
   than beside one page's own styles. */
.site-navigation .nav-current {
  color: var(--brand-blue);
}

/* Built-for menu. Click-toggled rather than hover-opened: hover menus are
   unreachable on touch and fire on accidental pass-through with a pointer. */
.nav-group {
  position: relative;
}

.nav-group__trigger {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0;
  border: 0;
  color: var(--text-body);
  background: transparent;
  font-size: 14px;
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: color 180ms ease;
}

.nav-group__trigger:hover,
.nav-group__trigger[aria-expanded="true"] {
  color: var(--brand-blue);
}

.nav-group__chevron {
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 200ms ease;
}

.nav-group__trigger[aria-expanded="true"] .nav-group__chevron {
  transform: translateY(1px) rotate(225deg);
}

.nav-menu {
  position: absolute;
  z-index: 40;
  top: calc(100% + 18px);
  right: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(214px, 1fr));
  gap: 8px 30px;
  padding: 24px 26px;
  border: 1px solid var(--border-base);
  border-radius: 18px;
  background: white;
  box-shadow: 0 26px 60px rgba(38, 30, 61, 0.16);
}

/* Hairline between the two groups, so "by role" and "by industry" read as separate
   lists rather than one eight-item column pair. */
.nav-menu__col + .nav-menu__col {
  padding-left: 30px;
  border-left: 1px solid var(--border-base);
}

.nav-menu[hidden] {
  display: none;
}

.nav-menu__label {
  margin: 0 0 12px;
  color: var(--brand-blue);
  font-size: 11px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Overrides .site-navigation a, which is laid out for a single-line nav item. */
.nav-menu a {
  display: block;
  padding: 9px 10px;
  margin: 0 -10px;
  border-radius: 10px;
  color: var(--text-heading);
  font-size: 15px;
  font-weight: var(--fw-medium);
  transition: background-color 160ms ease;
}

.nav-menu a:hover,
.nav-menu a:focus-visible {
  color: var(--text-heading);
  background: var(--bg-soft-blue);
}

.nav-menu a span {
  display: block;
  margin-top: 3px;
  color: var(--text-body);
  font-size: 13px;
  font-weight: var(--fw-normal);
}

.site-navigation .nav-action {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 0 18px;
  border-radius: var(--radius-pill);
  color: white;
  background: var(--brand-blue);
  transition:
    background-color 180ms ease,
    transform 180ms ease;
}

.site-navigation .nav-action:hover,
.site-navigation .nav-action:focus-visible {
  color: white;
  background: #1038ac;
  transform: translateY(-1px);
}

.menu-toggle {
  display: none;
  min-width: 52px;
  min-height: 44px;
  padding: 0;
  border: 0;
  color: var(--text-heading);
  background: transparent;
  font-weight: var(--fw-medium);
  cursor: pointer;
}

.hero {
  position: relative;
  display: grid;
  align-items: center;
  height: calc(100svh - 110px);
  min-height: 640px;
  max-height: 860px;
  overflow: hidden;
  color: white;
  background:
    radial-gradient(circle at 78% 38%, rgba(20, 71, 220, 0.22), transparent 34%),
    var(--brand-black);
}

.hero::after {
  position: absolute;
  inset: 0;
  content: "";
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.16) 1px, transparent 1.4px);
  background-position: right center;
  background-size: 26px 26px;
  mask-image: linear-gradient(90deg, transparent 38%, black 100%);
  opacity: 0.22;
  pointer-events: none;
}

.hero__copy {
  position: relative;
  z-index: 4;
  width: min(660px, 46vw);
  margin-left: clamp(28px, 7vw, 104px);
  padding-bottom: 50px;
}

.eyebrow {
  margin: 0 0 20px;
  color: var(--brand-blue);
  font-size: 12px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.eyebrow--inverse {
  color: var(--brand-cyan);
}

.hero .eyebrow {
  color: var(--brand-cyan);
}

/* The promise IS the hero headline now — it carries the <h1>, so one rule
   governs it. (There used to be a separate `.hero h1` display rule for the
   single word "Tensic" at up to 152px; a full sentence at that size is
   unreadable, and two rules on one element would have fought on specificity.) */
/* One statement of three sentences, 25.64em in Athletics Medium at this tracking
   against a min(660px, 46vw) column — so it wraps to three lines by design. 60px is
   chosen, not maximal: greedy wrapping there breaks exactly on the sentence stops
   ("Build, test and deploy AI." / "Skip the platform build." / "Keep control."), and
   the widest line measures 604px, leaving ~8% for hinting and fallback-font drift.
   66px and above is bigger but breaks mid-sentence. No text-wrap: balance — it
   evens line lengths, which is precisely what would undo the sentence alignment. */
.hero__promise {
  max-width: 720px;
  margin-bottom: 22px;
  color: white;
  font-size: clamp(26px, 4.2vw, 60px);
  font-weight: var(--fw-medium);
  line-height: 1.06;
  letter-spacing: -0.04em;
}

.hero__lede {
  max-width: 520px;
  margin-bottom: 32px;
  color: rgba(255, 255, 255, 0.68);
  font-size: 18px;
  line-height: 1.55;
}

/* Two paragraphs: the wrapper owns the space below the block, each paragraph only
   the gap to the next. */
.hero__lede p {
  margin-bottom: 14px;
}

.hero__lede p:last-child {
  margin-bottom: 0;
}

.hero__actions,
.final-section__actions {
  display: flex;
  align-items: center;
  gap: 22px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: var(--fw-bold);
  text-decoration: none;
  transition:
    transform 180ms ease,
    background-color 180ms ease,
    color 180ms ease;
}

.button:hover,
.button:focus-visible {
  transform: translateY(-2px);
}

.button--primary {
  color: white;
  background: var(--brand-blue);
}

.button--primary:hover,
.button--primary:focus-visible {
  background: #1038ac;
}

.button--light {
  color: var(--brand-blue);
  background: white;
}

/* Floating signup CTA, persistent from first paint. Above the header
   (z-index 20) but below the skip link (100), so keyboard users still reach the
   skip link first. */
.beta-float {
  position: fixed;
  z-index: 30;
  right: clamp(18px, 4vw, 44px);
  bottom: clamp(18px, 4vw, 44px);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 24px;
  border-radius: var(--radius-pill);
  color: white;
  background: var(--brand-blue);
  box-shadow: 0 16px 36px rgba(6, 16, 48, 0.38);
  font-size: 14px;
  font-weight: var(--fw-bold);
  text-decoration: none;
  transition:
    opacity 220ms ease,
    transform 220ms ease,
    background-color 180ms ease;
}

.beta-float:hover,
.beta-float:focus-visible {
  background: #1038ac;
  transform: translateY(-2px);
}

/* Shared by both states of the signup CTA — the in-flow hero button and the
   detached float — so they stay the same object to the eye. */
.cta-arrow {
  width: 16px;
  height: 16px;
  transition: transform 180ms ease;
}

.button:hover .cta-arrow,
.button:focus-visible .cta-arrow,
.beta-float:hover .cta-arrow,
.beta-float:focus-visible .cta-arrow {
  transform: translateX(3px);
}

/* Hidden while the hero button is still on screen. `visibility`, not opacity
   alone, so the hidden link is also out of the tab order and the accessibility
   tree — otherwise both copies of "Sign up" are announced at once. The delay
   applies to the flip only, so the fade-out still plays. */
.beta-float[data-visible="false"] {
  visibility: hidden;
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 220ms ease,
    transform 220ms ease,
    visibility 0s linear 220ms;
}

/* Beta status pill. Sits above the headline, carrying the "beta" signal that the
   CTA label no longer spells out. Cyan on translucent white, matching the chips
   in the hero diagram rather than the solid blue of the buttons — it is a label,
   not something to click. */
.beta-tag {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 14px;
  margin: 0 0 20px;
  border: 1px solid rgba(18, 200, 255, 0.42);
  border-radius: var(--radius-pill);
  color: var(--brand-cyan);
  background: rgba(18, 200, 255, 0.1);
  font-size: 11px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.text-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  font-weight: var(--fw-medium);
  text-decoration: none;
}

.text-link::after {
  position: absolute;
  right: 0;
  bottom: 7px;
  left: 0;
  height: 1px;
  content: "";
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 180ms ease;
}

.text-link:hover::after,
.text-link:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.text-link--inverse {
  color: rgba(255, 255, 255, 0.82);
}

/* Stretched top-to-bottom and flex-centred rather than positioned at top: 50% with
   a translate. That gives the box a definite height, which is what lets the SVG's
   `max-height: 100%` resolve — so the diagram scales down to fit a short hero instead
   of overflowing it, and stays centred whatever the hero's computed height turns out
   to be. `right` lands on the section-shell's right edge (the shell is
   min(100% - 48px, 1240px) centred, so its edge sits 50% - 620px from the viewport's
   right), putting the diagram on the same grid line as every section below. */
.hero__visual {
  position: absolute;
  z-index: 2;
  top: 0;
  right: max(24px, calc(50% - 620px));
  bottom: 0;
  display: flex;
  align-items: center;
  width: min(38vw, 560px);
  padding: 44px 0;
}

/* Editorial system diagram — the hero expression named in visual-world.md.
   Bleeds off the right edge on purpose so the hero reads as one composition
   rather than a boxed figure pasted next to the copy. */
.sysmap {
  width: 100%;
  height: auto;
  max-height: 100%;
  overflow: visible;
  font-family: var(--font-base);
}

/* Bounded fields: rounded, quiet, and readable on the dark hero. */
.sysmap__field {
  fill: rgba(255, 255, 255, 0.04);
  stroke: rgba(255, 255, 255, 0.16);
  stroke-width: 1;
}

.sysmap__field--instance {
  fill: rgba(255, 255, 255, 0.06);
  stroke: rgba(255, 255, 255, 0.24);
}

/* The one live project. Blue is reserved for it. */
.sysmap__field--active {
  fill: rgba(20, 71, 220, 0.16);
  stroke: rgba(18, 200, 255, 0.5);
}

.sysmap__mark path {
  fill: white;
}

.sysmap__title {
  fill: white;
  font-size: 15px;
  font-weight: var(--fw-medium);
}

.sysmap__level {
  fill: rgba(255, 255, 255, 0.42);
  font-size: 11px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.sysmap__chip rect {
  fill: rgba(255, 255, 255, 0.05);
  stroke: rgba(255, 255, 255, 0.14);
  stroke-width: 1;
}

.sysmap__chip text {
  fill: rgba(255, 255, 255, 0.72);
  font-size: 12px;
  text-anchor: middle;
}

.sysmap__pill {
  fill: rgba(255, 255, 255, 0.05);
  stroke: rgba(255, 255, 255, 0.12);
  stroke-width: 1;
}

.sysmap__pill--active {
  fill: rgba(20, 71, 220, 0.28);
  stroke: rgba(18, 200, 255, 0.42);
}

.sysmap__pilltext {
  fill: rgba(255, 255, 255, 0.78);
  font-size: 12px;
}

.sysmap__dot {
  fill: rgba(255, 255, 255, 0.32);
}

.sysmap__dot--active {
  fill: var(--brand-cyan);
}

/* Inactive routes stay neutral; exactly one carries the gradient. */
.sysmap__route {
  fill: none;
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 1.5;
}

.sysmap__route--active {
  stroke: url(#active-route);
  stroke-width: 2;
}

/* The live inference signal: one dot, one direction, 150-300ms easing over a
   slow loop — motion that explains readiness rather than decorating. */
.sysmap__signal {
  fill: var(--brand-cyan);
  animation: sysmap-signal 2.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes sysmap-signal {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  15%,
  70% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateY(54px);
  }
}

.hero-enter {
  opacity: 0;
  transform: translateY(18px);
  animation: hero-enter 720ms var(--hero-delay, 0ms) cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}

.hero-enter--0 {
  --hero-delay: 20ms;
}

.hero-enter--1 {
  --hero-delay: 80ms;
}

.hero-enter--2 {
  --hero-delay: 160ms;
}

.hero-enter--3 {
  --hero-delay: 260ms;
}

.hero-enter--4 {
  --hero-delay: 380ms;
}

.section-shell {
  width: min(calc(100% - 48px), 1240px);
  margin: 0 auto;
}

/* Sovereign AI. Sits between the dark hero and the white features section, so it
   takes the page tint to keep those two from running together. */
.sovereign-section {
  padding: clamp(88px, 10vw, 148px) 0;
  background: var(--bg-page);
}

.sovereign-layout {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}

.sovereign-map svg {
  width: 100%;
  height: auto;
}

/* No panel: the map sits transparently on the section tint. That removes the field
   the white stars were reading against, so the dots carry the contrast instead and
   the stars gain an outline — see below. */

/* 72% over --bg-page resolves to #5276e2 — 3.65:1 against the section, so the shape
   holds without a panel behind it. Drawn as strokes on zero-length subpaths, so
   stroke-width is the dot diameter and stroke-linecap: round is what makes them dots
   at all. No non-scaling-stroke: the dots scale with the map. */
.euromap__dots {
  fill: none;
  stroke: rgba(20, 71, 220, 0.72);
  stroke-width: 7.5;
  stroke-linecap: round;
}

/* EU flag gold. The outline is doing the work: gold measures 1.33:1 against the
   section tint and 2.75:1 against the dots, so on its own the ring would barely
   register on a light page — the brand-blue stroke (6.22:1 on the tint, 4.69:1 on
   the gold) is what draws each star. There is no yellow in the token set; #ffcc00 is
   the flag's own value. */
.euromap__stars {
  fill: #ffcc00;
  stroke: var(--brand-blue);
  stroke-width: 2;
}

/* One word, so it takes the display treatment of the Control heading rather than the
   smaller sentence-headline size. Capped below .section-heading h2's 88px because this
   one sits in a column beside the map, not across the full shell. */
.sovereign-copy h2 {
  margin-bottom: 40px;
  font-size: clamp(46px, 5.4vw, 76px);
  line-height: 0.98;
  letter-spacing: -0.052em;
}

/* Mirrors the .features__list rules: hairline top rule, one divider per item, and the
   same statement type. Static list items rather than buttons — there is one visual in
   this section, so nothing for a tablist to swap. */
.sovereign-points {
  max-width: 560px;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border-strong);
  list-style: none;
}

.sovereign-points li {
  padding: 22px 0;
  border-bottom: 1px solid var(--border-strong);
  color: var(--text-heading);
  font-size: clamp(19px, 1.5vw, 23px);
  font-weight: var(--fw-medium);
  line-height: 1.25;
  letter-spacing: -0.02em;
}

.platform-section,
.principles-section,
.audience-section {
  padding: clamp(96px, 11vw, 160px) 0;
}

.platform-section {
  background: white;
}

.section-heading h2 {
  margin-bottom: 0;
  font-size: clamp(48px, 6.2vw, 88px);
  line-height: 0.98;
  letter-spacing: -0.052em;
}

.features-heading {
  max-width: 900px;
  margin-bottom: 56px;
}

/* The features tablist: sub-values on the left, the matching shot on the right.
   Two columns rather than a carousel so every heading is scannable at once and
   nothing is hidden behind a next-arrow. */
.features {
  display: grid;
  grid-template-columns: 0.78fr 1.22fr;
  gap: clamp(32px, 4vw, 60px);
  align-items: start;
}

.features__list {
  border-top: 1px solid var(--border-strong);
}

.features__trigger {
  display: block;
  width: 100%;
  padding: 22px 0;
  border: 0;
  border-bottom: 1px solid var(--border-strong);
  color: var(--text-heading);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: color 180ms ease;
}

.features__trigger:hover,
.features__trigger.is-active {
  color: var(--brand-blue);
}

.features__statement {
  display: block;
  font-size: clamp(19px, 1.5vw, 23px);
  font-weight: var(--fw-medium);
  line-height: 1.25;
  letter-spacing: -0.02em;
}

/* Third text level: below the statement, above the shot. Sized between the kicker
   and the statement so the ladder reads value > title > detail. */
.features__support {
  display: block;
  margin-top: 8px;
  color: rgba(93, 87, 110, 0.86);
  font-size: 15px;
  font-weight: var(--fw-normal);
  line-height: 1.5;
  letter-spacing: normal;
}

.features__meta {
  margin: 44px 0 0;
  color: rgba(93, 87, 110, 0.72);
  font-size: 13px;
}

/* Sticky so the shot stays beside the accordion, which is taller than the frame
   once an item is open. */
.features__stage {
  position: sticky;
  top: 110px;
}

/* Two offset tint panels behind the frame, so the shot reads as a placed object
   rather than a bordered box. Both are on the figure, not the frame, because the
   frame clips its own overflow. */
.shot {
  position: relative;
  margin: 0;
}

.shot::before,
.shot::after {
  position: absolute;
  z-index: 0;
  content: "";
  border-radius: 20px;
}

.shot::before {
  top: -20px;
  right: 34px;
  left: 100px;
  height: 112px;
  background: rgba(20, 71, 220, 0.13);
}

.shot::after {
  top: 36px;
  left: -28px;
  width: 124px;
  height: 62%;
  background: rgba(18, 200, 255, 0.15);
}

/* A real capture replaces the whole placeholder frame rather than sitting inside
   it — the screenshot already has its own window chrome and rounded edge. */
.shot__image {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: auto;
  border-radius: 18px;
  box-shadow: 0 32px 90px rgba(38, 30, 61, 0.16);
}

.shot__frame {
  position: relative;
  z-index: 1;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: var(--bg-page);
  box-shadow: 0 32px 90px rgba(38, 30, 61, 0.16);
}

.shot__chrome {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 16px;
  color: rgba(255, 255, 255, 0.58);
  background: var(--brand-black);
}

.shot__chrome > span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.46);
}

.shot__chrome small {
  margin-left: auto;
  font-size: 11px;
}

/* Deliberately abstract grey blocks, not fake data: an obvious placeholder is
   better than a convincing wrong screenshot. Swap .shot__frame for an <img>
   when the real captures land. */
.shot__canvas {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 28px;
  min-height: 420px;
  padding: 30px;
}

.shot__rail,
.shot__body {
  display: grid;
  align-content: start;
  gap: 17px;
}

.shot__rail span {
  height: 12px;
  border-radius: 6px;
  background: rgba(38, 30, 61, 0.1);
}

.shot__rail span:first-child {
  background: rgba(20, 71, 220, 0.3);
}

.shot__bar {
  height: 14px;
  border-radius: 7px;
  background: rgba(38, 30, 61, 0.09);
}

.shot__bar--title {
  width: 52%;
  height: 22px;
  background: rgba(38, 30, 61, 0.16);
}

.shot__bar--short {
  width: 38%;
}

.shot__block {
  min-height: 132px;
  border: 1px solid var(--border-base);
  border-radius: 12px;
  background: white;
}

.shot__stamp {
  position: absolute;
  right: 14px;
  bottom: 14px;
  padding: 5px 11px;
  margin: 0;
  border-radius: var(--radius-pill);
  color: rgba(38, 30, 61, 0.5);
  background: rgba(38, 30, 61, 0.07);
  font-size: 10px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.shot figcaption {
  position: relative;
  z-index: 1;
  max-width: 520px;
  padding-top: 18px;
  color: rgba(93, 87, 110, 0.9);
  font-size: 13px;
  line-height: 1.5;
}
.principles-section {
  background: white;
}

.principles-heading {
  max-width: 920px;
  margin-bottom: 72px;
}

.principle-lines {
  border-top: 1px solid var(--border-strong);
}

.principle-line {
  position: relative;
  display: grid;
  grid-template-columns: 70px 0.8fr 1fr;
  gap: 32px;
  align-items: center;
  min-height: 178px;
  padding: 30px 0;
  overflow: hidden;
  border-bottom: 1px solid var(--border-strong);
}

.principle-line__index {
  color: var(--brand-blue);
  font-size: 13px;
  font-weight: var(--fw-medium);
}

.principle-line h3 {
  margin-bottom: 0;
  font-size: clamp(30px, 3.4vw, 48px);
  line-height: 1.02;
  letter-spacing: -0.038em;
}

.principle-line p {
  max-width: 500px;
  margin-bottom: 0;
  font-size: 18px;
}

.principle-line__signal {
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  background: var(--brand-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 360ms ease;
}

.principle-line:hover .principle-line__signal {
  transform: scaleX(1);
}

.audience-section {
  background: var(--bg-soft-blue);
}

.audience-layout {
  display: grid;
  grid-template-columns: 0.86fr 1.14fr;
  gap: clamp(64px, 10vw, 140px);
  align-items: start;
}

.audience-layout .section-heading {
  position: sticky;
  top: 96px;
}

.audience-switcher {
  min-width: 0;
}

.audience-tabs {
  display: flex;
  gap: 8px;
  padding-bottom: 22px;
  border-bottom: 1px solid rgba(38, 30, 61, 0.18);
}

.audience-tab {
  min-height: 44px;
  padding: 0 17px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: var(--text-body);
  background: transparent;
  font-weight: var(--fw-medium);
  cursor: pointer;
}

.audience-tab:hover,
.audience-tab:focus-visible {
  color: var(--brand-blue);
}

.audience-tab.is-active {
  color: white;
  background: var(--brand-blue);
}

.audience-panel {
  padding: 56px 0 0;
}

.audience-panel[hidden] {
  display: none;
}

.audience-panel.is-active {
  animation: panel-enter 300ms ease both;
}

.audience-panel__label {
  margin-bottom: 34px;
  color: var(--brand-blue);
  font-size: 12px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Sized for a full sentence. The old 72px ceiling was set for a short phrase and
   turned the new copy into three lines of shouting. */
.audience-panel h3 {
  max-width: 670px;
  margin-bottom: 26px;
  font-size: clamp(28px, 3.2vw, 42px);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.audience-panel > p:not(.audience-panel__label) {
  max-width: 640px;
  margin-bottom: 38px;
  font-size: 19px;
  line-height: 1.6;
}

.audience-panel ul {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: 40px;
  padding: 0;
  margin: 0;
  border-top: 1px solid rgba(38, 30, 61, 0.18);
  list-style: none;
}

.audience-panel li {
  padding: 17px 0;
  border-bottom: 1px solid rgba(38, 30, 61, 0.18);
  color: var(--text-heading);
  font-size: 14px;
  font-weight: var(--fw-medium);
}

.final-section {
  position: relative;
  min-height: 720px;
  display: grid;
  align-items: center;
  overflow: hidden;
  color: white;
  background: var(--gradient-blue-purple);
}

.final-section::after {
  position: absolute;
  inset: 0;
  content: "";
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.22) 1px, transparent 1.5px);
  background-size: 28px 28px;
  mask-image: linear-gradient(90deg, transparent 20%, black);
  opacity: 0.2;
}

.final-section__symbol {
  position: absolute;
  right: -7vw;
  bottom: -15vw;
  width: min(58vw, 850px);
  color: rgba(255, 255, 255, 0.13);
  transform: rotate(-8deg);
}

.final-section__inner {
  position: relative;
  z-index: 2;
}

.final-section h2 {
  max-width: 1050px;
  margin-bottom: 26px;
  color: white;
  font-size: clamp(40px, 7.4vw, 89px);
  line-height: 0.94;
  letter-spacing: -0.058em;
}

.final-section__lede {
  max-width: 620px;
  margin-bottom: 44px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 19px;
  line-height: 1.6;
}

.site-footer {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 32px;
  align-items: center;
  min-height: 118px;
  padding: 24px clamp(24px, 5vw, 72px);
  border-top: 1px solid var(--border-base);
  background: white;
  font-size: 13px;
}

.site-footer > a {
  display: block;
  width: 150px;
  height: 58px;
}

.site-footer img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.site-footer p {
  margin-bottom: 0;
}

.reveal-section {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 700ms cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 700ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

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

:focus-visible {
  outline: 3px solid rgba(20, 71, 220, 0.34);
  outline-offset: 3px;
}

@keyframes hero-enter {
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes route-flow {
  to {
    stroke-dashoffset: -144;
  }
}

@keyframes core-pulse {
  0%,
  100% {
    r: 48px;
    opacity: 0.78;
  }
  50% {
    r: 54px;
    opacity: 1;
  }
}

@keyframes panel-enter {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 1040px) {
  .site-navigation {
    gap: 18px;
  }

  .site-navigation a {
    font-size: 13px;
  }

  .hero__copy {
    width: min(560px, 54vw);
    margin-left: 44px;
  }

  /* Below this width the diagram cannot be both clear of the copy and legible —
     its labels would render under 7px — so it stops here rather than at 840px. */
  .hero__visual {
    display: none;
  }

  .sovereign-layout,
  .audience-layout {
    gap: 64px;
  }
}

@media (max-width: 840px) {
  .site-header {
    height: 68px;
  }

  .site-brand {
    width: 132px;
    height: 52px;
  }

  .menu-toggle {
    display: block;
  }

  .site-navigation {
    position: absolute;
    top: 68px;
    right: 0;
    left: 0;
    display: none;
    align-items: stretch;
    gap: 0;
    padding: 18px 24px 26px;
    border-bottom: 1px solid var(--border-base);
    background: white;
    box-shadow: var(--shadow-md);
  }

  .site-navigation[data-open="true"] {
    display: grid;
  }

  .site-navigation a {
    display: flex;
    align-items: center;
    min-height: 48px;
    border-bottom: 1px solid var(--border-base);
  }

  .site-navigation .nav-action {
    justify-content: center;
    margin-top: 16px;
    border-bottom: 0;
  }

  /* Inside the mobile drawer there is nowhere to float a panel, so the menu
     becomes part of the stack and its columns unstack. */
  .nav-group__trigger {
    justify-content: space-between;
    width: 100%;
    min-height: 48px;
    border-bottom: 1px solid var(--border-base);
  }

  .nav-menu__col + .nav-menu__col {
    padding-left: 0;
    border-left: 0;
  }

  .nav-menu {
    position: static;
    grid-template-columns: 1fr;
    gap: 0;
    padding: 8px 0 14px;
    border: 0;
    border-bottom: 1px solid var(--border-base);
    border-radius: 0;
    box-shadow: none;
    transform: none;
  }

  .nav-menu a {
    min-height: 44px;
    border-bottom: 0;
  }

  .hero {
    height: calc(100svh - 92px);
    min-height: 680px;
    max-height: none;
    align-items: start;
  }

  .hero__copy {
    width: auto;
    margin: 0;
    padding: 72px 24px 0;
  }

  /* Kept at phone width — it is the primary CTA once the hero is gone — but
     trimmed so it does not span most of the viewport. */
  .beta-float {
    min-height: 46px;
    padding: 0 18px;
    font-size: 13px;
  }

  .hero__promise {
    max-width: 600px;
    font-size: clamp(19px, 6.7vw, 52px);
  }

  .hero__lede {
    max-width: 590px;
    font-size: 16px;
  }

  .sovereign-layout,
  .audience-layout {
    grid-template-columns: 1fr;
  }

  .audience-layout .section-heading {
    position: static;
  }

  /* Map first at narrow widths would push the copy below the fold, so it follows. */
  .sovereign-map {
    order: 2;
    max-width: 520px;
  }

  /* Single column: the shot follows the list rather than sitting beside it, so
     sticky would leave it pinned over the copy. */
  .features {
    grid-template-columns: 1fr;
  }

  .features__stage {
    position: static;
  }
.principle-line {
    grid-template-columns: 52px 1fr;
  }

  .principle-line p {
    grid-column: 2;
  }

  .site-footer {
    grid-template-columns: 150px 1fr;
  }
}

@media (max-width: 600px) {
  .hero__copy {
    padding-top: 52px;
  }

  .hero__promise {
    margin-bottom: 14px;
  }

  .hero__lede {
    margin-bottom: 24px;
  }

  .hero__actions,
  .final-section__actions {
    align-items: flex-start;
    flex-direction: column;
    gap: 10px;
  }

  .button {
    width: 100%;
  }

  .text-link {
    min-height: 42px;
  }

  .section-shell {
    width: min(calc(100% - 40px), 1240px);
  }

  .platform-section,
  .principles-section,
  .audience-section,
  .sovereign-section {
    padding: 88px 0;
  }
.features-heading {
    margin-bottom: 38px;
  }

  .section-heading h2 {
    font-size: clamp(45px, 13.4vw, 64px);
  }

  .shot__canvas {
    grid-template-columns: 68px 1fr;
    min-height: 290px;
    padding: 20px;
  }

          .principles-heading {
    margin-bottom: 44px;
  }

  .principle-line {
    grid-template-columns: 36px 1fr;
    gap: 14px;
    min-height: 210px;
    align-content: center;
  }

  .principle-line h3 {
    font-size: 36px;
  }

  .principle-line p {
    font-size: 16px;
  }

  .audience-layout {
    gap: 48px;
  }

  .audience-tabs {
    overflow-x: auto;
  }

  .audience-tab {
    flex: 0 0 auto;
  }

  .audience-panel {
    padding-top: 42px;
  }

  .audience-panel h3 {
    font-size: 30px;
  }

  .audience-panel > p:not(.audience-panel__label) {
    font-size: 17px;
  }

  .audience-panel ul {
    grid-template-columns: 1fr;
  }

  .final-section {
    min-height: 680px;
  }

  .final-section h2 {
    font-size: clamp(23px, 7.4vw, 47px);
  }

  .site-footer {
    grid-template-columns: 1fr;
    gap: 14px;
  }
}

@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-enter,
  .reveal-section {
    opacity: 1;
    transform: none;
  }

  /* The signal carries meaning — it marks which route is live — so it stays
     visible and simply stops travelling. */
  .sysmap__signal {
    opacity: 1;
    transform: translateY(27px);
  }
}
