/* ResellerSpace - base styles */

/* Brand colours sampled from the logo mark:
   violet #6200fd, pink #fdb9ff, deep indigo #01001e to #02009d */
:root {
  --brand: #6200fd;        /* solid buttons, links */
  --brand-dark: #4d00c9;   /* solid buttons at rest */
  --brand-deep: #3a0099;   /* and their hover */
  --brand-light: #c961fe;  /* brand colour on dark bands */
  --brand-pink: #fdb9ff;   /* gradient tail, matches the mark */
  --soft: #f1e9ff;         /* secondary button fill */
  --soft-hover: #e6d9ff;
  --soft-text: #5200d6;    /* text on --soft */
  --ink: #0d1526;
  --ink-2: #4a5769;
  --line: #e4e8ee;
  --tile: #1c1740;         /* icon tiles in the mega menu */
  --grey: #f5f6f8;         /* action strip inside the mega card */
  --wrap: 1520px;
  --panel-row: 1280px;    /* the joined card rows, product and ethos */
  --head-gap: 14px;        /* space between the header card and the mega card */
  --band: #6200fd;         /* the flat block behind the header and the hero, = --brand */
  --font-head: "Familjen Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-body: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --edge: 8px;             /* corner shared by the header bar and the video */
  --band-inset: 12px;      /* violet gutter around the video block */
  --head-clear: 18px;      /* video showing above the header bar */
  --head-pad: calc(var(--band-inset) + var(--head-clear));
  --head-h: calc(var(--head-pad) + 64px + 14px);  /* pad + pill + pad */
}

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

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

body {
  margin: 0;
  /* clip, not hidden: hidden makes body a scroll container and silently
     breaks position: sticky on the header */
  overflow-x: clip;
  background: #ffffff;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
}

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

h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: -.03em;
  text-wrap: balance;
  line-height: 1.1;
  margin: 0;
}

