:root {
  --ink: #0B0B0F;
  --paper: #F4F1EA;
  --cobalt: #1B3BFF;
  --cobalt-deep: #0F26B8;
  --lime: #C7FF3D;
  --ink-60: rgba(11, 11, 15, .62);
  --paper-60: rgba(244, 241, 234, .62);
  --paper-15: rgba(244, 241, 234, .15);
  --edge: 2px;
  --gut: clamp(1.25rem, 4vw, 4.5rem);
  --sect: clamp(4.5rem, 10vw, 9rem);
  --font: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: inherit
}

button {
  font: inherit;
  color: inherit
}

/* ---------- type ---------- */
h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: .94;
  text-wrap: balance
}

h1 {
  font-size: clamp(2.9rem, 10.5vw, 8.5rem);
  text-transform: uppercase
}

h2 {
  font-size: clamp(2.2rem, 6.5vw, 5rem);
  text-transform: uppercase
}

h3 {
  font-size: clamp(1.35rem, 2.6vw, 2rem);
  letter-spacing: -.02em;
  line-height: 1.05
}

p {
  margin: 0
}

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  line-height: 1.45;
  max-width: 46ch
}

.eyebrow {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: .75rem;
}

.eyebrow::before {
  content: "";
  width: 2.5rem;
  height: var(--edge);
  background: currentColor;
  flex: none
}