a { color: var(--brand); }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 16px;
}

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

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: #ffffff;
  color: var(--ink);
  padding: 14px 18px;
  border-radius: 8px;
  text-decoration: none;
}
.skip:focus { left: 12px; top: 12px; }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Icon sprite holder, never rendered */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* fill and stroke inherit into the use shadow tree, so set them here */
.mi, .chev {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* Gradient words are inline-block so the padding-bottom can save the
   descenders, but that also lets a following comma or full stop wrap onto a
   line of its own. Wrap the pair in .nobr wherever punctuation follows. */
.nobr { white-space: nowrap; }

/* Gradient word in headings, runs violet to pink like the mark */
.hl {
  display: inline-block;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  background: linear-gradient(96deg, #4d00c9, #9d3df5);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border-radius: 8px;
  border: 1px solid transparent;
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

/* Rest is what used to be the hover, and hover goes a step darker again.
   Applied to every solid button, not just the one in the header: two
   different solid violets on the same screen would read as a mistake. White
   holds 9.73:1 at rest and 12.81:1 on hover. */
.btn-solid { background: var(--brand-dark); color: #ffffff; }
.btn-solid:hover { background: var(--brand-deep); }

.btn-soft { background: var(--soft); color: var(--soft-text); }
.btn-soft:hover { background: var(--soft-hover); }

/* On the dark band */
.btn-white { background: #ffffff; color: var(--brand-dark); }
.btn-white:hover { background: #f1e9ff; }

.btn-ghost { background: transparent; color: #ffffff; border-color: rgba(255, 255, 255, .32); }
.btn-ghost:hover { background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .55); }

/* --brand-pink, the tail of the gradient on the accent line above it. Dark
   ink, because white on this pink is 1.55:1 and unreadable. 10.9:1 at rest
   and 9.0:1 on hover, and the fill reads 9.8:1 against the card. */
.btn-pink { background: var(--brand-pink); color: var(--tile); }
.btn-pink:hover { background: #f79dfa; }

/* ---------------------------------------------------------------
   Band holding the header and the hero
   --------------------------------------------------------------- */

.topband {
  position: relative;
  /* One flat colour behind the floating header and the hero. Every section
     below the hero paints its own background, so the fill only ever shows
     where it is meant to. A variable, so the whole block is one edit. */
  background: var(--band);
}


/* A plain white bar with a hairline under it, and nothing else. The mega
   menu and the mobile drawer sit on top of it as bordered white panels. */
.site-head {
  position: sticky;
  top: 0;
  z-index: 40;
  /* top padding puts the bar inside the video rather than across its edge */
  padding: var(--head-pad) 0 14px;
  background: transparent;
  transition: opacity .2s ease, transform .2s ease;
}

/* Released at the end of the hero. It fades rather than being unpinned,
   because taking it out of flow would drop the hero by the height of the
   bar: the hero's negative top margin is measured against it. Hidden this
   way nothing moves, and it comes back on the way up. */
.site-head.is-past {
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
}

/* the header sits on the same measure as the rest of the page, so the logo
   lines up with the section content below it */

/* Two pills side by side: the menu on the left, the region switcher on the
   right. Stretch rather than centre, so the small one can decide its own
   height without dragging the tall one down with it. */
.head-row {
  display: flex;
  align-items: stretch;
  gap: 10px;
}

/* Homepage only. The menu keeps its full width and starts hard against the
   left, the region pill sits hard against the right, and the gap between
   them widens so they read as two pills rather than one bar with a seam.
   Sizing to content pulled the menu in too far, so it stretches as before.
   On .topband rather than the homepage only class, so all three pages get
   the same menu. Only the band behind it differs: the homepage runs the
   gradient, the inner pages the flat violet. */
.topband .head-row {
  /* Menu centred, region pill pinned to the right edge. They cannot both be
     flex items and do that, since space-between would drag the menu left, so
     the pill comes out of the flow and the menu centres on the full width as
     though it were the only thing there. */
  position: relative;
  justify-content: center;
  gap: 16px;
  /* The video is full bleed less --band-inset, while .wrap caps at 1520px
     and centres. On anything wider than that the pill could not reach the
     video's edge however much padding came off, because the container itself
     stopped short. Matching the video's box is what makes the two line up.
     The mega panel is still capped at --wrap, so the dropdown does not
     stretch with it. */
  max-width: none;
  /* a touch inside the video rather than hard against it */
  padding-left: calc(var(--band-inset) + 12px);
  padding-right: calc(var(--band-inset) + 12px);
}

/* The row runs full bleed so the region pill can reach the outer edge,
   which would otherwise stretch the menu across the whole screen. Capping
   the menu instead of the row keeps it the length it was while leaving the
   pill on the right where it belongs; the gap between the two grows with the
   window rather than the menu doing so. */
.topband .head-shell {
  flex: 0 1 auto;
  width: 100%;
  max-width: 1280px;
}

.topband .head-aside {
  position: absolute;
  top: 50%;
  /* pulled in from the outer edge, further than the menu is from the
     left, so the small pill does not sit tight in the corner */
  right: calc(var(--band-inset) + 28px);
  transform: translateY(-50%);
}

/* A white pill floating on the violet block, inset from both edges. */
.head-shell {
  flex: 1;
  min-width: 0;
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 8px 8px 8px 18px;
  background: #ffffff;
  /* Not a capsule. Square as the site's language goes: the same 8px the
     buttons use, and matched by the video block below it. */
  border-radius: var(--edge);
  box-shadow: 0 6px 22px rgba(6, 4, 24, .18);
  transition: box-shadow .18s ease;
}

.brand {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: 6px 0;
  min-height: 44px;
  text-decoration: none;
}

/* Lockup is 392 x 58, so height drives the width */
.brand-logo {
  display: block;
  width: auto;
  height: 25px;
}

@media (min-width: 400px) {
  .brand-logo { height: 29px; }
}

@media (max-width: 1159px) {
  .brand { margin-right: auto; }
}

/* Nav toggle. Sits inside the white pill, so it is outlined not filled. */
.nav-toggle {
  width: 44px;
  height: 44px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(13, 21, 38, .20);
  border-radius: 8px;
  cursor: pointer;
}

.nav-toggle:hover { background: rgba(13, 21, 38, .05); }

.nav-toggle-box {
  display: block;
  width: 20px;
  height: 14px;
  position: relative;
}

.nav-bar {
  position: absolute;
  left: 0;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform .2s ease, opacity .2s ease;
}
.nav-bar:nth-child(1) { top: 0; }
.nav-bar:nth-child(2) { top: 6px; }
.nav-bar:nth-child(3) { top: 12px; }

.nav-toggle[aria-expanded="true"] .nav-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------------------------------------------------------------
   Nav. Mobile first: a stacked drawer card under the header card.
   --------------------------------------------------------------- */

.nav {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + var(--head-gap));
  max-height: calc(100vh - 110px);
  overflow-y: auto;
  padding: 8px 16px 16px;
  background: #ffffff;
  border-radius: 10px;
  box-shadow: 0 14px 34px rgba(6, 4, 24, .24);
}

.nav.is-open { display: block; }

.nav-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
}

.nav-item { border-bottom: 1px solid var(--line); }

.nav-link,
.nav-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 4px 0;
  background: none;
  border: 0;
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.nav-link:hover,
.nav-trigger:hover { color: var(--brand-dark); }

.chev {
  width: 18px;
  height: 18px;
  transition: transform .2s ease;
}

.nav-trigger[aria-expanded="true"] .chev { transform: rotate(180deg); }

.nav-actions { display: grid; gap: 8px; }

/* text action next to the one solid CTA, the way Elementor does it */
.nav-plain {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 6px;
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color .16s ease, color .16s ease;
}

/* A fill, not just a colour change. Beside a solid button a text only hover
   reads as a label rather than a control. --soft-hover rather than the grey
   the mega menu uses: grey is 1.08:1 against the white pill, near enough to
   invisible, where this is 1.33:1 and tinted violet so it registers as a
   colour rather than a smudge. Violet text still holds 7.29:1 on it. */
.nav-plain:hover,
.nav-plain:focus-visible {
  background: var(--soft-hover);
  color: var(--brand-dark);
}

/* The second pill, holding Contact and Login. Hidden on the narrowest
   screens, where the logo, the burger and two actions will not share a line:
   the drawer copies below cover those. */
.head-aside {
  display: none;
  gap: 2px;
  align-items: center;
  align-self: center;
  flex: none;
  padding: 4px;
  background: #ffffff;
  border-radius: var(--edge);
  box-shadow: 0 6px 22px rgba(6, 4, 24, .18);
}

@media (min-width: 700px) {
  .head-aside { display: flex; }
  .nav-login,
  .region-drawer { display: none; }
}

.region { position: relative; }

.region-trigger {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  margin: 0;
  padding: 0 8px;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .16s ease;
}

.region-trigger:hover { background: var(--grey); }
.region-trigger[aria-expanded="true"] { background: var(--grey); }
.region-trigger .chev { width: 13px; height: 13px; opacity: .5; }
.region-trigger[aria-expanded="true"] .chev { transform: rotate(180deg); }

/* The white US and Indian bands run to the edge of the artwork, so on a
   white pill the flag would have no outline of its own. */
.flag {
  display: block;
  flex: none;
  width: 21px;
  height: 14px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(13, 21, 38, .16);
}

.region-menu {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  right: -4px;
  z-index: 50;
  min-width: 158px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 18px 44px rgba(6, 4, 24, .30);
}

.region-menu.is-open { display: block; animation: megaIn .16s ease-out; }

/* Inside the drawer the panel opens inline instead. .nav is a scrolling
   container there, so an absolutely positioned menu would be clipped by it. */
.region-drawer { width: 100%; }

.region-drawer .region-trigger {
  width: 100%;
  justify-content: space-between;
  min-height: 48px;
}

.region-drawer .region-menu {
  position: static;
  min-width: 0;
  margin-top: 4px;
  padding: 0;
  border: 0;
  box-shadow: none;
}

.region-menu a {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--ink);
  font-size: 15px;
  text-decoration: none;
  transition: background-color .16s ease;
}

.region-menu a:hover { background: var(--grey); }

.region-name { flex: 1; }

.region-menu a[aria-current] { background: var(--soft); color: var(--soft-text); }


/* Mega menus */
.mega { display: none; }
.mega.is-open { display: block; }

.mega-card { padding: 0 0 12px; }

.mega-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mega-item {
  display: block;
  padding: 12px 10px;
  border-radius: var(--edge);
  color: var(--ink);
  text-decoration: none;
  transition: background-color .16s ease;
}

.mega-item:hover,
.mega-item:focus-visible { background: var(--grey); }

.mi-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-bottom: 12px;
  border-radius: 6px;
  /* Flat, no gradient. The same lilac the secondary buttons use, so the tile
     is not a new colour, with the violet that pairs with it. 7.66:1. */
  background: var(--soft);
  color: var(--soft-text);
}

.mi { width: 19px; height: 19px; }

.mi-title {
  display: block;
  margin-bottom: 4px;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.35;
}

.mi-desc {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

/* Grouped mega menu: a product beside a labelled set of features */
.mega-groups { display: grid; gap: 20px; }

.mega-label {
  margin: 0 0 6px;
  padding-left: 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* Action strip along the bottom of the mega card */
.mega-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
  padding: 14px 16px;
  background: var(--grey);
  border-radius: 8px;
}

.mega-foot p {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

.mega-foot .btn { flex: none; }

/* Domain search sits in the strip on the Domains menu */
.dsearch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  margin: 0;
}

.dsearch-input {
  flex: 1 1 160px;
  min-width: 0;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
}

.dsearch-input:focus-visible { border-color: var(--brand); }

/* ---------------------------------------------------------------
   Hero, on the dark band
   --------------------------------------------------------------- */

.hero { padding: 40px 0 56px; }

.hero { position: relative; overflow: hidden; }

.hero-grid {
  position: relative;
  text-align: center;
}

.hero-copy {
  position: relative;
  z-index: 1;
  max-width: 800px;
  margin: 0 auto;
}

/* Split hero: copy left, illustration right, used on the product pages.
   Qualified with .hero-grid so it beats the centred rule above on
   specificity rather than depending on source order. */
.hero-grid.hero-split { text-align: left; }

.hero-split .hero-copy {
  max-width: 620px;
  margin: 0;
}

.hero-split .lede {
  margin-left: 0;
  margin-right: 0;
}

.hero-split .hero-actions { justify-content: flex-start; }

/* Feature ticks under the lede. Two columns so six points read as a short
   block rather than a long list. */
.hero-ticks {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px 26px;
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
}

.hero-ticks li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink-2);
}

.tick {
  width: 17px;
  height: 17px;
  margin-top: 2px;
  flex: none;
  fill: none;
  stroke: var(--brand-light);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hero-split .hero-note { text-align: left; }

/* hidden until there is a second column worth having */
.hero-art-side { display: none; }

.hero-svg { display: block; width: 100%; height: auto; }/* Offer badge above the heading: solid tag, then the wording.
   Parked, not currently in the markup. To bring it back, drop this
   above the h1 in the hero:
   <p class="eyebrow"><span class="eyebrow-tag">Offer</span><span
   class="eyebrow-text">Your wording here</span></p> */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  padding: 5px 14px 5px 5px;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 6px;
}

.eyebrow-tag {
  flex: none;
  padding: 4px 9px;
  border-radius: 4px;
  background: var(--brand);
  color: #ffffff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.eyebrow-text {
  font-size: 13px;
  font-weight: 600;
  color: #ffffff;
}

h1 {
  font-size: clamp(34px, 8vw, 60px);
  margin: 0 0 18px;
  color: var(--ink);
}

.lede {
  margin: 0 auto 28px;
  max-width: 34em;
  font-size: 17px;
  color: var(--ink-2);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-bottom: 20px;
}

.hero-actions .btn { flex: 1 1 auto; min-width: 160px; }

.hero-note {
  margin: 0;
  font-size: 14px;
  color: var(--ink-2);
}


/* ---------------------------------------------------------------
   Light band variant. Everything sitting on .topband is built for a dark
   background, so each piece needs a light counterpart: the logo, the nav
   text, the outlined controls and the strip.
   --------------------------------------------------------------- */


.nav-toggle { border-color: rgba(13, 21, 38, .20); }
.nav-toggle:hover { background: rgba(13, 21, 38, .05); }
.nav-bar { background: var(--ink); }

/* search row */
.hsearch-form { box-shadow: none; }

.hsearch-form:focus-within {
  box-shadow: 0 0 0 5px rgba(98, 0, 253, .16),
              0 10px 26px rgba(46, 22, 92, .16);
}


/* ---------------------------------------------------------------
   Domain search. Parked, not currently in the markup. To bring it back,
   drop a <section class="domains" id="domains"> holding a .sec-head, a
   <form class="dfind"> with .dfind-input and a submit button, a
   <p class="dfind-msg" id="domainMsg">, a <ul class="tlds"> and a
   <p class="dfind-note">. The validation in main.js already looks for
   .dfind and #domainSearch, so it will start working again on its own.
   --------------------------------------------------------------- */

.domains {
  background: linear-gradient(115deg, #ffffff 0%, #faf8ff 55%, #f1e9ff 100%);
  border-bottom: 1px solid var(--line);
  padding: 48px 0;
}

.dfind {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  max-width: 660px;
  margin: 0 auto;
}

.dfind-input {
  flex: 1 1 240px;
  min-width: 0;
  min-height: 52px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}

.dfind-input::placeholder { color: #8b95a5; }

.dfind-input:focus-visible {
  border-color: var(--brand);
  outline-offset: 1px;
}

.dfind-input.is-wrong { border-color: #b3261e; }

.dfind-btn { flex: 0 0 auto; min-height: 52px; padding: 12px 28px; }

.dfind-msg {
  max-width: 660px;
  margin: 10px auto 0;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
  min-height: 1.5em;
}

.dfind-msg.is-wrong { color: #b3261e; }

.tlds {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 660px;
  margin: 18px auto 0;
  padding: 0;
  list-style: none;
}

.tlds li {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #ffffff;
  font-size: 14px;
  font-weight: 600;
  color: var(--soft-text);
}

.dfind-note {
  max-width: 52ch;
  margin: 18px auto 0;
  text-align: center;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Boxed hero: search row, then a light card on the dark page
   --------------------------------------------------------------- */

/* almost flush to the header. Qualified with .hero so a later
   .hero padding rule in a wider breakpoint cannot override it. */
.hero.hero-boxed {
  /* colour comes from .topband, so the header pill and the hero sit on one
     unbroken block rather than two that have to be kept in step */
  padding: 8px 0 40px;
  /* The base .hero clips its overflow, which was cutting the top off the
     search field focus ring since the field sits flush to the section edge.
     This variant has no side illustrations to contain, and body already has
     overflow-x: clip, so nothing can scroll sideways. */
  overflow: visible;
}

/* Light-on-dark copy for the band. Scoped to .hero rather than .hero-boxed,
   because every page's hero now sits on the same violet block. Measured
   against #6200fd: white 7.2, lede 4.7, notes 5.0, highlight 3.7 to 4.6.
   Notes and ticks were #c9bce8 and #c961fe, which cleared #320066 but come
   in at 4.03 and 2.26 on this lighter ground, so both are raised. */
.hero h1 { color: #ffffff; }

/* Flat, not clipped to a gradient. That also lets the highlight go back to
   plain inline text: the inline-block and the padding/margin pair below it
   only existed so background-clip: text would not cut the descenders, and
   the inline-block was what let a line break fall before a trailing comma. */
.hero .hl,
.hero .hl-ink {
  display: inline;
  background: none;
  padding-bottom: 0;
  margin-bottom: 0;
  color: #fdb9ff;
  -webkit-text-fill-color: #fdb9ff;
}

.hero .lede { color: #d8ccf2; }
.hero .hero-note { color: #ded4f2; }
.hero .hero-ticks li { color: #d8ccf2; }
.hero .hero-ticks .tick { stroke: #e9b8ff; }

/* the light-band focus halo would disappear here, so the band gets the
   violet-on-dark one back */
.hero-boxed .hsearch-form:focus-within {
  box-shadow: 0 0 0 5px rgba(201, 97, 254, .28),
              0 10px 28px rgba(6, 4, 24, .34);
}

/* the screenshot is nearly white and separates from the band on its own.
   A dark drop shadow on a dark ground only muddies its edges. */

/* search row */
.hsearch {
  display: grid;
  gap: 14px;
  margin-bottom: 36px;
}

/* The shared message block reserves a line of height so errors do not shift
   the layout. In this hero it sat between the field and the card, holding it
   down by a line and a half of nothing, so here it collapses when empty. */
.hero-boxed .dfind-msg {
  min-height: 0;
  margin: 0;
  text-align: left;
}

.hero-boxed .dfind-msg:not(:empty) { margin: 8px 0 0; }

.hsearch-form {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 10px;
  /* a ring rather than a border, so nothing shifts when it appears */
  box-shadow: 0 0 0 0 rgba(201, 97, 254, 0), 0 0 0 rgba(6, 4, 24, 0);
  transition: box-shadow .2s ease;
}

/* No hard ring. The field lifts off the band with a soft violet halo, which
   reads as active without drawing a line next to the violet button beside it.
   focus-within, so clicking the magnifier counts too. */
.hsearch-form:focus-within {
  box-shadow: 0 0 0 5px rgba(201, 97, 254, .18),
              0 10px 28px rgba(6, 4, 24, .34);
}

.hsearch-form:focus-within .hsearch-icon { stroke: var(--brand); }

.hsearch-icon {
  width: 22px;
  height: 22px;
  margin-left: 12px;
  flex: none;
  fill: none;
  stroke: #8b95a5;
  stroke-width: 1.9;
  stroke-linecap: round;
}

.hsearch-input {
  flex: 1;
  min-width: 0;
  min-height: 50px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
}

.hsearch-input:focus { outline: none; }
.hsearch-input::placeholder { color: #8b95a5; }

.hsearch-btn { flex: none; min-height: 50px; padding: 12px 32px; }/* colour comes from the .hero-boxed band rules above */
.hero-boxed .hero-copy { max-width: none; margin: 0; text-align: left; }

/* ---------------------------------------------------------------
   Metrics strip and onboarding steps
   --------------------------------------------------------------- */

/* ---------------------------------------------------------------
   Section rules
   --------------------------------------------------------------- */

/* A rule between every pair of sections, never above the first one, so the
   hero still runs straight into the page. Two tones: a hairline in the line
   colour with a white line under it, which reads as a small step down into
   the next section rather than a line drawn between them. The white half
   only shows where the section below is tinted. */
main > section + section {
  border-top: 1px solid var(--line);
  box-shadow: inset 0 1px 0 #ffffff;
}

/* Three exceptions. The logo strip is a band rather than a section of the
   page, so it is left to float without a rule on either side of it, and the
   closing call to action already sits on its own dark card, which is edge
   enough without a line above it as well. */
.clients,
.clients + section,
.cta {
  border-top: 0;
  box-shadow: none;
}

/* ---------------------------------------------------------------
   Client wall
   --------------------------------------------------------------- */

.clients {
  background: #ffffff;
  padding: 28px 0;
}

.clients-eyebrow {
  margin: 0 0 18px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* Edges fade rather than cut, so logos arrive and leave instead of being
   clipped in half at the boundary. A mask, so it works over any background. */
.client-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 18%, #000 82%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 18%, #000 82%, transparent);
}

.client-track {
  display: flex;
  width: max-content;
  /* 46s, not 41. A ninth logo made one copy about 12 per cent wider, so the
     duration goes up by the same 12 per cent and the strip travels at the
     speed it did before. */
  animation: client-marquee 46s linear infinite;
}

/* the gap lives on the items, including the last one, so the seam between
   the two copies is the same width as every other gap. A gap on the flex
   container would leave the join half a gap short. */
.client-logos {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.client-logos li {
  flex: none;
  margin-right: 40px;
}

/* The track holds four identical copies, so shifting it by 25 per cent moves
   it exactly one copy and it lands on a frame identical to the one it started
   on. The join is invisible. It never pauses: the only thing that stops it is
   a reduced motion preference, at the end of this file. */
@keyframes client-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-25%); }
}

/* Set by height, not width. Logos come in wildly different aspect ratios and
   matching their widths makes a wide wordmark tower over a square mark. The
   max-width is a guard for anything unusually long. */
.client-logo {
  display: block;
  width: auto;
  height: 26px;
  max-width: 170px;
  object-fit: contain;
  /* The logos arrive here already reduced to one flat colour, baked into
     the assets themselves rather than filtered at render time. Unrelated
     brand palettes side by side is what makes these rows look untidy, and a
     single ink also settles the contrast question: every mark now sits at
     the same 4.8:1 on white instead of one of them at 2.0. */
}

/* A long wordmark set to the same cap height as a compact mark ends up
   several times wider and swamps the row, so the width cap binds first and
   the height falls out of it. Add this to anything past roughly 8:1. */
.client-logo-wide {
  height: auto;
  max-height: 26px;
  width: 210px;
  max-width: 100%;
}

/* The opposite case. A mark that stacks two or three bands spends most of
   its height on things that are not the name, so matched at the common
   height the name itself comes out much smaller than its neighbours. Add
   this to anything squarer than about 3:1. */
.client-logo-tall {
  height: 34px;
  max-width: 108px;
}

/* A solid filled badge carries far more ink than a wordmark of the same
   height, so matching heights makes it dominate the row. Set a few pixels
   shorter to even the weight out. */
.client-logo-badge {
  height: 30px;
  max-width: 108px;
}

/* ---------------------------------------------------------------
   Three plain facts
   --------------------------------------------------------------- */

/* Joined cells over a line coloured background, the same construction as the
   product and ethos rows above and below it. The shared edges read as one
   statement in three parts rather than three loose paragraphs. */
.facts {
  background: #ffffff;
  padding: 56px 0;
}

.fact-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  max-width: var(--panel-row);
  margin: 0 auto;
  padding: 0;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  list-style: none;
}

.fact-list > li {
  background: #ffffff;
  padding: 22px 20px 24px;
}

.fact-title {
  /* These carry the section on their own, since there is no heading above
     the row. At 18px they read as list item labels. The widest of the three
     is 324px at this cap against a 392px column, so there is room. */
  margin: 0 0 13px;
  font-size: clamp(20px, 2vw, 25px);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.02em;
  color: var(--ink);
}

.fact-desc {
  /* Around 46 characters a line at three across. Any wider and the three
     columns stop reading as three columns. */
  max-width: 46ch;
  margin: 0;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Product cards
   --------------------------------------------------------------- */

.products {
  background: #ffffff;
  padding: 56px 0 8px;
}

/* Ranged left, and at the row measure rather than a narrower centred block,
   so every heading starts on the same axis as the cards or the list beneath
   it. The lede below keeps its own reading measure. */
.sec-head {
  max-width: var(--panel-row);
  margin: 0 auto 32px;
  text-align: left;
}

.sec-head h2 {
  margin: 0 0 14px;
  /* One size for every section heading on the site, matched to the speed
     section which set it. The longest of them, "What staying independent
     actually buys you", needs 758px at this cap against the 880px measure,
     so all of them hold one line where they are meant to. */
  font-size: clamp(29px, 3.4vw, 42px);
}

/* Controlled line breaks. Inline on narrow screens so the text wraps
   naturally, forced onto their own lines once there is room. */
.line { display: inline; }

@media (min-width: 620px) {
  /* any heading that sets its own breaks opts out of balancing, not just
     the section ones */
  h1:has(.line),
  h2:has(.line),
  h3:has(.line) { text-wrap: initial; }
  .line { display: block; }
}

/* Heading accent for light backgrounds. The dark-band .hl runs much
   lighter and would be unreadable here. */
.hl-ink {
  display: inline-block;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  background: linear-gradient(96deg, #4d00c9, #9d3df5);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* The heading wants the extra width; a line of 17px body text does not.
   Around 64 characters is where it stays comfortable to read. */
.sec-lede {
  max-width: 64ch;
  margin: 0;
  font-size: 17px;
  color: var(--ink-2);
}

/* Small label above a section heading. Tracked out, because at this size
   uppercase set solid is hard to read. 13px is the floor: anything smaller
   and the letter-spacing stops rescuing it. */
.sec-eyebrow {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--soft-text);
}

.cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  list-style: none;
  margin: 0;
  padding: 0;
}

.card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #ffffff;
  color: var(--ink);
  text-decoration: none;
  transition: background-color .18s ease;
}

.card:hover { background: #faf9fd; }

.card-art {
  display: block;
  position: relative;
  line-height: 0;
  border-bottom: 1px solid var(--line);
}

/* Every illustration panel on the page, product cards and ethos cards alike.
   One weight of line, no fills, a ruling you have to look for, and room
   around the mark. The three values the drawings read from live here, so the
   whole set recolours without touching eight SVGs. */
.panel-art {
  --ground: #0f0b20;
  --grid: rgba(255, 255, 255, .055);
  --ico: #c961fe;
}

/* Hover lights the ruling rather than washing the panel in colour: the same
   grid again in white, revealed through a soft circle that follows the
   pointer. Only the opacity is transitioned. Moving the mask centre smoothly
   would make the light lag behind the cursor instead of sitting under it. */
.grid-lit {
  /* The ruling underneath sits at .055, so this is about three times it
     rather than six. Enough to read as the lines catching the light, not
     enough to become a second grid. */
  stroke: rgba(255, 255, 255, .16);
  opacity: 0;
  transition: opacity .28s ease;
  -webkit-mask-image: radial-gradient(circle at var(--mx, 50%) var(--my, 48%),
                                      #000 0%, rgba(0, 0, 0, 0) 46%);
          mask-image: radial-gradient(circle at var(--mx, 50%) var(--my, 48%),
                                      #000 0%, rgba(0, 0, 0, 0) 46%);
}

.card:hover .grid-lit,
.card:focus-visible .grid-lit,
.plat-item:hover .grid-lit,
.ethos-item:hover .grid-lit,
.speed-art:hover .grid-lit { opacity: 1; }

.card-art svg { display: block; width: 100%; height: auto; }

.card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  /* extra top padding to clear the badge hanging over the seam */
  padding: 34px 18px 20px;
}

.card-title {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -.02em;
}

.card-desc {
  display: block;
  flex: 1;
  margin-bottom: 14px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

/* Price pill floating on the illustration panel. System font, since
   Familjen Grotesk is reserved for headings. */
.card-badge {
  position: absolute;
  /* 18px matches the card body padding, so the pill lines up with the
     title below it. Sits astride the seam. */
  left: 18px;
  bottom: 0;
  transform: translateY(50%);
  z-index: 2;
  padding: 7px 13px;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 6px 18px rgba(6, 4, 24, .3);
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
  color: var(--brand);
}

.card-badge strong {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* Looks like a button, but it is a span: the whole card is already the
   link, so a real button here would nest one control inside another
   and add a second tab stop for the same destination. */
.card-btn {
  align-self: flex-start;
  padding: 9px 18px;
}

.card:hover .card-btn { background: var(--soft-hover); }

.cards-note {
  margin: 26px auto 0;
  text-align: center;
  max-width: 74ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
}

.cards-note a { font-weight: 600; white-space: nowrap; }

/* Money back guarantee callout. Same dark band as the CTA card.
   Parked, not currently in the markup. To bring it back, drop this
   after the .cards-note paragraph in the products section:
   <div class="guarantee"> [cta-streaks svg]
     <span class="guarantee-tile"><svg class="guarantee-icon"><use
       href="#i-shield"></use></svg></span>
     <span class="guarantee-text"><strong>Title</strong><span>Body</span></span>
   </div> */
.guarantee {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 860px;
  margin: 34px auto 0;
  padding: 28px 24px;
  text-align: center;
  border-radius: 10px;
  background: linear-gradient(165deg, #14102b, #1c1740 42%, #262055 76%, #2e2766);
}

.guarantee-tile {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  /* matches the mega menu tiles: light gradient, dark glyph */
  background: linear-gradient(135deg, var(--brand-light), var(--brand-pink));
}

.guarantee-icon {
  width: 25px;
  height: 25px;
  fill: none;
  stroke: var(--tile);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.guarantee-text { position: relative; }

.guarantee-text strong {
  display: block;
  margin-bottom: 6px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: #ffffff;
}

.guarantee-text span {
  display: block;
  font-size: 15px;
  line-height: 1.6;
  color: #cfc9e8;
}

/* ---------------------------------------------------------------
   Stats band. Parked, not currently in the markup. To bring it back, drop a
   <section class="stats"> holding a .sec-head.sec-head-dark and a
   <ul class="stat-list"> of .stat-figure and .stat-label pairs.
   --------------------------------------------------------------- */

.stats {
  background: linear-gradient(165deg, #14102b, #1c1740 42%, #262055 76%, #2e2766);
  padding: 48px 0;
}

.stat-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px 20px;
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: center;
}

/* Display type, so Familjen Grotesk rather than the body stack */
.stat-figure {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(32px, 7vw, 50px);
  line-height: 1.05;
  letter-spacing: -.03em;
  padding-bottom: 0.1em;
  background: linear-gradient(96deg, #c961fe, #fdb9ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.stat-label {
  display: block;
  max-width: 24ch;
  margin: 0 auto;
  font-size: 15px;
  line-height: 1.5;
  color: #cfc9e8;
}


/* ---------------------------------------------------------------
   Ethos cards, on the dark band
   --------------------------------------------------------------- */

.ethos {
  /* The only tinted section on the page apart from the WordPress block, so
     the four claims sit on something rather than floating on white with
     everything else. */
  background: #f7f6fb;
  padding: 56px 0;
}

/* Mark beside the words rather than a panel above them. The page already
   runs three rows of joined cards; a fourth read as more of the same, and
   this halves the height of the section into the bargain. */
.ethos-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  max-width: var(--panel-row);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

/* White cards on the tint, rather than joined cells over a hairline. Not
   joined, because at two across a joined pair reads as one wide box with a
   line down it. */
.ethos-list li {
  display: flex;
  gap: 18px;
  /* centred against the whole card, not pinned to the first line of it. The
     paragraphs run to three or four lines, so aligned to the top the tile
     sat well above the middle of everything beside it. */
  align-items: center;
  padding: 22px 20px 24px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* The one piece of motion left in here. The clock and the uptime trace went
   with the two claims they illustrated. Stops under prefers-reduced-motion
   with everything else. */
.ethos-drop { animation: ethosDrop 3.6s ease-in-out infinite; }

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

/* Sits under the row, on the same axis as the heading above it. The four
   cards are the short version of this argument; the About page carries the
   long one. */
.ethos-more {
  max-width: var(--panel-row);
  margin: 26px auto 0;
}

.ethos-title {
  margin: 0 0 6px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
}

.ethos-desc {
  margin: 0;
  max-width: 46ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Support
   --------------------------------------------------------------- */

.help {
  background: #ffffff;
  padding: 52px 0;
}

/* One rounded block holding both. Stacked it is video then card; wide, the
   video fills the block and the card floats over the right of it. The card
   stays in normal flow either way, so it is the card that sets the height
   and long copy can never be clipped by the video's aspect ratio. */
.help-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  max-width: var(--panel-row);
  margin: 0 auto;
  border-radius: 16px;
  overflow: hidden;
  /* What shows before the video loads, and instead of it on a phone or a
     metered connection where it is never fetched. The panel ruling rather
     than a flat colour, so an empty block still looks like the rest of the
     site rather than a hole. Done in CSS because the block has no fixed
     aspect: an SVG ruling would stretch with it. */
  background:
    radial-gradient(115% 105% at 50% 45%, rgba(15, 11, 32, 0) 30%, #0f0b20 100%),
    repeating-linear-gradient(to right, rgba(255, 255, 255, .055) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(to bottom, rgba(255, 255, 255, .055) 0 1px, transparent 1px 40px),
    #0f0b20;
}

.help-media { aspect-ratio: 16 / 9; }

.help-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.help-card {
  background: #ffffff;
  padding: 26px 22px 28px;
}

.help-statement {
  margin: 0 0 22px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: clamp(20px, 2.4vw, 27px);
  line-height: 1.35;
  letter-spacing: -.02em;
  color: var(--ink);
  text-wrap: balance;
}

.help-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.help-list li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin-bottom: 13px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink-2);
}

.help-list li:last-child { margin-bottom: 0; }

.help-icon {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  /* the sprite entries are bare paths, so the weight comes from here */
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (min-width: 700px) {
  .help-card { padding: 32px 30px 34px; }
}

@media (min-width: 1160px) {
  .help-block {
    grid-template-columns: minmax(0, 1fr) minmax(0, 470px);
    align-items: center;
    min-height: 540px;
  }

  /* out of flow and behind, so the card decides the height and the video
     covers whatever that turns out to be */
  .help-media {
    position: absolute;
    inset: 0;
    aspect-ratio: auto;
  }

  .help-block { position: relative; }

  .help-card {
    position: relative;
    z-index: 1;
    grid-column: 2;
    margin: 30px;
    border-radius: 12px;
    padding: 38px 34px 40px;
  }
}

/* ---------------------------------------------------------------
   Speed
   --------------------------------------------------------------- */

.speed {
  background: #ffffff;
  padding: 52px 0;
}

.speed-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  max-width: var(--panel-row);
  margin: 0 auto;
}

@media (min-width: 1160px) {
  /* Not at 700: a 440px panel next to the text leaves the text about 250px
     at that width, narrower than the drawing beside it. */
  .speed-split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 440px);
    align-items: center;
    gap: 56px;
  }
}

.speed-text h2 {
  /* Not inside a .sec-head, so it needs its own declaration, but the same
     numbers: this is the heading the rest were matched to. "Fast before you
     change a thing" is 525px at the cap against a 616px column at 1160,
     where the column is at its narrowest. */
  margin: 0 0 16px;
  font-size: clamp(29px, 3.4vw, 42px);
}

.speed-text p {
  margin: 0 0 16px;
  font-size: 16px;
  line-height: 1.65;
  max-width: 56ch;
  color: var(--ink-2);
}

.speed-note { margin-bottom: 0; }
.speed-note a { font-weight: 600; }

/* Square, and held there. Stretched to the height of the text beside it the
   drawing would be sliced and the chip would lose its outer traces. */
.speed-art {
  aspect-ratio: 1 / 1;
  align-self: center;
  border-radius: 12px;
  overflow: hidden;
  line-height: 0;
}

.speed-art svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* A pulse running the chip's own outline. The rounded rect measures
   2 x (144 - 28) twice for the straights plus one whole 14 radius circle for
   the four corners, so 464 + 88 = 552, and the dash and the gap add up to
   that. Get it wrong and the pulse jumps on every repeat. Stops under
   prefers-reduced-motion with everything else, through the blanket rule near
   the end of the file. */
.speed-pulse {
  stroke: rgba(255, 255, 255, .8);
  stroke-dasharray: 56 496;
  animation: speedPulse 6s linear infinite;
}

@keyframes speedPulse {
  from { stroke-dashoffset: 552; }
  to { stroke-dashoffset: 0; }
}

/* ---------------------------------------------------------------
   The platform
   --------------------------------------------------------------- */

.platform {
  background: #ffffff;
  /* 56 at the bottom, not 8. The six tiles used to run almost into whatever
     followed them, which with a rule between sections put the icons within a
     few pixels of the line. */
  padding: 56px 0;
}

/* Not joined into one panel like the product and ethos rows. Six of these
   under a shared heading is already a lot of ruled dark squares, and boxing
   them as well would turn the middle of the page into a grid of grids. */
.plat-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 34px 30px;
  max-width: var(--panel-row);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

@media (min-width: 700px) {
  .plat-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1160px) {
  .plat-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The panel recipe again at a quarter of the size: same ground, same faint
   ruling, same single weight mark. Rounded a little tighter than the cards
   because the corner radius has far less edge to sit on. */
.plat-tile,
.ethos-tile {
  display: block;
  width: 72px;
  height: 72px;
  margin-bottom: 16px;
  border-radius: 12px;
  overflow: hidden;
  line-height: 0;
}

.plat-tile svg,
.ethos-tile svg {
  display: block;
  width: 100%;
  height: 100%;
}

.plat-name {
  margin: 0 0 7px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -.02em;
  color: var(--ink);
}

.plat-desc {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Included with every plan
   --------------------------------------------------------------- */

.incl {
  background: #ffffff;
  padding: 48px 0 8px;
}

.incl-card {
  padding: 28px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: linear-gradient(115deg, #ffffff 0%, #faf8ff 55%, #f1e9ff 100%);
}

.incl-title {
  margin: 0 0 24px;
  font-size: clamp(29px, 3.4vw, 42px);
  line-height: 1.15;
}

.incl-title span { display: block; }

.incl-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Soft round badge behind each icon */
.incl-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 14px;
  border-radius: 50%;
  background: var(--soft);
}

.incl-icon {
  display: block;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--brand);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.incl-name {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: -.02em;
}

.incl-desc {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   About page
   --------------------------------------------------------------- */

.band {
  background: #ffffff;
  padding: 48px 0;
}

.sec-head-dark h2 { color: var(--ink); }
.sec-head-dark .sec-lede { color: var(--ink-2); }

.two-col {
  display: grid;
  gap: 8px;
}

.prose p {
  margin: 0 0 16px;
  max-width: 62ch;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

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

.careers-card {
  padding: 28px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: linear-gradient(115deg, #ffffff 0%, #faf8ff 55%, #f1e9ff 100%);
}

.reviews-note {
  margin: 0 auto;
  max-width: 62ch;
  text-align: center;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.careers-card { text-align: center; }

.careers-card .sec-head { margin-bottom: 16px; }

.careers-note {
  margin: 0 auto 18px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   WordPress explainer, dark card on white
   --------------------------------------------------------------- */

.wp {
  background: #f7f6fb;
  padding: 40px 0;
}

.wp-card {
  display: grid;
  /* Pulled in from the full 1472px measure onto the same axis as the card
     rows above and below it. Left to fill .wrap it ran about 190px wider
     than everything else on the page. */
  max-width: var(--panel-row);
  margin-inline: auto;
  gap: 28px;
  padding: 22px 20px;
  border-radius: 10px;
  background: #ffffff;
  border: 1px solid var(--line);
}

.wp-eyebrow {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--brand);
}

.wp-lead h2 {
  margin: 0 0 18px;
  font-size: clamp(29px, 3.4vw, 42px);
  color: var(--ink);
}

.wp-lead p {
  margin: 0 0 16px;
  max-width: 46ch;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

/* Prose links only. Unqualified, this also caught the button below it: a
   class plus an element outranks .btn-solid's single class, so it was
   overriding the white text with ink and underlining the button as well. */
.wp-lead p a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.wp-lead p a:hover { color: var(--brand-dark); }

.wp-cta {
  gap: 10px;
  margin-top: 10px;
  text-decoration: none;
}

.wp-arrow {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

.wp-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
}

.wp-list li {
  display: flex;
  gap: 16px;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}

.wp-list li:first-child { border-top: 0; padding-top: 0; }

/* Same tile the mega menu uses, so the two read as one system. Sized to sit
   against the first line of the heading rather than the top of the block. */
.wp-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 34px;
  height: 34px;
  margin-top: 1px;
  border-radius: 6px;
  background: var(--soft);
  color: var(--soft-text);
}

.wp-glyph {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A slow rise and fall, 4px over six seconds. Small on purpose: these sit
   beside body copy, and anything faster or further turns into something you
   have to read around. Only transform moves, so it stays on the compositor
   and costs nothing to run. */
@keyframes wp-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

.wp-icon { animation: wp-float 6s ease-in-out infinite; }

/* Negative delays, so each one starts already part way through rather than
   waiting its turn. Otherwise the column moves as a single block. */
.wp-list li:nth-child(2) .wp-icon { animation-delay: -1.2s; }
.wp-list li:nth-child(3) .wp-icon { animation-delay: -2.4s; }
.wp-list li:nth-child(4) .wp-icon { animation-delay: -3.6s; }
.wp-list li:nth-child(5) .wp-icon { animation-delay: -4.8s; }

.wp-text h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--ink);
}

.wp-text p {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Reviews
   --------------------------------------------------------------- */

/* ---------------------------------------------------------------
   Reviews. Parked, not currently in the markup. Taken off the homepage
   while the ten dummy entries wait to be replaced by real ones. To bring it
   back, drop a <section class="reviews"> holding a .sec-head and a
   <ul class="reviews-list is-clamped" id="reviewList"> of <li><article
   class="review"> blocks, each with a .review-by, a .review-meta and a
   .review-body, then a <button class="btn btn-soft" id="reviewMore">. The
   show-more script in main.js already looks for those two ids and does
   nothing when they are absent, so it starts working again on its own.
   .reviews-score, .reviews-figure, .reviews-outof and .reviews-count are
   the rating summary, which has never been in the markup.
   --------------------------------------------------------------- */

.reviews {
  background: #ffffff;
  padding: 48px 0 8px;
}

.reviews-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Applied by JS, so without JS all ten stay visible rather than
   being hidden behind a button that cannot work. */
.reviews-list.is-clamped > li:nth-child(n + 7) { display: none; }

/* Rating summary and star row. Parked, not currently in the markup.
   To bring it back, drop this above the reviews list:
   <div class="reviews-score"><span class="reviews-figure">4.8</span>
     <span class="reviews-outof">out of 5</span>
     <span class="stars" role="img" aria-label="4.8 out of 5">[5 x
       <svg class="star"><use href="#i-star"></use></svg>]</span>
     <a class="reviews-count" href="...">Based on 59 reviews</a></div> */
.reviews-score {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 12px;
  margin: 0 0 28px;
}

.reviews-figure {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 34px;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--ink);
}

.reviews-outof {
  font-size: 15px;
  color: var(--ink-2);
}

.stars {
  display: flex;
  gap: 3px;
  color: var(--brand);
}

.star {
  width: 17px;
  height: 17px;
  fill: currentColor;
  stroke: none;
  flex: none;
}

.reviews-count {
  font-size: 15px;
  font-weight: 600;
}

.review {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 20px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 10px;
}

/* name, then where it came from, then the review itself */
.review-by {
  margin: 0 0 2px;
  font-size: 15px;
  line-height: 1.4;
}

.review-by strong { font-weight: 600; color: var(--ink); }
.review-by span { color: var(--ink-2); }

.review-meta {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--ink-2);
}

.review-body {
  flex: 1;
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.reviews-more {
  margin-top: 24px;
  text-align: center;
}

.reviews-all {
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   Plan cards, app list and FAQ (web hosting page)
   --------------------------------------------------------------- */

.plans { background: #ffffff; padding: 48px 0; }

.plan-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 24px 22px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 10px;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.plan:hover {
  transform: translateY(-2px);
  border-color: #d7dbe4;
  box-shadow: 0 12px 26px rgba(13, 21, 38, .10);
}

/* the recommended one carries the brand edge, not a colour fill */
.plan.is-picked {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand);
}

.plan-tag {
  position: absolute;
  top: 0;
  left: 22px;
  transform: translateY(-50%);
  padding: 5px 11px;
  border-radius: 6px;
  background: var(--brand);
  color: #ffffff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.plan-name {
  margin: 0 0 6px;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.plan-blurb {
  margin: 0 0 16px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.plan-price {
  margin: 0 0 18px;
  font-size: 14px;
  color: var(--ink-2);
}

.plan-price strong {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--ink);
}

.plan-cta { width: 100%; margin-bottom: 20px; }

.plan-specs {
  list-style: none;
  margin: 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--line);
}

.plan-specs li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 7px 0;
  font-size: 15px;
  color: var(--ink-2);
}

.plan-specs strong {
  font-weight: 600;
  color: var(--ink);
  text-align: right;
}

.plans-note {
  max-width: 62ch;
  margin: 26px auto 0;
  text-align: center;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* apps */
.apps { background: #ffffff; padding: 40px 0; }

.app-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 760px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.app-list li {
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

/* faq, built on details so it works with no JS at all */
.faq { background: #ffffff; padding: 40px 0 56px; }

.faq-list {
  max-width: 820px;
  margin: 0 auto;
  border-top: 1px solid var(--line);
}

.faq-item { border-bottom: 1px solid var(--line); }

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  padding: 16px 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--brand-dark); }

.faq-mark {
  width: 18px;
  height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .2s ease;
}

.faq-item[open] .faq-mark { transform: rotate(180deg); }

.faq-body p {
  margin: 0;
  padding: 0 0 18px;
  max-width: 68ch;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

/* ---------------------------------------------------------------
   CTA band. Sits on white, so it paints over the dark band above.
   --------------------------------------------------------------- */

.cta {
  background: #ffffff;
  padding: 56px 0;
}

.cta-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  padding: 32px 26px;
  border-radius: 10px;
  background: linear-gradient(165deg, #100c24 0%, #171232 42%, #1d1745 76%, #241d54 100%);
}

/* Anchored right at its own aspect ratio. Stretching it across the whole
   card flattened the streak angle and thickened the strokes. */
.cta-streaks {
  /* Back to a band at the right hand end rather than the full card: across
     the whole width it was too much. The z-index pair stays, so the lines
     still pass behind the title and the buttons where they overlap. */
  position: absolute;
  top: 0;
  right: 0;
  z-index: 0;
  width: auto;
  height: 100%;
  pointer-events: none;
}

/* Lines falling down the card. Nine tracks, each with its own length,
   speed and a negative delay so they are already part way down on the first
   frame rather than all starting at the top together. Only transform moves,
   so the whole thing runs on the compositor. */
.cta-guides { opacity: 0.035; }

.cta-drop {
  animation-name: ctaFall;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

@keyframes ctaFall {
  from { transform: translateY(0); }
  to { transform: translateY(280px); }
}

.cta-drop-1 { animation-duration: 6.5s; animation-delay: -0.0s; }
.cta-drop-2 { animation-duration: 9.0s; animation-delay: -3.1s; }
.cta-drop-3 { animation-duration: 5.2s; animation-delay: -1.4s; }
.cta-drop-4 { animation-duration: 10.5s; animation-delay: -6.2s; }
.cta-drop-5 { animation-duration: 7.4s; animation-delay: -2.3s; }
.cta-drop-6 { animation-duration: 8.2s; animation-delay: -4.8s; }
.cta-drop-7 { animation-duration: 6.0s; animation-delay: -0.9s; }
.cta-drop-8 { animation-duration: 11.0s; animation-delay: -5.4s; }
.cta-drop-9 { animation-duration: 7.9s; animation-delay: -2.7s; }

.cta-title {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: clamp(21px, 3.4vw, 29px);
  line-height: 1.25;
  color: #ffffff;
}

.cta-title span { display: block; }

.cta-accent {
  padding-bottom: 0.14em;
  /* the ink gradient is unreadable on this: #4d00c9 lands at 1.4:1 against
     the darkest stop. Lilac to pink instead, 8.0:1 at its weakest point. */
  background: linear-gradient(96deg, #c961fe, #fdb9ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.cta-actions {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.cta-actions .btn { flex: 1 1 auto; min-width: 150px; }

/* ---------------------------------------------------------------
   Footer
   --------------------------------------------------------------- */

.foot {
  background: var(--tile);
  padding: 48px 0 24px;
  color: #c7c1dd;
}

.foot-top {
  display: grid;
  gap: 36px;
  padding-bottom: 32px;
}

.foot-logo {
  display: block;
  width: auto;
  height: 29px;
  margin-bottom: 18px;
}

.foot-brand p {
  margin: 0;
  max-width: 30em;
  font-size: 16px;
  color: #c7c1dd;
}

/* Social row, under the logo and the line of copy */
.social {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 8px;
  color: #c7c1dd;
  transition: color .16s ease, background-color .16s ease, border-color .16s ease;
}

.social a:hover {
  color: var(--tile);
  background: #ffffff;
  border-color: #ffffff;
}

/* filled marks, unlike the stroked icons elsewhere */
.social-icon {
  width: 19px;
  height: 19px;
  fill: currentColor;
  stroke: none;
}

.foot-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px 20px;
}

.foot-col h3 {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: #ffffff;
}

.foot-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot-col a,
.foot-legal a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 16px;
  color: #c7c1dd;
  text-decoration: none;
  transition: color .16s ease;
}

/* --brand-dark would be all but invisible here, so links brighten to white
   on hover instead of reaching for a colour. */
.foot-col a:hover,
.foot-legal a:hover { color: #ffffff; }

.foot-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 24px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, .12);
}

.foot-copy {
  margin: 0;
  font-size: 15px;
  color: #a49cc4;
}

.foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot-legal a { font-size: 15px; }

/* ---------------------------------------------------------------
   Wider screens
   --------------------------------------------------------------- */

@media (min-width: 700px) {
  .wrap { padding: 0 24px; }
  .hero { padding: 56px 0 80px; }

  .hero.hero-boxed { padding: 12px 0 56px; }

  /* Fill what is left of the viewport so the card bottom lands on the fold
     and no white shows above it. 131px is the utility strip plus the header,
     both of which sit in normal flow above this section.
     dvh rather than vh so a mobile address bar does not overshoot. */
  .hero.hero-boxed {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 131px);
    min-height: calc(100dvh - 131px);
    padding-bottom: 0;
  }

  .hero-boxed > .wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
  }  .hsearch {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 24px;
    margin-bottom: 48px;
  }  .hero-actions .btn { flex: 0 0 auto; }
  .hero-ticks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lede { font-size: 18px; }

  .cta-card { padding: 38px 36px; gap: 32px; flex-wrap: nowrap; }
  .cta-actions .btn { flex: 0 0 auto; }

  .domains { padding: 64px 0; }

  .clients { padding: 36px 0; }
  .client-logos li { margin-right: 50px; }
  .client-logo { height: 30px; max-width: 190px; }
  .client-logo-wide { width: 245px; max-height: 30px; }
  .client-logo-tall { height: 38px; max-width: 124px; }
  .client-logo-badge { height: 34px; max-width: 124px; }
  .facts { padding: 68px 0; }
  .fact-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .products { padding: 72px 0 16px; }
  .sec-head { margin-bottom: 40px; }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* icon beside the text once there is room */
  .guarantee {
    flex-direction: row;
    align-items: center;
    gap: 22px;
    text-align: left;
    padding: 32px 38px;
  }

  .stats { padding: 64px 0; }
  .stat-label { font-size: 16px; }

  .ethos { padding: 64px 0; }
  .ethos-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .plans { padding: 64px 0; }
  .plan-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
  .apps { padding: 56px 0; }
  .faq { padding: 56px 0 72px; }

  .wp { padding: 48px 0; }
  .wp-card { padding: 30px 32px; gap: 34px; }

  .reviews { padding: 64px 0 8px; }
  .reviews-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }

  .incl { padding: 64px 0 8px; }
  .incl-card { padding: 36px 32px; }

  .band { padding: 64px 0; }
  .two-col { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px; }
  .careers-card { padding: 36px 32px; }
  .incl-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 32px; }

  .foot { padding: 64px 0 28px; }
  .foot-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
}

@media (min-width: 1160px) {
  .nav-toggle { display: none; }

  .head-shell { padding: 8px 10px 8px 26px; }

  .nav {
    display: flex;
    align-items: center;
    gap: 16px;
    position: static;
    flex: 1;
    max-height: none;
    overflow: visible;
    padding: 0;
    background: none;
    border-radius: 0;
    box-shadow: none;
  }

  /* centred in the pill, with the logo left and the actions right */
  .nav-list {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    gap: 1px;
    margin: 0;
  }

  .nav-item { border-bottom: 0; }

  /* 12px sides rather than 14: six top level items need the room.
     Light text here because the bar sits on the dark band. The base rules
     above keep the mobile drawer dark on white. */
  .nav-link,
  .nav-trigger {
    width: auto;
    min-height: 44px;
    padding: 9px 12px;
    border-radius: 8px;
    color: var(--ink);
    font-size: 15px;
    /* 600 rather than 500. It was the only 500 on the site, and one extra
       weight of this family is 45KB of woff2 for a single rule. */
    font-weight: 600;
    transition: background-color .16s ease, color .16s ease;
  }

  .nav-link:hover,
  .nav-trigger:hover { background: rgba(13, 21, 38, .06); color: var(--ink); }

  .nav-trigger[aria-expanded="true"] { background: rgba(13, 21, 38, .07); color: var(--ink); }

  .chev { width: 14px; height: 14px; opacity: .55; }


  .nav-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
  }

  .nav-link,
  .nav-trigger { color: var(--ink); }

  .nav-link:hover,
  .nav-trigger:hover,
  .nav-trigger[aria-expanded="true"] {
    background: rgba(13, 21, 38, .06);
    color: var(--ink);
  }

  /* on a light band these go back to their normal fills */
  .nav-actions .btn-soft {
    background: var(--soft);
    color: var(--soft-text);
    border-color: transparent;
  }

  .nav-actions .btn-soft:hover { background: var(--soft-hover); }

  .nav-actions .btn-solid {
    background: var(--brand-dark);
    color: #ffffff;
    border-color: transparent;
  }

  .nav-actions .btn-solid:hover { background: var(--brand-deep); }

  /* Contact becomes an outline on the band. The soft violet fill is kept for
     the mobile drawer, where it sits on white. */
  .nav-actions .btn-soft {
    background: var(--soft);
    color: var(--soft-text);
    border-color: transparent;
  }

  .nav-actions .btn-soft:hover { background: var(--soft-hover); }

  /* Login goes white with ink text on the band. Desktop only: in the mobile
     drawer this button sits on white, where a white fill would vanish. */
  .nav-actions .btn-solid {
    background: var(--brand-dark);
    color: #ffffff;
    border-color: transparent;
  }

  .nav-actions .btn-solid:hover { background: var(--brand-deep); }

  /* The header row is full width but the panel is not: it stays a centred
     card up to --wrap, so the items do not stretch across a large monitor.
     Centred with margin auto rather than a transform, because the open
     animation uses transform and the two would fight. */
  .mega {
    position: absolute;
    left: 0;
    right: 0;
    width: min(var(--wrap), 100%);
    margin-inline: auto;
    top: calc(100% + var(--head-gap));
  }

  .mega.is-open {
    display: block;
    animation: megaIn .16s ease-out;
  }

  .mega-card {
    padding: 30px 32px;
    background: #ffffff;
    border: 1px solid var(--line);
    border-radius: 12px;
    /* it drops onto the violet block now, so a grey shadow would vanish */
    box-shadow: 0 18px 44px rgba(6, 4, 24, .30);
  }

  .mega-items {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    /* no column gap: the divider lives on the cell edge, and a gap on top of
       it makes the clearance uneven, wider on one side of a line than the
       other. The breathing room comes from the cell padding below instead. */
    column-gap: 0;
    row-gap: 8px;
  }

  /* hairline between columns, matching the reference */
  .mega-items > li + li { border-left: 1px solid var(--line); }

  /* The hover fill used to run the full width of the cell and butt straight
     into the hairline. Half the indent sits on the cell and half comes off
     the link, so the fill stops 12px clear of a divider on both sides while
     the text stays exactly where it was. */
  .mega-items > li { padding: 0 12px; }

  /* Menus with more than four items wrap to a fixed three across,
     otherwise the columns get too narrow to read. */
  .mega-items-wrap {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    row-gap: 22px;
  }

  /* first item of each row starts a fresh column, so no divider */
  .mega-items-wrap > li:nth-child(3n + 1) { border-left: 0; }

  .mega-item { height: 100%; padding: 6px 8px; }
  /* --grey, the same fill the action strip at the foot of the card uses.
     Keyboard focus gets the identical treatment: a hover-only affordance
     leaves anyone tabbing through the menu with nothing to follow. */
  .mega-item:hover,
  .mega-item:focus-visible { background: var(--grey); }

  .mega-item:hover .mi-title,
  .mega-item:focus-visible .mi-title { color: var(--brand-dark); }

  .mega-groups {
    grid-template-columns: minmax(0, 330px) minmax(0, 1fr);
    gap: 40px;
  }

  /* features sit three across, with the product set apart by a rule */
  .mega-group + .mega-group {
    padding-left: 40px;
    border-left: 1px solid var(--line);
  }

  .mega-group + .mega-group .mega-items {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .mega-label { margin-bottom: 10px; padding-left: 20px; }

  .mega-foot { margin-top: 20px; padding: 16px 20px; }

  .dsearch { width: auto; flex: 1; max-width: 520px; }

  .hero { padding: 96px 0 116px; }

  .hero.hero-boxed { padding: 20px 0 72px; }
  .hsearch { margin-bottom: 60px; }  /* the split hero carries an illustration, so it needs less padding
     than the centred one to sit at the same height on screen */
  .hero:has(.hero-split) { padding: 52px 0 84px; }

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

  .hero-split {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
    align-items: center;
    gap: 48px;
  }

  .hero-art-side { display: block; }

  .domains { padding: 80px 0; }

  .clients { padding: 44px 0; }
  .client-logos li { margin-right: 58px; }
  .client-logo { height: 34px; max-width: 205px; }
  .client-logo-wide { width: 280px; max-height: 34px; }
  .client-logo-tall { height: 44px; max-width: 134px; }
  .client-logo-badge { height: 38px; max-width: 134px; }
  .facts { padding: 84px 0; }
  /* both sides of the rule between these two, so it has room to be seen */
  .platform, .help { padding: 76px 0; }
  .fact-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .fact-list > li { padding: 26px 24px 28px; }

  .products { padding: 88px 0 24px; }
  /* Both joined rows are pulled in from the full 1472px measure and centred
     on the same axis as the headings above them. Same variable, so they line
     up with each other rather than only happening to agree. */
  .cards { max-width: var(--panel-row); margin-inline: auto; }
  .ethos-list { gap: 24px; }
  .ethos-list li { padding: 26px 24px 28px; }

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

  .stats { padding: 84px 0; }

  .ethos { padding: 84px 0; }
  .ethos-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the padding belongs to the text now, or it puts a white margin back
     around the illustration at this width */
  .ethos-body { padding: 20px 20px 24px; }

  .plans { padding: 84px 0; }
  .plan-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .plan { padding: 28px 26px; }
  .apps { padding: 64px 0; }
  .faq { padding: 64px 0 88px; }

  .wp { padding: 56px 0; }
  .wp-card {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    /* The list of five runs a good deal taller than the lead beside it.
       Centred, the shortfall is split between top and bottom instead of
       sitting as one dead run under the button. */
    align-items: center;
    gap: 60px;
    padding: 34px 44px;
  }

  .reviews { padding: 84px 0 8px; }
  .reviews-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .review { padding: 24px; }

  /* four across, with hairlines between the columns */
  .stat-list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; }
  .stat-list > li + li { border-left: 1px solid rgba(255, 255, 255, .13); }

  .band { padding: 88px 0; }
  .careers-card { padding: 44px 44px; }

  /* heading sits to the left of the four features */
  .incl { padding: 80px 0 8px; }
  .incl-card {
    display: grid;
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    align-items: center;
    gap: 56px;
    padding: 44px 44px;
  }
  .incl-title { margin: 0; }
  .incl-list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; }

  .cta { padding: 72px 0; }
  .cta-card { padding: 44px 48px; }

  .foot { padding: 72px 0 32px; }

  .foot-top {
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    gap: 72px;
    padding-bottom: 40px;
  }
}

/* Only once the 800px copy column leaves real space either side */
@media (min-width: 1340px) {  .hero { padding: 108px 0 128px; }
}

@keyframes megaIn {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, .mega.is-open { animation: none !important; transition: none !important; }
}


/* The frame around the video block, and nothing else: every section below
   the hero is opaque and the bar sits on the video, not on this. White at
   the left running into pink at the right. Three stops rather than two, so the
   fall is even across the strip instead of bunching in the middle. Nothing
   sits on this, so there is no contrast to hold. */
.topband-film {
  background: linear-gradient(to right, #ffffff 0%, #ffeaff 45%, #fdc4ff 100%);
}


/* ---------------------------------------------------------------
   Film hero. Appended at the end on purpose: .hero-boxed sets padding in
   three separate breakpoints further up, and these rules share its
   specificity, so they have to come last to win on source order.
   --------------------------------------------------------------- */

.hero.hero-film {
  position: relative;
  display: flex;
  align-items: center;
  /* Rises the full height of the header, less the gutter, so the bar sits
     wholly inside the video with --head-clear of it showing above. Derived
     from --head-h, so nothing has to be re-guessed if the bar changes. */
  margin: calc(var(--band-inset) - var(--head-h)) var(--band-inset) var(--band-inset);
  padding: 156px 0 52px;
  min-height: 76vh;
  overflow: visible;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: var(--edge);
  /* what stays when the video is never fetched at all: reduced motion,
     small screens, data saver. Same violet the other pages' heroes use. */
  background: var(--band);
}

/* Once the video is in, the layer beneath it goes dark. The rounded clip
   antialiases a pixel short of the video edge, and a bright --band showing
   through there was reading as a blue hairline round the whole block. */
.hero-film.has-video .hero-media { background: #1c0038; }

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: var(--edge);
  object-fit: cover;
}

/* Still set for the worst case, a pure white frame, but as light as that
   case allows: 0.57 is the floor and this is 0.58. Everything clears its
   threshold on a white frame (white 4.7:1, highlight 3.0:1), and 42 per cent
   of the video comes through rather than 32. Going lower means the small
   text stops passing whenever a bright area drifts behind it. */
.hero-scrim { display: none; }

.hero-film.has-video .hero-scrim {
  display: block;
  position: absolute;
  inset: 0;
  border-radius: var(--edge);
  background: #1c0038;
  opacity: .58;
}

.hero-film > .wrap {
  position: relative;
  z-index: 1;
}

.hero-film .hero-copy {
  max-width: 900px;
  margin: 0 auto;
  text-align: center;
}

/* The generic .line rule blocks these out from 620px up, but the longest of
   them is 27 characters, up to about 1058px of display type. Below 1200px
   the column cannot hold that, so the line would overflow and wrap and the
   three line shape would come apart. Held inline until there is room, and
   balanced in the meantime so the wrapping still looks deliberate. */
.hero-film h1 .line { display: inline; }
.hero-film h1 { text-wrap: balance; }

@media (min-width: 1200px) {
  /* wider column, so the 27 character line has somewhere to sit */
  .hero-film .hero-copy { max-width: 1120px; }
  .hero-film h1 .line { display: block; }
  .hero-film h1 { text-wrap: initial; }

  .hero-film .lede { max-width: none; }

  .hero-film .lede .line {
    display: block;
    /* body leading, not the tight display leading the headings use */
    line-height: 1.5;
  }
}

/* Bigger, but only the ceiling moves. The three lines are broken by hand
   with .line spans, so if the type outgrows the column a line wraps inside
   itself and the break pattern falls apart. The 8vw slope is what keeps the
   longest line, 21 characters, inside the column on narrow screens; raising
   the cap from 60 to 70 only takes effect above about 875px, where there is
   room for it. */
.hero-film h1 {
  color: #ffffff;
  font-size: clamp(34px, 8vw, 70px);
}
/* white, not the lilac the flat band uses: over video the tint was what
   forced the scrim up, and it buys nothing here */
.hero-film .lede { max-width: 62ch; margin: 0 auto 26px; color: #ffffff; }

/* Same gate as the heading, and for the same reason: the first line is 85
   characters, about 857px, and it only has somewhere to sit once the copy
   column widens at 1200px. Inline below that, so it wraps naturally rather
   than overflowing. */
.hero-film .lede .line { display: inline; }
.hero-film .hero-note { color: #ffffff; }

.hero-film .hsearch {
  grid-template-columns: minmax(0, 1fr);
  max-width: 620px;
  margin: 0 auto 12px;
  gap: 12px;
}

.hero-film .dfind-msg { text-align: center; }

/* Extensions under the search field. Filled with a wash of the scrim colour
   rather than a white one: white lifts the ground and drops the text to
   3.7:1 on a bright video frame, where darkening it takes the text from
   4.86:1 up to 7.7:1. The border stays because on a dark frame the fill and
   the ground land within a few values of each other, and the edge is the
   only thing separating them. */
/* Centred under the search field, and held to the same 620px box as the
   field itself so the row is centred on the input rather than on the much
   wider copy column, which would leave it looking off to one side. */
.hero-tlds {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 620px;
  margin: 18px auto 0;
  padding: 0;
  list-style: none;
}

.hero-tlds li {
  padding: 6px 14px;
  background: rgba(28, 0, 56, .30);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--edge);
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
}

/* Not an extension, so no box. White rather than the pink it had: pink on
   the bare ground falls to 3.14:1 with the chip fill gone, where white holds
   4.86:1. The border stays in the box model as transparent so this still
   lines up with the chips beside it instead of sitting a pixel high. */
.hero-tlds .is-offer {
  background: none;
  border-color: transparent;
  color: #ffffff;
}

@media (min-width: 700px) {
  :root { --band-inset: 16px; }

  .hero.hero-film {
    padding: 180px 0 64px;
    min-height: 80vh;
  }
}

@media (min-width: 1160px) {
  .hero.hero-film {
    padding: 210px 0 80px;
    min-height: min(88vh, 880px);
  }
}


/* Nobody who has asked for reduced motion gets a moving strip. Falls back to
   the wall this replaced: one copy, wrapped, centred and held still. */
@media (prefers-reduced-motion: reduce) {
  .client-marquee {
    -webkit-mask-image: none;
            mask-image: none;
  }

  .client-track {
    width: auto;
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 16px;
    animation: none;
  }

  .client-track > [aria-hidden="true"] { display: none; }

  .client-logos {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 22px;
  }
}


/* No slide for anyone who asked for less motion. It still gets out of the
   way, it just does it without travelling. */
@media (prefers-reduced-motion: reduce) {
  .site-head { transition: none; }
  .site-head.is-past { transform: none; }
  .wp-icon { animation: none; }
}