/* ---------- texture ---------- */
/* Dot lattice. Inherits currentColor, so it inverts per section automatically. */
section:not(.hero)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px, currentColor 1px, transparent 0);
  background-size: 30px 30px;
  opacity: .15;
  -webkit-mask-image: radial-gradient(115% 85% at 50% 0%, #000 28%, transparent 76%);
  mask-image: radial-gradient(115% 85% at 50% 0%, #000 28%, transparent 76%);
}

section:not(.hero)>.wrap {
  position: relative;
  z-index: 1
}

/* Film grain, fixed to the viewport so it does not scroll with content. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
  opacity: .09;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* ---------- section artwork ----------
   Each piece is drawn on a transparent ground in a single colour, so presence is
   controlled entirely by opacity and the mask. Nothing here is a rectangle the eye
   can find an edge on — the mask dissolves the art before it reaches the section
   boundary. scale() gives the parallax headroom to travel without exposing a gap. */
.sect-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
  z-index: 0;
  transform: scale(1.14);
  will-change: transform;
  -webkit-mask-image: radial-gradient(123% 103% at 72% 45%, #000 28%, transparent 83%);
  mask-image: radial-gradient(123% 103% at 72% 45%, #000 28%, transparent 83%);
}

/* Paper grounds take ink strokes, which read heavier — so they get less. */
.sect-art--on-dark {
  opacity: .2;
}

.sect-art--on-light {
  opacity: .09;
}

/* For sections whose content sits directly over the busiest part of the art. */
.sect-art--quiet {
  opacity: .12;
}

.sect-art--left {
  -webkit-mask-image: radial-gradient(123% 103% at 22% 50%, #000 28%, transparent 83%);
  mask-image: radial-gradient(123% 103% at 22% 50%, #000 28%, transparent 83%);
}

.sect-art--wide {
  -webkit-mask-image: radial-gradient(138% 95% at 50% 40%, #000 32%, transparent 88%);
  mask-image: radial-gradient(138% 95% at 50% 40%, #000 32%, transparent 88%);
}

/* ---------- layout ---------- */
.wrap {
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--gut)
}

/* overflow:hidden is load-bearing, not tidiness. .sect-art is inset:0 with scale(1.14), so it
   reaches 7% past every edge of its section — unclipped, that widens the document and the page
   renders with a gutter beside it on narrow screens. Nothing inside a section is meant to escape
   it, and the only sticky element on the page (.nav) is a header, outside every section. */
section {
  padding-block: var(--sect);
  position: relative;
  overflow: hidden;
  isolation: isolate
}

.sect-ink {
  background: var(--ink);
  color: var(--paper)
}

.sect-cobalt {
  background: var(--cobalt);
  color: var(--paper)
}

.sect-head {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem)
}

@media(min-width:900px) {
  .sect-head {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-end;
    gap: 3rem
  }

  .sect-head .lede {
    text-align: right;
    max-width: 34ch
  }
}

.skip {
  position: absolute;
  left: .5rem;
  top: -4rem;
  z-index: 200;
  background: var(--lime);
  color: var(--ink);
  padding: .75rem 1.25rem;
  font-weight: 600;
  transition: top .15s;
}

.skip:focus {
  top: .5rem
}

:where(a, button, input, textarea, select):focus-visible {
  outline: 3px solid var(--lime);
  outline-offset: 3px;
}

.sect-cobalt :where(a, button, input, textarea):focus-visible {
  outline-color: var(--paper)
}

/* ---------- buttons ---------- */
.btn {
  --bg: var(--ink);
  --fg: var(--paper);
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  background: var(--bg);
  color: var(--fg);
  padding: .95rem 1.6rem;
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .01em;
  text-decoration: none;
  border: none;
  cursor: pointer;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: transform .25s cubic-bezier(.2, .8, .2, 1), color .2s;
  will-change: transform;
}

.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--lime);
  transform: translateY(101%);
  transition: transform .35s cubic-bezier(.2, .8, .2, 1);
}

.btn:hover::after,
.btn:focus-visible::after {
  transform: translateY(0)
}

.btn:hover,
.btn:focus-visible {
  color: var(--ink)
}

.btn .arw {
  transition: transform .35s cubic-bezier(.2, .8, .2, 1)
}

.btn:hover .arw {
  transform: translateX(.35rem)
}

.btn-lime {
  --bg: var(--lime);
  --fg: var(--ink)
}

.btn-lime::after {
  background: var(--paper)
}

/* Compact variant, for buttons sitting inside cards. */
.btn-sm {
  padding: .7rem 1.1rem;
  font-size: .85rem;
}

/* Outlined variant. The fill deliberately stays lime rather than currentColor:
   .btn:hover flips the text to ink, and a currentColor fill would flip with it,
   painting a black button on a black section. */
.btn-ghost {
  --bg: transparent;
  --fg: currentColor;
  box-shadow: inset 0 0 0 var(--edge) currentColor
}

/* ---------- nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  border-bottom: var(--edge) solid var(--cobalt);
  transition: background .3s, color .3s, border-color .3s;
}

.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: 4.5rem
}

.mark {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-weight: 700;
  letter-spacing: -.02em;
  font-size: 1.05rem;
  text-decoration: none;
  text-transform: uppercase;
}

/* Colour is the only thing separating the suffix from the name, so it carries the whole
   distinction. The company name stays "Global Agents" everywhere it is machine-readable. */
.mark-tld {
  color: var(--lime)
}

.mark .glyph {
  width: 1.6rem;
  height: 1.6rem;
  background: var(--cobalt);
  flex: none;
  clip-path: polygon(0 0, 100% 0, 100% 66%, 66% 100%, 0 100%);
}

.nav-links {
  display: none;
  gap: 2rem;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0
}

.nav-links a {
  text-decoration: none;
  font-size: .9rem;
  font-weight: 500;
  padding-block: .35rem;
  position: relative;
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: var(--edge);
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .3s cubic-bezier(.2, .8, .2, 1);
}

.nav-links a:hover::after {
  transform: scaleX(1);
  transform-origin: left
}

/* Contact is the destination, not a peer of the other four links. Filled, and inline-flex
   so the vertical padding actually reserves space instead of overlapping the line box.
   The underline sweep is suppressed — it reads as noise once the link has a background. */
.nav-links a.nav-cta,
.nav-drawer a.nav-cta {
  display: inline-flex;
  align-items: center;
  background: var(--lime);
  color: var(--ink);
  font-weight: 600;
  transition: background .25s
}

.nav-links a.nav-cta {
  padding: .5rem 1rem
}

.nav-links a.nav-cta::after {
  display: none
}

.nav-drawer a.nav-cta {
  padding: .6rem 1.2rem;
  margin-top: .5rem
}

.nav-links a.nav-cta:hover,
.nav-links a.nav-cta:focus-visible,
.nav-drawer a.nav-cta:hover,
.nav-drawer a.nav-cta:focus-visible {
  background: var(--paper)
}

.nav-toggle {
  display: grid;
  place-items: center;
  gap: 5px;
  width: 2.75rem;
  height: 2.75rem;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

.nav-toggle span {
  display: block;
  width: 1.4rem;
  height: 2px;
  background: currentColor;
  transition: transform .3s, opacity .2s
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg)
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg)
}

.nav-drawer {
  display: grid;
  overflow: hidden;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s cubic-bezier(.2, .8, .2, 1);
  border-top: 0 solid var(--paper-15);
}

.nav-drawer[data-open="true"] {
  grid-template-rows: 1fr;
  border-top-width: var(--edge)
}

.nav-drawer>div {
  min-height: 0
}

.nav-drawer ul {
  list-style: none;
  margin: 0;
  padding: 1rem 0 1.5rem;
  display: grid;
  gap: .25rem
}

.nav-drawer a {
  display: block;
  padding: .7rem 0;
  text-decoration: none;
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -.02em
}

@media(min-width:1000px) {
  .nav-links {
    display: flex
  }

  .nav-toggle,
  .nav-drawer {
    display: none
  }
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  min-height: min(92svh, 900px);
  display: flex;
  align-items: center;
  padding-block: clamp(4rem, 12vh, 8rem);
  overflow: hidden;
}

#field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block
}

.hero .wrap {
  position: relative;
  z-index: 2
}

.hero-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem)
}

.hero h1 .ln {
  display: block;
  overflow: hidden
}

.hero h1 .ln>span {
  display: block;
  transform: translateY(100%);
  animation: rise .9s cubic-bezier(.16, 1, .3, 1) forwards
}

.hero h1 .ln:nth-child(2)>span {
  animation-delay: .09s
}

.hero h1 .ln:nth-child(3)>span {
  animation-delay: .18s
}

.hero h1 em {
  font-style: normal;
  color: var(--lime)
}

@keyframes rise {
  to {
    transform: translateY(0)
  }
}

.hero-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem;
  align-items: flex-end;
  justify-content: space-between;
  opacity: 0;
  animation: fade .8s ease .5s forwards;
}

@keyframes fade {
  to {
    opacity: 1
  }
}

.hero-sub .lede {
  color: var(--paper-60)
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem
}

/* Forced onto its own line so the promise reads as a footnote to both buttons,
   not as a label belonging to whichever one happens to sit beside it. */
.cta-note {
  flex-basis: 100%;
  font-size: .78rem;
  letter-spacing: .02em;
  opacity: .55;
  margin-top: .35rem;
  max-width: 44ch;
}

.hero-meta {
  position: relative;
  z-index: 2;
  border-top: var(--edge) solid var(--paper-15);
  margin-top: clamp(3rem, 7vw, 5rem);
  padding-top: 1.25rem;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(2, 1fr);
  font-size: .8rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--paper-60);
  opacity: 0;
  animation: fade .8s ease .7s forwards;
}

@media(min-width:800px) {
  .hero-meta {
    grid-template-columns: repeat(4, 1fr)
  }
}

/* ---------- marquee ---------- */
.marquee {
  background: var(--lime);
  color: var(--ink);
  border-block: var(--edge) solid var(--ink);
  overflow: hidden;
  padding-block: .9rem;
}

.marquee__track {
  display: flex;
  width: max-content;
  animation: slide 38s linear infinite
}

.marquee:hover .marquee__track {
  animation-play-state: paused
}

.marquee__group {
  display: flex;
  align-items: center;
  gap: 2.5rem;
  padding-right: 2.5rem;
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.marquee__group i {
  font-style: normal;
  opacity: .45
}

@keyframes slide {
  to {
    transform: translateX(-50%)
  }
}

/* ---------- integrations ribbon ----------
   Deliberately quiet: paper ground, low-contrast greyscale wordmarks, slow drift,
   and edges masked to nothing so names fade in and out rather than clipping. */
.ribbon {
  background: var(--ink);
  color: var(--paper);
  border-block: var(--edge) solid var(--paper-15);
  padding-block: clamp(2rem, 4vw, 3rem);
  overflow: hidden;
  position: relative;
}

.ribbon__label {
  text-align: center;
  padding-inline: var(--gut);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  opacity: .55;
  margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

.ribbon__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}

/* Drifts right, opposite the lime marquee above, so the two never read as the same band. */
.ribbon__track {
  display: flex;
  width: max-content;
  animation: drift 70s linear infinite;
}

.ribbon:hover .ribbon__track {
  animation-play-state: paused;
}

.ribbon__group {
  display: flex;
  align-items: center;
  gap: clamp(2rem, 4vw, 3.5rem);
  padding-right: clamp(2rem, 4vw, 3.5rem);
}

/* Icon and name move as one unit, so the pair lifts together on hover. */
.ribbon__item {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-size: clamp(.95rem, 1.4vw, 1.2rem);
  font-weight: 600;
  letter-spacing: -.015em;
  white-space: nowrap;
  opacity: .55;
  transition: opacity .35s;
}

.ribbon__item:hover {
  opacity: 1;
}

/* brightness(0) collapses every mark to a flat silhouette so vendor brand colours
   cannot break the rhythm; invert(1) then lifts that silhouette from black to paper,
   which is what makes them visible on the ink ground. Both are required — drop the
   invert and the icons disappear into the background. */
.ribbon__item img {
  height: 1.15em;
  width: 1.15em;
  filter: grayscale(1) brightness(0) invert(1);
}

@keyframes drift {
  from {
    transform: translateX(-50%)
  }

  to {
    transform: translateX(0)
  }
}

/* ---------- services ---------- */
.svc {
  display: grid;
  border-top: var(--edge) solid currentColor
}

.svc-item {
  border-bottom: var(--edge) solid currentColor;
  padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
  display: grid;
  gap: 1rem;
  align-items: start;
  position: relative;
}

@media(min-width:900px) {
  .svc-item {
    grid-template-columns: 5rem 1fr 1.1fr;
    gap: 2.5rem;
    align-items: center
  }
}

.svc-num {
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .18em;
  opacity: .5
}

.svc-item p {
  max-width: 52ch;
  opacity: .75;
  line-height: 1.55
}

.svc-item::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: var(--edge);
  width: 100%;
  background: var(--lime);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .5s cubic-bezier(.2, .8, .2, 1);
}

.svc-item:hover::after {
  transform: scaleX(1)
}

.svc-item:hover h3 {
  color: var(--lime)
}

.svc-item h3 {
  transition: color .3s
}

/* ---------- products ---------- */
.prods {
  display: grid;
  gap: var(--edge);
  background: currentColor;
  border: var(--edge) solid currentColor
}

@media(min-width:900px) {
  .prods {
    grid-template-columns: repeat(2, 1fr)
  }
}

.prod {
  background: var(--paper);
  color: var(--ink);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-height: clamp(20rem, 34vw, 26rem);
  transition: background .35s, color .35s;
}

.prod:hover {
  background: var(--cobalt);
  color: var(--paper)
}

/* Solid chip rather than an outline: at rest it is the only dark mass in a paper card,
   so it anchors the eye at the top of each product. */
.prod-tag {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  align-self: flex-start;
  padding: .35rem .65rem;
  background: var(--ink);
  color: var(--paper);
  transition: background .35s, color .35s;
}

/* Card hover flips the ground to cobalt, so the chip inverts with it. */
.prod:hover .prod-tag {
  background: var(--paper);
  color: var(--cobalt);
}

.prod p {
  opacity: .75;
  line-height: 1.55
}

.prod ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .5rem;
  font-size: .9rem
}

.prod li {
  display: flex;
  gap: .6rem;
  align-items: baseline
}

.prod li::before {
  content: "";
  width: .5rem;
  height: .5rem;
  background: currentColor;
  flex: none;
  transform: translateY(-1px)
}

.prod-foot {
  margin-top: auto;
  padding-top: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  border-top: var(--edge) solid currentColor;
}

.prod-price {
  font-size: .8rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: .75
}

.prod-price b {
  font-size: 1.35rem;
  letter-spacing: -.02em;
  text-transform: none;
  opacity: 1
}

.prod-stack {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.prod-stack span {
  padding: .3rem .55rem;
  box-shadow: inset 0 0 0 1px currentColor;
  opacity: .8
}

/* ---------- process ---------- */
.steps {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem)
}

@media(min-width:900px) {
  .steps {
    grid-template-columns: repeat(3, 1fr)
  }
}

.step {
  display: grid;
  gap: 1rem;
  align-content: start;
  border-top: var(--edge) solid currentColor;
  padding-top: 1.5rem
}

.step-n {
  font-size: clamp(3.5rem, 7vw, 5.5rem);
  font-weight: 700;
  line-height: .8;
  letter-spacing: -.05em;
  color: var(--lime);
}

.step p {
  opacity: .8;
  line-height: 1.55;
  max-width: 40ch
}

/* ---------- results ---------- */
.stats {
  display: grid;
  gap: var(--gut) 2rem;
  grid-template-columns: 1fr
}

@media(min-width:560px) {
  .stats {
    grid-template-columns: repeat(2, 1fr)
  }
}

/* Four across as soon as the columns can hold "$1,500" without wrapping. The numeral
   scale is pulled back here so the widest value still fits a quarter-width column. */
@media(min-width:860px) {
  .stats {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--gut) 1.5rem;
  }

  .stat b {
    font-size: clamp(2.2rem, 4.4vw, 4.75rem);
  }
}

.stat {
  display: grid;
  gap: .5rem;
  border-top: var(--edge) solid currentColor;
  padding-top: 1.25rem
}

.stat b {
  font-size: clamp(2.75rem, 6vw, 4.75rem);
  font-weight: 700;
  line-height: .85;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}

.stat span {
  font-size: .85rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .7
}

.disclaimer {
  margin-top: 2.5rem;
  font-size: .8rem;
  opacity: .55;
  max-width: 60ch
}

/* Delivered work borrows the stat row's rule treatment so the two sections still read
   as one claim block, even though they now sit on different backgrounds. */
.cases {
  display: grid;
  gap: var(--gut) 2rem;
  grid-template-columns: 1fr;
  margin-top: clamp(2.5rem, 5vw, 4rem)
}

@media(min-width:860px) {
  .cases {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--gut) 1.5rem
  }
}

.case {
  display: grid;
  gap: .9rem;
  align-content: start;
  border-top: var(--edge) solid currentColor;
  padding-top: 1.25rem
}

.case h3 {
  font-size: clamp(1.15rem, 1.9vw, 1.5rem)
}

.case p {
  font-size: .95rem;
  line-height: 1.55;
  opacity: .75;
  max-width: 40ch
}

.case ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .45rem;
  font-size: .9rem
}

.case li {
  display: flex;
  gap: .6rem;
  align-items: baseline
}

/* Lime, not cobalt — these markers sit on the ink ground, where cobalt goes muddy. */
.case li::before {
  content: "";
  width: .5rem;
  height: .5rem;
  background: var(--lime);
  flex: none;
  transform: translateY(-1px)
}

.case li b {
  font-variant-numeric: tabular-nums
}

/* Marker pen, not a filled box. The gradient fades in and out at the ends and runs at a
   slight angle, so it reads as a swipe rather than a background colour. box-decoration-break
   is what keeps the stroke drawn on every line when the phrase wraps — without it the
   gradient is computed once across the whole inline box and the wrapped lines come out bare.
   The text colour is forced to ink because the same phrase may sit on paper, cobalt, or ink. */
.hl {
  color: var(--ink);
  font-weight: 600;
  background-image: linear-gradient(101deg,
      transparent .1em,
      color-mix(in srgb, var(--lime) 88%, transparent) .5em,
      color-mix(in srgb, var(--lime) 88%, transparent) calc(100% - .45em),
      transparent calc(100% - .05em));
  background-repeat: no-repeat;
  padding: .1em .55em;
  margin: 0 -.3em;
  border-radius: .15em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ---------- faq ---------- */
.faq {
  display: grid;
  border-top: var(--edge) solid currentColor;
  margin-top: clamp(2.5rem, 5vw, 4rem)
}

.faq details {
  border-bottom: var(--edge) solid currentColor
}

/* list-style:none kills the disclosure triangle in Firefox; the ::-webkit- rule below
   does the same in Safari. Both are needed — neither covers the other. */
.faq summary {
  display: flex;
  gap: 1.5rem;
  align-items: baseline;
  justify-content: space-between;
  padding-block: clamp(1.15rem, 2.4vw, 1.6rem);
  cursor: pointer;
  font-size: clamp(1.05rem, 1.9vw, 1.45rem);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.15;
  list-style: none;
  transition: color .3s
}

.faq summary::-webkit-details-marker {
  display: none
}

/* Cobalt, not lime — the FAQ moved to the paper ground, where lime has almost no contrast. */
.faq summary:hover {
  color: var(--cobalt)
}

.faq summary::after {
  content: "+";
  flex: none;
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1;
  transition: transform .35s cubic-bezier(.2, .8, .2, 1)
}

.faq details[open] summary::after {
  transform: rotate(45deg)
}

.faq details p {
  padding-bottom: clamp(1.15rem, 2.4vw, 1.6rem);
  max-width: 62ch;
  opacity: .8;
  line-height: 1.6
}

/* ---------- contact ---------- */
.contact-grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem)
}

@media(min-width:960px) {
  .contact-grid {
    grid-template-columns: 1fr 1fr;
    align-items: start
  }
}

.form {
  display: grid;
  gap: 1.25rem
}

.field {
  display: grid;
  gap: .5rem
}

.field label {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .75
}

.field input,
.field textarea {
  font: inherit;
  color: inherit;
  background: transparent;
  border: none;
  border-bottom: var(--edge) solid currentColor;
  padding: .7rem 0;
  border-radius: 0;
}

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

.field input::placeholder,
.field textarea::placeholder {
  color: currentColor;
  opacity: .35
}

.field-alt {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-note {
  font-size: .85rem;
  font-weight: 600;
  color: var(--lime);
}

.form-fine {
  font-size: .75rem;
  opacity: .5;
  max-width: 40ch;
}

.g-recaptcha {
  min-height: 78px;
}

.contact-aside {
  display: grid;
  gap: 1.5rem;
  align-content: start
}

.contact-aside a {
  font-weight: 600
}

/* Deliberately quiet. The form is the conversion path; this is the escape hatch for people
   who distrust forms, and at display size it was pulling traffic away from the thing that
   actually captures a lead. */
.alt-contact {
  font-size: .9rem;
  opacity: .6
}

.alt-contact a {
  border-bottom: 1px solid currentColor;
  text-decoration: none;
  padding-bottom: .1rem
}

/* ---------- footer ---------- */
footer {
  background: var(--ink);
  color: var(--paper);
  padding-block: 3rem 2rem;
  position: relative;
  isolation: isolate
}

footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px, currentColor 1px, transparent 0);
  background-size: 30px 30px;
  opacity: .07;
  -webkit-mask-image: radial-gradient(100% 120% at 50% 100%, #000 20%, transparent 72%);
  mask-image: radial-gradient(100% 120% at 50% 100%, #000 20%, transparent 72%);
}

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

.foot {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: space-between;
  align-items: center
}

.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: .9rem
}

.foot-links a {
  text-decoration: none;
  opacity: .65;
  transition: opacity .2s
}

.foot-links a:hover {
  opacity: 1
}

.foot small {
  opacity: .5;
  font-size: .8rem
}

.foot-note {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--paper-15);
  font-size: .68rem;
  letter-spacing: .04em;
  line-height: 1.6;
  opacity: .45;
  max-width: 70ch;
}

/* ---------- reveal ---------- */
.rv {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s cubic-bezier(.16, 1, .3, 1), transform .7s cubic-bezier(.16, 1, .3, 1)
}

.rv.in {
  opacity: 1;
  transform: none
}

.rv-d1 {
  transition-delay: .08s
}

.rv-d2 {
  transition-delay: .16s
}

.rv-d3 {
  transition-delay: .24s
}

.rv-d4 {
  transition-delay: .32s
}

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

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

  .rv {
    opacity: 1;
    transform: none
  }

  .hero h1 .ln>span {
    transform: none
  }

  .hero-sub,
  .hero-meta {
    opacity: 1
  }

  .marquee__track {
    animation: none
  }

  /* Static ribbon: wrap the names onto lines instead of scrolling them past,
     drop the duplicate track, and lift the edge mask that only made sense while moving. */
  .ribbon__track {
    animation: none;
    flex-wrap: wrap;
    width: auto;
  }

  .ribbon__group[aria-hidden="true"] {
    display: none;
  }

  .ribbon__group {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 1rem;
    padding-right: 0;
  }

  .ribbon__viewport {
    -webkit-mask-image: none;
    mask-image: none;
  }
}
