:root {
  --ink: #131313;
  --muted: #5c5c5c;
  --line: rgba(19, 19, 19, 0.1);
  --page: #ffffff;
  --panel: #f7f7f8;
  --accent: #06b6d4;
  --brand: #2e63f0; /* the logo blue; hover a step deeper at #1f4fd6 */
  --black: #0c0c0c;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  overflow-x: hidden;
  background: var(--page);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { text-decoration: none; color: inherit; }

/* ── Navbar ─────────────────────────────────────────────── */
.nav-wrap { position: sticky; top: 0; z-index: 50; padding: 14px 20px 0; }
.nav {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 10px 10px 18px;
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(19, 19, 19, 0.08);
  border-radius: 999px;
  box-shadow: 0 6px 24px rgba(12, 12, 12, 0.07);
}
/* The mark leads the bar at 40px against the Contact button's 45, so the logo is the
   tallest thing on the left without making the pill any deeper than the button already
   makes it. */
.brand { display: flex; align-items: center; gap: 11px; font-weight: 700; letter-spacing: -0.025em; }
.brand img { width: 40px; height: 40px; object-fit: contain; }
.brand span { font-size: 21px; }
.brand span b { color: var(--accent); font-weight: 700; }
/* The free space sits before the links rather than after them, so the links travel across
   to the buttons and the whole right-hand side reads as one group. */
.nav-links { display: flex; align-items: center; gap: 30px; margin-left: auto; margin-right: 28px; }
.nav-links a {
  position: relative;
  font-size: 15px;
  color: var(--muted);
  transition: color 0.2s;
}
/* The rule under a link grows from the middle out on hover and simply stands there on the
   page you are already on, so the two states are the same mark arrived at differently. */
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -7px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: scaleX(0);
  transition: transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after { transform: scaleX(1); }
/* Which page you are on. With five of them the bar has to say so. */
.nav-links a[aria-current="page"] { color: var(--ink); font-weight: 500; }
.nav-links a[aria-current="page"]::after { transform: scaleX(1); background: var(--accent); }
.nav-actions { display: flex; align-items: center; gap: 10px; }

/* Keyboard focus, which the bar had none of. Only for keyboard users, so a mouse click
   does not leave a ring behind it. */
.nav a:focus-visible,
.nav button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Off the top of the page the bar tightens: less air above it, a firmer edge and a deeper
   shadow, so it reads as floating over the page rather than sitting in it. */
.nav-wrap.stuck { padding-top: 8px; }
.nav-wrap.stuck .nav {
  background: rgba(255, 255, 255, 0.94);
  border-color: rgba(19, 19, 19, 0.1);
  box-shadow: 0 10px 30px rgba(12, 12, 12, 0.11);
}

/* Over the footer the bar turns itself inside out rather than sitting as a white lozenge
   on a black ground. Everything that was ink becomes white and the dark button becomes the
   light one, so it stays the thing your eye goes to. */
.nav-wrap.on-dark .nav {
  background: rgba(22, 22, 24, 0.72);
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.34);
}
.nav-wrap.on-dark .brand { color: #fff; }
.nav-wrap.on-dark .brand img { filter: brightness(0) invert(1); }
.nav-wrap.on-dark .nav-links a { color: rgba(255, 255, 255, 0.74); }
.nav-wrap.on-dark .nav-links a:hover,
.nav-wrap.on-dark .nav-links a[aria-current="page"] { color: #fff; }
.nav-wrap.on-dark .btn-ghost { color: #fff; border-color: rgba(255, 255, 255, 0.24); }
.nav-wrap.on-dark .btn-ghost:hover { background: rgba(255, 255, 255, 0.1); }
.nav-wrap.on-dark .btn-dark { background: #fff; color: var(--ink); }
.nav-wrap.on-dark .btn-dark:hover { background: rgba(255, 255, 255, 0.88); }
.nav-wrap.on-dark .nav-toggle svg { stroke: #fff; }
.nav-wrap .nav,
.nav-wrap .brand img,
.nav-wrap .nav-links a,
.nav-wrap .btn-ghost,
.nav-wrap .btn-dark,
.nav-wrap .nav-toggle svg {
  transition: background-color 0.3s, border-color 0.3s, color 0.3s, box-shadow 0.3s, filter 0.3s;
}
.nav-wrap { transition: padding-top 0.3s; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  padding: 13px 26px;
  transition: transform 0.2s, background-color 0.2s, box-shadow 0.2s;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn-dark { background: var(--black); color: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); }
.btn-dark:hover { background: #1d1d1d; }
.btn-accent { background: var(--accent); color: #05242a; }
.btn-accent:hover { background: #22c9e4; }
.btn-ghost { border: 1px solid var(--line); color: var(--ink); background: transparent; }
.btn-ghost:hover { background: rgba(19, 19, 19, 0.05); }
.btn-sm { padding: 10px 20px; font-size: 14px; }
.roll { overflow: hidden; position: relative; display: inline-block; height: 1.3em; }
.roll span { display: block; transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.btn:hover .roll span { transform: translateY(-1.3em); }
.nav-toggle { display: none; border: 0; background: transparent; padding: 8px; cursor: pointer; }
.nav-toggle svg { display: block; }

/* ── Hero ───────────────────────────────────────────────── */
.hero { max-width: 1120px; margin: 0 auto; padding: 72px 20px 0; text-align: center; }
.hero h1 {
  margin: 0;
  font-size: clamp(42px, 7.4vw, 92px);
  line-height: 0.98;
  letter-spacing: -0.04em;
  font-weight: 700;
}
.hero h1 .line { display: block; }
.hero h1 .line + .line { margin-top: 6px; }
.hero h1 .soft { color: var(--muted); }
.hero .pill {
  display: inline-block;
  vertical-align: middle;
  width: clamp(88px, 13vw, 168px);
  height: clamp(38px, 5.4vw, 66px);
  border-radius: 999px;
  margin: 0 8px;
  object-fit: cover;
  box-shadow: 0 10px 28px rgba(12, 12, 12, 0.18);
}
.hero p.lede {
  margin: 26px auto 0;
  max-width: 620px;
  font-size: clamp(16px, 1.4vw, 19px);
  line-height: 1.6;
  color: var(--muted);
}
.hero-actions { margin-top: 34px; display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }

/* Fanned cards */
.fan {
  position: relative;
  height: 470px;
  margin: 56px auto 0;
  max-width: 1120px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
}
.fan .card {
  position: absolute;
  margin: 0;
  width: 240px;
  height: 360px;
  border-radius: 32px;
  overflow: hidden;
  background-size: cover;
  background-position: center center;
  will-change: transform;
  transform-origin: center center;
  box-shadow: rgba(0, 0, 0, 0.15) 0 15px 35px;
}
.fan .card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fan .card figcaption {
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: 18px;
  color: #fff;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
}
/* Closed: the cards overlap in a fan — how the hero rests before you scroll. Opening is
   driven by scroll position, not the cursor, so it plays the same every time; see the
   handler at the end of the page. */
.fan .card { pointer-events: none; transition: transform 0.75s cubic-bezier(0.2, 0.8, 0.2, 1); }
.fan .c1 { z-index: 18; transform: translate(-240px, 48px) rotate(-24deg) scale(0.88); transition-delay: 0.16s; }
.fan .c2 { z-index: 19; transform: translate(-120px, 12px) rotate(-12deg) scale(0.94); transition-delay: 0.08s; }
.fan .c3 { z-index: 20; transform: translate(0px, 0px) rotate(0deg) scale(1); }
.fan .c4 { z-index: 19; transform: translate(120px, 12px) rotate(12deg) scale(0.94); transition-delay: 0.08s; }
.fan .c5 { z-index: 18; transform: translate(240px, 48px) rotate(24deg) scale(0.88); transition-delay: 0.16s; }
/* Open, once the group scrolls into view: the cards separate and sit side by side.
   --step is one card plus its gap, and it shrinks on narrower screens to stay on the page. */
.fan { --step: 252px; }
.fan.open .c1 { transform: translate(calc(var(--step) * -2), 26px) rotate(-8deg) scale(0.92); }
.fan.open .c2 { transform: translate(calc(var(--step) * -1), 8px) rotate(-4deg) scale(0.96); }
.fan.open .c3 { transform: translate(0px, 0px) rotate(0deg) scale(1); }
.fan.open .c4 { transform: translate(var(--step), 8px) rotate(4deg) scale(0.96); }
.fan.open .c5 { transform: translate(calc(var(--step) * 2), 26px) rotate(8deg) scale(0.92); }
@media (max-width: 1340px) { .fan { --step: 224px; } }
@media (max-width: 1180px) {
  .fan { --step: 190px; }
  .fan .card { width: 208px; height: 312px; }
}
/* No motion preference: the fan simply stays in its closed, overlapping shape. */
@media (prefers-reduced-motion: reduce) {
  .fan .card { transition: none; }
}

/* Clients strip */
.clients { margin-top: 64px; padding-bottom: 72px; text-align: center; }
.clients p { margin: 0 0 22px; color: var(--muted); font-size: 15px; }
.ticker { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
.ticker ul {
  display: flex;
  gap: 56px;
  list-style: none;
  margin: 0;
  padding: 0;
  width: max-content;
  animation: slide 28s linear infinite;
}
.ticker li { font-size: 20px; font-weight: 600; color: rgba(19, 19, 19, 0.38); letter-spacing: -0.01em; white-space: nowrap; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ticker ul { animation: none; } }

/* ── How we help ────────────────────────────────── */
.pillars { max-width: 1120px; margin: 0 auto; padding: 8px 20px 104px; }
.pillars h2 {
  margin: 0;
  text-align: center;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.08;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.pillars .sub {
  margin: 18px auto 0;
  max-width: 560px;
  text-align: center;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
}
.pillar-grid { margin-top: 48px; display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.pillar {
  position: relative;
  margin: 0;
  aspect-ratio: 3 / 4;
  border-radius: 28px;
  overflow: hidden;
  isolation: isolate;
  box-shadow: rgba(0, 0, 0, 0.15) 0 15px 35px;
}
.pillar img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1); }
.pillar:hover img { transform: scale(1.04); }
/* The copy sits on the photo, so the foot of each card darkens under it. */
.pillar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12, 12, 12, 0) 34%, rgba(12, 12, 12, 0.78) 100%);
}
.pillar-copy { position: absolute; left: 24px; right: 24px; bottom: 24px; z-index: 1; color: #fff; }
.pillar-copy h3 { margin: 0; font-size: 23px; font-weight: 700; letter-spacing: -0.01em; }
.pillar-copy p { margin: 8px 0 0; font-size: 15px; line-height: 1.55; color: rgba(255, 255, 255, 0.82); }
/* A .reveal block lifts its .rise children into place the first time it scrolls into
   view, each after its own --d. Only a page that ran the script hides them first, so a
   broken or blocked script still leaves everything readable. */
.js-reveal .reveal .rise {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
  transition-delay: var(--d, 0s);
}
.js-reveal .reveal.in .rise { opacity: 1; transform: none; }
.pillars .sub { --d: 0.08s; }
.pillar:nth-child(1) { --d: 0.16s; }
.pillar:nth-child(2) { --d: 0.24s; }
.pillar:nth-child(3) { --d: 0.32s; }
@media (prefers-reduced-motion: reduce) {
  .pillar img,
  .js-reveal .reveal .rise { transition: none; }
}

/* ── Stacking service cards ──────────────────────────── */
.works { max-width: 1120px; margin: 0 auto; padding: 0 20px 120px; }
.works h2 {
  margin: 0;
  text-align: center;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.works .sub {
  margin: 18px auto 0;
  max-width: 560px;
  text-align: center;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  --d: 0.08s;
}
.work-stack { margin-top: 56px; }
/* Every card parks at the same height, so each one covers the card below once it lands;
   what you see of the one below is the gap left while the new card is still small. The
   sticky element and the painted card are separate, so the card's own transform cannot
   disturb the stack. */
.work { position: sticky; top: 96px; }
.work + .work { margin-top: 12px; }
/* Two nested layers carry the entrance: each scales up, straightens and fades as the card
   climbs to its parked place, the inner one finishing first, so the card unfurls rather
   than simply growing. The script writes the values from scroll position; with no script
   both layers stay at rest. */
.work-rise,
.work-card { transform-origin: center center; will-change: transform; }
.work-card {
  position: relative;
  overflow: hidden;
  border-radius: 32px;
  background: var(--black);
  isolation: isolate;
}
.work-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(26px);
  transform: scale(1.18);
  z-index: -2;
}
/* The photos behind the blur run bright, so the card is darkened enough for white copy. */
.work-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg, rgba(12, 12, 12, 0.82), rgba(12, 12, 12, 0.6));
}
.work-inner { display: flex; gap: 32px; padding: 28px; align-items: stretch; }
.work-shot {
  flex: 0 0 300px;
  border-radius: 24px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.14);
  aspect-ratio: 3 / 4;
}
.work-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.work-copy { flex: 1; display: flex; flex-direction: column; justify-content: space-between; gap: 24px; padding: 6px 4px 8px 0; color: #fff; }
.work-count {
  margin: 0 0 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  font-size: 15px;
  color: rgba(255, 255, 255, 0.64);
}
.work-count b { font-weight: 400; color: #fff; }
.work-copy h3 { margin: 0; font-size: clamp(24px, 2.6vw, 34px); line-height: 1.12; letter-spacing: -0.02em; font-weight: 700; }
.work-copy p.body { margin: 0; max-width: 48ch; font-size: 16px; line-height: 1.65; color: rgba(255, 255, 255, 0.64); }
/* Split headings: the script breaks them into letters, each carrying its index, so they
   arrive one after another out of a blur. Words stay whole when the line wraps. */
.split .w { white-space: nowrap; }
.split .c { display: inline-block; }
.js-reveal .reveal .split .c {
  opacity: 0;
  transform: translateY(10px);
  filter: blur(10px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.6s ease;
  transition-delay: calc(var(--d, 0s) + var(--i) * 0.022s);
  will-change: transform;
}
.js-reveal .reveal.in .split .c { opacity: 1; transform: none; filter: blur(0px); }
/* On the cards the letters only rise, with no blur. */
.js-reveal .reveal .split.plain .c {
  filter: none;
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
  transition-delay: calc(var(--d, 0s) + var(--i) * 0.018s);
}
.work-card { --d: 0s; }
.work-copy h3 { --d: 0.14s; }

@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-links.open {
    display: flex;
    position: absolute;
    left: 20px;
    right: 20px;
    top: 76px;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin: 0;
    padding: 14px 18px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 20px;
    box-shadow: 0 16px 40px rgba(12, 12, 12, 0.14);
  }
  .nav-links.open a { padding: 10px 0; font-size: 16px; }
  .nav-toggle { display: inline-flex; }
  .hero { padding-top: 48px; }
  .fan { height: 330px; }
  .fan .card { width: 172px; height: 258px; border-radius: 24px; }
  .fan .c1, .fan .c5 { display: none; }
  .fan .c2 { transform: translate(-56px, 12px) rotate(-12deg) scale(0.94); }
  .fan .c4 { transform: translate(56px, 12px) rotate(12deg) scale(0.94); }
  .fan.open .c2 { transform: translate(-92px, 8px) rotate(-5deg) scale(0.96); }
  .fan.open .c4 { transform: translate(92px, 8px) rotate(5deg) scale(0.96); }
  .pillars { padding-bottom: 76px; }
  .pillar-grid { margin-top: 36px; }
  .pillar { aspect-ratio: 4 / 5; border-radius: 24px; }
  .works { padding-bottom: 88px; }
  .work-stack { margin-top: 40px; }
  .work { top: 88px; }
  .work-card { border-radius: 24px; }
  .work-inner { flex-direction: column; gap: 22px; padding: 20px; }
  .work-shot { flex: none; width: 100%; aspect-ratio: 4 / 3; }
  .work-copy { padding: 0; }
}
    
/* Pricing: the three service packages, the middle one the one most brands pick. */
/* The section is a track: the stage inside it is held still while the plans come out, and
   the page moves on once they are all there. Its height is set by the script, which knows
   how tall the stage turned out. */
.pricing {
  position: relative;
  margin-bottom: 96px;
}
.pricing-stage {
  position: sticky;
  top: 96px; /* the line the service cards above park on */
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px;
}
.pricing-after {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px 120px;
}
.pricing h2 {
  margin: 0;
  text-align: center;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.pricing .sub {
  margin: 18px auto 0;
  max-width: 600px;
  text-align: center;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  --d: 0.08s;
}
.plans {
  margin-top: 48px;
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(3, 1fr);
  align-items: stretch;
}
.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0;
  padding: 28px;
  border-radius: 24px;
  background: var(--panel);
  overflow: hidden;
  isolation: isolate;
}
/* Growth sits above the other two, so they are genuinely hidden behind it until they
   come out; each side card carries its own scroll-driven transform. */
.plan.featured {
  z-index: 2;
}
.plan-top {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.plan-icon {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 13px;
  overflow: hidden;
}
.plan-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.plan h3 {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.plan-blurb {
  margin: 6px 0 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
}
.plan-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
  color: var(--muted);
}
.plan-price {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.plan-price b {
  font-size: clamp(34px, 3.4vw, 42px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
}
.plan-price span {
  font-size: 15px;
  color: var(--muted);
}
.plan-line {
  height: 1px;
  background: var(--line);
}
.plan-points {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
}
.plan-points li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 15px;
  line-height: 1.45;
}
.plan-points i {
  width: 22px;
  height: 22px;
  flex: none;
  margin-top: 1px;
  border-radius: 999px;
  background: rgba(19, 19, 19, 0.08);
  display: grid;
  place-items: center;
}
.plan-points svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  stroke-width: 2.4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.plan .btn {
  width: 100%;
  margin-top: auto;
}
/* The picked plan: dark, with the same photo-under-gradient the cards above use. */
.plan.featured {
  background: var(--black);
  color: #fff;
}
.plan-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}
.plan.featured::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(12, 12, 12, 0.93), rgba(12, 12, 12, 0.985));
}
/* Only the name sits under the tag; the blurb keeps the full width. */
.plan.featured h3 {
  padding-right: 92px;
}
.plan.featured .plan-blurb,
.plan.featured .plan-meta,
.plan.featured .plan-price span {
  color: rgba(255, 255, 255, 0.64);
}
.plan.featured .plan-price b {
  color: var(--accent);
}
.plan.featured .plan-line {
  background: rgba(255, 255, 255, 0.2);
}
.plan.featured .plan-points i {
  background: rgba(255, 255, 255, 0.2);
}
.plan.featured .btn {
  background: #fff;
  color: var(--black);
}
.plan.featured .btn:hover {
  background: #f0f0f0;
}
.plan-tag {
  position: absolute;
  top: 22px;
  right: 22px;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.pricing .note {
  margin: 26px auto 0;
  max-width: 640px;
  text-align: center;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
  --d: 0.4s;
}
@media (max-width: 900px) {
  .plans {
    grid-template-columns: 1fr;
    margin-top: 36px;
  }
  .pricing {
    margin-bottom: 0;
  }
  .pricing-after {
    padding-bottom: 88px;
  }
}
    
/* Questions, answered: two columns of accordions. Native <details>, so it works with a
   keyboard and without the script; name= lets a browser that knows it keep one open. */
.faq {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px 120px;
}
.faq h2 {
  margin: 0;
  text-align: center;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.faq .sub {
  margin: 18px auto 0;
  max-width: 600px;
  text-align: center;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  --d: 0.08s;
}
.faq-grid {
  margin-top: 48px;
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr 1fr;
  align-items: start;
}
.faq-col {
  display: grid;
  gap: 16px;
  align-content: start;
}
.faq-item {
  background: var(--panel);
  border-radius: 24px;
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 21px 26px;
  font-size: 17.5px;
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.4;
  border-radius: 24px;
}
.faq-item summary::-webkit-details-marker {
  display: none;
}
.faq-item summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.faq-item summary svg {
  width: 15px;
  height: 15px;
  flex: none;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.faq-item[open] summary svg {
  transform: rotate(180deg);
}
.faq-a {
  margin: 0;
  padding: 0 26px 24px;
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--muted);
}
.faq-item[open] .faq-a {
  animation: faq-open 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes faq-open {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (max-width: 900px) {
  .faq-grid {
    grid-template-columns: 1fr;
    margin-top: 36px;
  }
  .faq {
    padding-bottom: 88px;
  }
}
    
/* A cylinder of images: twelve faces on a ring, the whole ring tipped back so you look
   across it. Pure CSS 3D — the transform on each face places it on the circle, and the
   scroll turns the ring (see paintReel). It stands still for reduced motion. */
.reel {
  position: relative;
  /* Clipped sideways, so a wide ring can never widen the page; open top and bottom, so
     nothing is cut across a photograph when the tilt swings a card past the box. */
  overflow-x: clip;
  overflow-y: visible;
  /* The reference's own framing: 80px of air all round the cylinder's 1133x500 box, and
     80px again between it and the words. Ours was half that, which is what made the whole
     section sit shorter than theirs even with the ring measuring the same. */
  padding: 80px 20px;
  text-align: center;
}
.reel .btn {
  margin-top: 30px;
}
.reel h2 {
  position: relative; /* if a card ever hangs past the stage, the words stay on top of it */
  z-index: 1;
  margin: calc(80px * var(--reel-fit, 1)) auto 0;
  max-width: 820px;
  text-align: center;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.reel .sub {
  margin: 16px auto 0;
  max-width: 560px;
  text-align: center;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  --d: 0.08s;
}
.reel-stage {
  margin-top: 0;
  /* The reference's own box: 1133 by 500, no perspective on it — the ring carries its own,
     so the vanishing point tips with the ring instead of staying nailed to the page. */
  max-width: 1133px;
  height: calc(500px * var(--reel-fit, 1));
  margin-inline: auto;
  display: grid;
  place-items: center;
}
.reel-scale {
  /* The tilt throws the ring low; this puts it back in the middle of its box. The fit is
     set by the script: on a short screen the whole thing shrinks together so the circle,
     the words and the button all stand on one screen at once. */
  transform: translateY(calc(-48px * var(--reel-fit, 1))) scale(var(--reel-fit, 1));
  transform-style: preserve-3d;
}
.ring {
  position: relative;
  width: 144px;
  height: 200px;
  transform-style: preserve-3d;
  /* The vanishing point belongs to the ring itself, not to the box around it: the eye sits
     1200px in front of the ring's own centre, so tipping the ring tips the perspective with
     it. Where it rests before the script takes over, and where it stays without one. */
  transform: perspective(1200px) rotate(-10deg) rotateX(-10deg) rotateY(90deg);
  will-change: transform;
}
.ring figure {
  position: absolute;
  inset: 0;
  margin: 0;
  border-radius: 16px;
  overflow: hidden;
  /* No shadow. The reference carries none anywhere on the card, and on a white page a
     shadow under a turning card gives away that it is a flat rectangle rather than a
     photograph standing in space. */
  /* Twelve cards on a circle 362px across the radius — measured off the reference, where a
     144x200 card at 30° steps leaves about 45px of air between neighbours. Wider and the
     circle reads as a loose fan; tighter and the cards overlap. */
  transform: rotateY(calc(var(--i) * 30deg)) translateZ(362px);
}
.ring img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 900px) {
  .reel-stage {
    margin-top: 8px;
  }
  .reel {
    padding: 48px 20px 64px;
    --reel-fit: 0.5; /* where a phone lands without the script */
  }
}

/* ── Footer ─────────────────────────────────────────────
   A dark close to the page, built the way the Aveum footer is: the name
   set enormous and ghosted across the top, revealed a letter at a time as
   the footer arrives and taken apart again on the way back up, then the
   columns, then a hairline rule and the small print.

   The reveal is tied to scroll POSITION, not played on a trigger, so
   scrolling back up runs it backwards rather than replaying it. Each
   letter carries its own clipped gradient — with one gradient on the
   paragraph the letters would have nothing of their own to fade, since
   their text is transparent and the visible pixels belong to the parent.
   The resting state here is fully opaque and the script clears the
   letters itself, so with the script off, or under reduced motion, the
   footer simply carries its name rather than an invisible one. */
.foot {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--black);
  color: #fff;
}
.foot-ground {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(70% 58% at 50% 8%, rgba(6, 182, 212, 0.16) 0%, rgba(6, 182, 212, 0) 70%),
    radial-gradient(90% 70% at 50% 120%, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0) 65%);
}
.foot-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 84px 20px 30px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 78px;
}
/* The word leads the footer rather than sitting under the columns, and the
   reason is the animation, not the composition: how much of the reveal can
   be seen is decided by how long the word is on screen, and up here that
   is the footer's whole height instead of its last stretch. */
.wordmark {
  width: 100%;
  margin: 0;
  text-align: center;
  font-size: clamp(34px, 12.3vw, 186px);
  line-height: 0.85;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-indent: 0.1em; /* offsets the trailing letter-space on a centred line */
  user-select: none;
  transform: translateZ(0); /* its own layer: the whole word would repaint every frame otherwise */
}
/* Plain inline spans, never inline-block: an inline-block carries its own
   trailing letter-space inside its width and is a break opportunity, which
   would widen the word by eight letter-spaces and let it wrap. */
.wordmark span {
  background: linear-gradient(to top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.32) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.foot-cols {
  width: 100%;
  display: flex;
  justify-content: space-between;
  gap: 32px;
}
.foot-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; max-width: 320px; }
.foot-brand .brand { color: #fff; }
/* The mark is a dark hexagon on transparent; on the dark ground it needs to be its own
   negative rather than a second, paler asset to keep in step with the one in the bar. */
.foot-brand .brand img { filter: brightness(0) invert(1); }
.foot-brand .brand span b { color: var(--accent); }
.foot-brand p { margin: 0; font-size: 16px; line-height: 1.6; letter-spacing: -0.02em; color: rgba(255, 255, 255, 0.8); }
.foot-col { display: flex; flex-direction: column; gap: 16px; }
.foot-col h2 {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: #fff;
}
.foot-col ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 12px; }
.foot-col li, .foot-col a { font-size: 16px; line-height: 1.6; letter-spacing: -0.02em; color: rgba(255, 255, 255, 0.8); }
.foot-col a { transition: color 0.3s; }
.foot-col a:hover { color: #fff; }
.foot-col.reach ul { gap: 10px; }
.foot-bottom { width: 100%; display: flex; flex-direction: column; gap: 20px; }
.foot-rule { height: 1px; width: 100%; background: rgba(255, 255, 255, 0.12); }
.foot-legal {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.foot-legal p { margin: 0; font-size: 14px; line-height: 1.6; letter-spacing: -0.02em; }
.foot-legal .note { color: rgba(255, 255, 255, 0.6); }
.foot-legal .rights { color: rgba(255, 255, 255, 0.8); flex-shrink: 0; }
@media (min-width: 1024px) {
  .foot-legal { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 40px; }
}
@media (max-width: 900px) {
  .foot-inner { gap: 48px; padding-top: 64px; }
  .foot-cols { flex-direction: column; gap: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  .ring {
    transform: perspective(1200px) rotate(-19deg) rotateX(-19deg) rotateY(18deg);
  }
}

/* ── Inner pages ────────────────────────────────────────
   Every page but the homepage opens the same way: a short centred head over
   white, then its own sections down the same 1120px measure the hero uses.
   The homepage earns its fan of photographs and its cylinder; these do not,
   and giving them one each would make the site feel like five homepages. */
.page-head {
  max-width: 900px;
  margin: 0 auto;
  padding: 72px 20px 0;
  text-align: center;
}
.page-head .eyebrow {
  margin: 0 0 18px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.page-head h1 {
  margin: 0;
  font-size: clamp(38px, 5.6vw, 68px);
  line-height: 1.02;
  letter-spacing: -0.04em;
  font-weight: 700;
}
.page-head h1 .soft { color: var(--muted); }
.page-head .lede {
  margin: 22px auto 0;
  max-width: 620px;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.6;
  color: var(--muted);
}
.page-head .hero-actions { margin-top: 34px; }

/* A section on an inner page: the same head-then-content rhythm as the
   homepage's, at a measure that suits reading rather than display. */
.slab { max-width: 1120px; margin: 0 auto; padding: 104px 20px 0; }
.slab.tight { padding-top: 72px; }
.slab > h2 {
  margin: 0;
  max-width: 820px;
  font-size: clamp(28px, 3.6vw, 42px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.slab > .sub {
  margin: 16px 0 0;
  max-width: 620px;
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.6;
  color: var(--muted);
}
.slab.center { text-align: center; }
.slab.center > h2, .slab.center > .sub { margin-left: auto; margin-right: auto; }

/* A plain bordered card, the shape the FAQ and the plans already use. */
.tile {
  border: 1px solid var(--line);
  border-radius: 20px;
  background: #fff;
  padding: 28px;
}
.tile h3 { margin: 0; font-size: 20px; line-height: 1.25; letter-spacing: -0.02em; font-weight: 700; }
.tile p { margin: 10px 0 0; font-size: 16px; line-height: 1.65; color: var(--muted); }
.tile-grid { margin-top: 40px; display: grid; gap: 18px; grid-template-columns: repeat(3, 1fr); }
.tile-grid.two { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) {
  .tile-grid, .tile-grid.two { grid-template-columns: 1fr; }
  .slab { padding-top: 72px; }
}

/* A numbered step. The number is set large and pale so the eye reads the
   heading first and takes the order from the margin. */
.steps { margin-top: 44px; display: flex; flex-direction: column; gap: 0; }
.step {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 24px;
  padding: 30px 0;
  border-top: 1px solid var(--line);
  align-items: start;
}
.step:last-child { border-bottom: 1px solid var(--line); }
.step .n {
  font-size: clamp(34px, 4vw, 52px);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.04em;
  color: rgba(19, 19, 19, 0.16);
}
.step h3 { margin: 0; font-size: 21px; line-height: 1.25; letter-spacing: -0.025em; font-weight: 700; }
.step p { margin: 10px 0 0; max-width: 620px; font-size: 16px; line-height: 1.65; color: var(--muted); }
@media (max-width: 700px) {
  .step { grid-template-columns: 1fr; gap: 10px; }
  .step .n { font-size: 30px; }
}

/* The closing ask, on every page that is not the homepage. */
.closer { max-width: 1120px; margin: 112px auto 0; padding: 0 20px; }
.closer-inner {
  border-radius: 28px;
  background: var(--black);
  color: #fff;
  padding: clamp(44px, 6vw, 76px) clamp(24px, 5vw, 64px);
  text-align: center;
}
.closer h2 {
  margin: 0 auto;
  max-width: 700px;
  font-size: clamp(28px, 3.8vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.closer p {
  margin: 16px auto 0;
  max-width: 560px;
  font-size: 17px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.72);
}
.closer .btn { margin-top: 30px; }

/* Three short labels under a service, in the shape the old site used them. */
.chips { margin: 18px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.chips li {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 12px;
}

/* The state a page is in when there is genuinely nothing to list. Said plainly rather
   than filled with placeholders — an empty shelf is better than a stocked fake one. */
.nothing {
  margin: 52px auto 0;
  max-width: 640px;
  border: 1px dashed rgba(19, 19, 19, 0.18);
  border-radius: 20px;
  padding: 48px 28px;
  text-align: center;
}
.nothing h3 { margin: 0; font-size: 21px; letter-spacing: -0.025em; font-weight: 700; }
.nothing p { margin: 12px auto 0; max-width: 460px; font-size: 16px; line-height: 1.65; color: var(--muted); }
.nothing .btn { margin-top: 24px; }

/* ── Contact ────────────────────────────────────────────
   Reach-us column beside the form, the shape the app's own contact page uses. */
.reach-grid {
  max-width: 1120px;
  margin: 0 auto;
  padding: 64px 20px 0;
  display: grid;
  gap: 40px;
  grid-template-columns: 2fr 3fr;
  align-items: start;
}
@media (max-width: 860px) {
  .reach-grid { grid-template-columns: 1fr; gap: 28px; padding-top: 44px; }
}
.reach h2 { margin: 0; font-size: 21px; letter-spacing: -0.025em; font-weight: 700; }
.reach dl { margin: 22px 0 0; }
.reach dt { font-size: 13px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.reach dd { margin: 6px 0 22px; font-size: 17px; line-height: 1.5; letter-spacing: -0.02em; }
.reach dd a { border-bottom: 1px solid var(--line); transition: border-color 0.2s; }
.reach dd a:hover { border-color: var(--ink); }
.reach .small { font-size: 15px; color: var(--muted); }

.form-card {
  border: 1px solid var(--line);
  border-radius: 24px;
  background: var(--panel);
  padding: clamp(24px, 3vw, 34px);
}
.field { display: block; margin-bottom: 18px; }
.field span {
  display: block;
  margin-bottom: 7px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.field input,
.field textarea {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 16px; /* under 16 and iOS zooms the page on focus */
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 13px 15px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.field textarea { min-height: 132px; resize: vertical; }
.field input::placeholder,
.field textarea::placeholder { color: rgba(92, 92, 92, 0.6); }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.16);
}
.field-row { display: grid; gap: 0 18px; grid-template-columns: 1fr 1fr; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }
.form-card .btn { width: 100%; margin-top: 6px; }
/* Said before the button is pressed, not after: the form has no server behind it and
   hands the message to whatever mail app the visitor uses. Better they know. */
.form-note { margin: 14px 0 0; font-size: 14px; line-height: 1.6; color: var(--muted); text-align: center; }
.form-note a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* Where the work happens. On a geographic niche this is not decoration — it is the
   question a visitor actually has, so it gets a line of its own above the headline. */
.here {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 auto 22px;
  padding: 7px 15px 7px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--muted);
}
.here svg { width: 15px; height: 15px; flex: none; stroke: var(--accent); fill: none; stroke-width: 1.8; }
.here b { color: var(--ink); font-weight: 600; }

/* The towns, as a plain run of words rather than a grid of link cards: it answers
   "do you come out to me" without pretending each one is a page. */
.towns,
.trades {
  margin: 34px auto 0;
  max-width: 900px;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}
.towns li,
.trades li {
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 15px;
}
.towns li.more,
.trades li.more { border-style: dashed; }
/* The trades are businesses rather than places, so they carry a little more weight
   on the page than a town name does. */
.trades li { font-weight: 500; color: var(--ink); }
.trades li.more { font-weight: 400; color: var(--muted); }

/* ── Fit finder ─────────────────────────────────────────
   A few questions in the navbar that end in a plan name — or in an honest "we are
   probably not your best option", which is the half that makes the other half worth
   believing. Built as a native <dialog>: Escape closes it, the backdrop is free, and
   focus is handled by the browser rather than by a trap of our own. */
.fit-btn { background: var(--accent); color: #05242a; }
.fit-btn:hover { background: #22c9e4; }
.nav-wrap.on-dark .fit-btn { background: var(--accent); color: #05242a; }

.fit[open] {
  width: min(560px, calc(100vw - 32px));
  max-height: min(86vh, 760px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 24px;
  box-shadow: 0 30px 80px rgba(12, 12, 12, 0.24);
  background: var(--page);
  color: var(--ink);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.fit::backdrop { background: rgba(12, 12, 12, 0.45); backdrop-filter: blur(3px); }
.fit-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 20px 16px;
  border-bottom: 1px solid var(--line);
}
.fit-rail { flex: 1; height: 4px; border-radius: 4px; background: var(--panel); overflow: hidden; }
.fit-rail i { display: block; height: 100%; background: var(--accent); border-radius: 4px; transition: width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); }
.fit-step-of { font-size: 13px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.fit-x {
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 6px;
  line-height: 0;
  border-radius: 8px;
  color: var(--muted);
}
.fit-x:hover { background: var(--panel); color: var(--ink); }
.fit-body { padding: 26px 24px 8px; overflow-y: auto; }
.fit-body h2 { margin: 0; font-size: clamp(21px, 2.4vw, 26px); line-height: 1.2; letter-spacing: -0.03em; font-weight: 700; }
.fit-body .help { margin: 9px 0 0; font-size: 15px; line-height: 1.6; color: var(--muted); }
.fit-opts { margin: 20px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
.fit-opt {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
  font: inherit;
  font-size: 16px;
  letter-spacing: -0.015em;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color 0.18s, background-color 0.18s, transform 0.18s;
}
.fit-opt:hover { border-color: rgba(19, 19, 19, 0.28); transform: translateY(-1px); }
.fit-opt[aria-pressed="true"] { border-color: var(--accent); background: rgba(6, 182, 212, 0.07); }
/* The tick box only appears where more than one answer is allowed, so the shape of the
   control tells you whether picking a second thing is expected. */
.fit-opt .box {
  flex: none;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--line);
  border-radius: 6px;
  display: grid;
  place-items: center;
}
.fit-opt[aria-pressed="true"] .box { border-color: var(--accent); background: var(--accent); }
.fit-opt .box svg { width: 12px; height: 12px; stroke: #fff; fill: none; stroke-width: 2.4; opacity: 0; }
.fit-opt[aria-pressed="true"] .box svg { opacity: 1; }
.fit-foot { display: flex; align-items: center; gap: 10px; padding: 16px 24px 22px; }
.fit-foot .btn { padding: 11px 22px; font-size: 15px; }
.fit-back { margin-right: auto; border: 0; background: transparent; font: inherit; font-size: 15px; color: var(--muted); cursor: pointer; padding: 8px 4px; }
.fit-back:hover { color: var(--ink); }
.fit-back[hidden] { display: none; }

/* The answer. The plan name is the headline; the reasoning under it is what makes it
   land as a recommendation rather than a guess. */
.fit-verdict { display: flex; align-items: center; gap: 10px; margin: 0 0 14px; font-size: 13px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; }
.fit-verdict.yes { color: var(--accent); }
.fit-verdict.maybe { color: #b4791a; }
.fit-plan { margin: 0; font-size: clamp(28px, 3.4vw, 38px); line-height: 1.05; letter-spacing: -0.04em; font-weight: 700; }
.fit-plan span { color: var(--muted); font-size: 0.5em; letter-spacing: -0.02em; }
.fit-why { margin: 16px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; }
.fit-why li { position: relative; padding-left: 26px; font-size: 15px; line-height: 1.6; color: var(--muted); }
.fit-why li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.fit-note {
  margin: 18px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
}
@media (max-width: 560px) {
  .fit[open] { width: 100vw; max-width: 100vw; max-height: 92vh; border-radius: 20px 20px 0 0; margin: auto auto 0; }
  .fit-foot { flex-wrap: wrap; }
  .fit-foot .btn { flex: 1; }
}

/* The fit button carries two labels and shows the one that fits: the long one while the
   bar has room, the short one once the links crowd it. */
.on-narrow { display: none; }
@media (max-width: 939px) {
  .on-wide { display: none; }
  .on-narrow { display: inline; }
}
@media (max-width: 860px) {
  /* Login moves into the menu rather than off the site: two buttons and a toggle are
     enough on a phone, and an existing client still needs a way in. */
  .nav-actions .btn-ghost { display: none; }
  .nav-links.open .nav-login {
    margin-top: 6px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
    width: 100%;
    font-weight: 600;
    color: var(--ink);
  }
}
@media (min-width: 861px) {
  .nav-login { display: none; }
}

/* ── The map ────────────────────────────────────────────
   Real city limits, not a sketch: the boundaries are the US Census's own (TIGERweb,
   Incorporated Places, public domain), simplified to the pixel and projected
   equirectangular with the cosine correction for this latitude, so the shapes on the
   page are the shapes on the ground. Inline SVG rather than a map library — nothing
   fetched, no key, and the town names stay real text a crawler can read. */
.slab.wide { max-width: 1280px; }
/* The tipped plane's near edge projects wider than the page on a narrow screen; clipped
   sideways only, so nothing standing on it is cut off top or bottom. */
.slab.wide:has(.scene) { overflow-x: clip; overflow-y: visible; }
/* The heading, the line under it and the plane are one block. --stick-top, set by the
   script from the block's real height, is where its top sits when the block is centred on
   the screen: that is the point the plane finishes lying flat. */
/* No hold after the map: it lies flat exactly as it reaches the centre of the screen, and
   the page carries straight on. A hold would leave a blank under it while it was pinned.
   The section closes with the same air every section opens with. */
.map-section { padding-bottom: 104px; }
@media (max-width: 900px) { .map-section { padding-bottom: 72px; } }
.map-stick { position: sticky; top: var(--stick-top, 96px); }
.slab.wide > h2 { text-align: center; margin-left: auto; margin-right: auto; }
.map-wrap {
  /* Sized so the whole map is on screen at once: the card's width follows the height of
     the window (the canvas is 5:3), between a floor a laptop can still read and a cap a
     big monitor does not turn into a wall. 240px is the bar, the heading, the gap and the card's     own padding. */
  max-width: clamp(640px, calc((100vh - 240px) * 1.6667), 980px);
  margin: 40px auto 0;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 24px;
  background: var(--panel);
}
.map { display: block; width: 100%; height: auto; overflow: visible; }
.map-grid line { stroke: rgba(19, 19, 19, 0.05); stroke-width: 1.4; }
/* Each town's limits traced in the logo blue, with a wash of the same inside so the
   shape reads as a place rather than a line. Hover lifts the wash. */
.map-pin .limits {
  fill: var(--brand);
  fill-opacity: 0.07;
  fill-rule: evenodd;
  stroke: var(--brand);
  stroke-width: 1.6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transition: fill-opacity 0.25s, stroke-width 0.25s;
}
.map-pin.big .limits { fill-opacity: 0.1; stroke-width: 2; }
.map-pin .dot { fill: var(--brand); stroke: #fff; stroke-width: 2; }
.map-pin text {
  font-family: inherit;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
  fill: var(--ink);
  paint-order: stroke;
  stroke: rgba(247, 247, 248, 0.9); /* the panel colour, so a name stays legible over a line */
  stroke-width: 6px;
  stroke-linejoin: round;
}
.map-pin.big text { font-weight: 700; font-size: 30px; }
.map-pin:hover .limits { fill-opacity: 0.2; stroke-width: 2.4; }

@media (max-width: 960px) {
  .map-wrap { padding: 12px; margin-top: 30px; }
}
/* On a phone twenty names cannot be read at any size. The two anchors keep theirs;
   the rest are still in the markup for a reader with a screen reader or a crawler. */
@media (max-width: 640px) {
  .map-pin:not(.big) text { display: none; }
}

/* ── The map, in 3D ─────────────────────────────────────
   The same language as the photo cylinder: a plane tipped back in perspective, the
   twenty-three cities standing off it as blue blocks, and their names as signs planted
   at each city and turned to face the camera. The tilt answers the scroll the way the
   cylinder's does. The city shapes are the Census's own, drawn once into a <defs> group
   and stamped seven times with <use> — six slices for the sides and one for the top — so
   the extrusion is real depth in the scene, not a drop shadow. */
.plane-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.scene {
  --tilt: 56deg;
  --spin: -16deg;
  --lift: 16px;
  margin: 36px auto 0; /* the two tall signs stand above the plane when it is steep */
  max-width: 1080px;
  /* The plane is drawn at its true size and then set back and down in the scene, so the
     tipped-back top edge does not run off the card and the whole thing stands inside a
     laptop screen with the heading above it. */
  /* The room left on the screen under the heading and the bar. The plane is sized from
     this height, so what is drawn always fits it. */
  height: clamp(340px, calc(100vh - 330px), 600px);
  perspective: 1400px;
  perspective-origin: 50% 24%;
  overflow: visible;
}
.plane {
  position: absolute;
  left: 50%;
  /* The vanishing point is at 24% of the scene, so everything projects towards it: a
     plane centred in the box lands 4.6% high. It is centred at 55.6% to land at 50%. Tipped
     back, the near edge projects lower than the far one as well, so it is held higher
     still — --k is the tilt as a fraction, set with the angle. */
  top: calc(55.6% - 7% * var(--k, 0));
  /* Sized from the scene's height rather than its width: flat, it is seen at 82% of its
     size (it sits 300px back in a 1400px perspective), so 1.16 fills 95% of the height. */
  height: 116%;
  width: auto;
  max-width: 100%;
  aspect-ratio: 1100 / 655;
  transform-style: preserve-3d;
  transform: translate(-50%, -50%) translateZ(-300px) rotateX(var(--tilt)) rotateZ(var(--spin));
  transform-origin: 50% 50%;
  will-change: transform;
}
/* max-width beats height when the screen is narrow, and then the aspect ratio needs the
   width to be the thing that is set. */
@supports (aspect-ratio: 1) {
  .plane { height: auto; width: min(100%, calc(clamp(340px, 100vh - 330px, 600px) * 1.16 * 1100 / 655)); }
}
.plane-face {
  position: absolute;
  inset: 0;
  border-radius: 28px;
  background:
    linear-gradient(rgba(19, 19, 19, 0.045) 1px, transparent 1px) 0 0 / 10% 100%,
    linear-gradient(90deg, rgba(19, 19, 19, 0.045) 1px, transparent 1px) 0 0 / 100% 16.67%,
    #fbfbfc;
  border: 1px solid var(--line);
  box-shadow: 0 40px 80px -30px rgba(12, 12, 12, 0.28), 0 2px 0 rgba(255, 255, 255, 0.9) inset;
}
.layer { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.layer.lakes { fill: #dfeaf1; stroke: #cfe0ea; stroke-width: 0.6; transform: translateZ(0.5px); }
/* The sides: the shape restamped a little higher each time, in a deeper blue, so the block
   reads as solid from the angle the plane is seen at. */
.layer.side { fill: #1f4fd6; stroke: #1a44bd; stroke-width: 0.7; transform: translateZ(calc(var(--i) * (var(--lift) / 6.5))); }
.layer.top { fill: var(--brand); stroke: #fff; stroke-width: 0.9; stroke-linejoin: round; transform: translateZ(var(--lift)); pointer-events: auto; }
.layer.top path { transition: fill 0.2s; }
.layer.top path:hover { fill: #5a86f5; }

/* A sign at each city: a stem standing on the block and a label turned back to face the
   camera, which is the inverse of the plane's own turn. */
.pin {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 0;
  height: 0;
  transform: translateZ(var(--lift)) rotateZ(calc(var(--spin) * -1)) rotateX(calc(var(--tilt) * -1));
  transform-origin: 0 0;
  transform-style: preserve-3d;
  pointer-events: none;
}
.pin { --h: 26px; --up: calc(var(--h) * var(--stand, 1)); } /* --stand: how far the post stands, set with the tilt */
.pin i {
  position: absolute;
  left: -1px;
  bottom: 0;
  width: 2px;
  height: max(0px, var(--up));
  background: var(--brand);
  border-radius: 2px;
}
.pin i::after {
  content: "";
  position: absolute;
  left: -3px;
  bottom: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 2px #fff;
}
.pin span {
  position: absolute;
  left: 0;
  bottom: var(--up);
  transform: translateX(calc(-50% + var(--dx, 0px)));
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 10px;
  box-shadow: 0 6px 16px rgba(12, 12, 12, 0.12);
  pointer-events: auto;
}
/* Tipped back, twenty-one signs cannot stand on a foreshortened plane without piling
   up, so only Dallas and Fort Worth show while it is steep; the rest rise into place
   over the last third of the turn, which is also when the plane has room for them.
   --k is the tilt as a fraction of the way back. */
.pin:not(.big) { opacity: calc((0.42 - var(--k, 0)) / 0.42); transition: opacity 0.15s linear; }
.pin.big { --h: 44px; }
.pin.big i { width: 3px; left: -1.5px; }
.pin.big span { font-size: 14px; padding: 6px 12px; background: var(--brand); color: #fff; border-color: transparent; }
.pin:hover span { border-color: var(--brand); }
@media (max-width: 900px) {
  .scene { height: clamp(260px, calc(100vh - 360px), 460px); perspective: 1100px; }
  .plane { transform: translate(-50%, -50%) translateZ(-60px) rotateX(var(--tilt)) rotateZ(var(--spin)); }
  .pin { --h: 20px; }
  .pin span { font-size: 11px; padding: 4px 8px; }
  .pin.big { --h: 30px; }
  .pin.big span { font-size: 12px; }
}
@media (max-width: 640px) {
  /* Twenty-three signs will not stand on a phone-wide plane; the two anchors keep theirs. */
  .pin:not(.big) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* No turn: the map is shown as it ends up, flat and whole. */
  .scene { --tilt: 0deg; --spin: 0deg; }
}

/* ── Who it is for: the search on a phone, and the trades that win it (from the rebuild) ── */
.trade {
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  padding: 12px 18px 12px 14px; border-radius: 999px;
  background: var(--page); border: 1px solid var(--line);
  font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink);
}
.trade svg { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--brand); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* ── Who it is for: the trades, as a band that moves ────── */
.trade {
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  padding: 12px 18px 12px 14px; border-radius: 999px;
  background: var(--page); border: 1px solid var(--line);
  font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink);
}
.trade svg { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--brand); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.who-note { margin: 40px auto 0; max-width: 640px; text-align: center; }
@media (prefers-reduced-motion: reduce) {
  .band-row { animation: none; width: auto; flex-wrap: wrap; justify-content: center; }
  .band-track:last-child { display: none; }
  .band { mask-image: none; -webkit-mask-image: none; }
}

/* the fanned hero photos and the drifting trade pills reach past a phone screen: clip sideways only, so nothing scrolls horizontally */
.hero, .who { overflow-x: clip; overflow-y: visible; }

.who-grid { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 72px; align-items: center; max-width: 1060px; margin: 56px auto 0; padding: 0 24px; }
.who-trades { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; list-style: none; }
.trade { cursor: default; transition: background 0.35s ease, border-color 0.35s ease, color 0.35s ease, transform 0.35s ease; }
.trade svg { transition: stroke 0.35s ease; }
.trade.on { background: var(--brand); border-color: var(--brand); color: #fff; transform: translateY(-2px); }
.trade.on svg { stroke: #fff; }
.who-more { margin: 18px 0 0; font-size: 15px; color: var(--muted); }
.wp { width: 300px; margin: 0 auto; padding: 14px 14px 18px; border-radius: 34px; background: var(--page); border: 6px solid var(--line); box-shadow: 0 40px 60px -30px rgba(12, 12, 12, 0.35); font-size: 13px; line-height: 1.4; color: var(--ink); }
.wp-top { display: flex; justify-content: center; margin-bottom: 12px; }
.wp-top span { width: 60px; height: 6px; border-radius: 6px; background: var(--panel); }
.wp-search { display: flex; align-items: center; gap: 8px; padding: 11px 14px; border-radius: 999px; background: var(--panel); font-size: 14px; min-height: 42px; }
.wp-lens { width: 13px; height: 13px; flex: none; border: 2px solid var(--muted); border-radius: 50%; position: relative; }
.wp-lens::after { content: ""; position: absolute; right: -6px; bottom: -6px; width: 7px; height: 2px; background: var(--muted); transform: rotate(45deg); }
.wp-caret { width: 1.5px; height: 16px; background: var(--ink); animation: wp-blink 1s steps(2, start) infinite; }
.wp-map { height: 120px; margin-top: 10px; border-radius: 14px; position: relative; background: linear-gradient(rgba(19, 19, 19, 0.05) 1px, transparent 1px) 0 0 / 100% 22px, linear-gradient(90deg, rgba(19, 19, 19, 0.05) 1px, transparent 1px) 0 0 / 22px 100%, #eef2f8; }
.wp-dot { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: var(--muted); }
.wp-dot.d1 { left: 20%; top: 30%; } .wp-dot.d2 { left: 70%; top: 22%; }
.wp-dot.you { left: 48%; top: 58%; width: 16px; height: 16px; background: var(--brand); box-shadow: 0 0 0 6px rgba(46, 99, 240, 0.18); animation: wp-ping 2.4s ease-out infinite; }
.wp-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.wp-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 14px; border: 1px solid var(--line); }
.wp-row.you { border-color: var(--brand); box-shadow: 0 8px 20px -14px rgba(46, 99, 240, 0.6); }
.wp-ic { width: 34px; height: 34px; flex: none; border-radius: 10px; background: var(--panel); display: grid; place-items: center; }
.wp-row.you .wp-ic { background: var(--brand); }
.wp-ic svg { width: 18px; height: 18px; fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.wp-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.wp-t b { font-weight: 600; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wp-t em { font-style: normal; font-size: 11.5px; color: var(--muted); }
.wp-bar { display: block; height: 8px; border-radius: 4px; background: var(--panel); width: 70%; }
.wp-bar.s { width: 45%; }
.wp-call { flex: none; padding: 7px 12px; border-radius: 999px; background: var(--brand); color: #fff; font-size: 12px; font-weight: 600; }
@keyframes wp-blink { to { visibility: hidden; } }
@keyframes wp-ping { 0% { box-shadow: 0 0 0 0 rgba(46, 99, 240, 0.35); } 100% { box-shadow: 0 0 0 16px rgba(46, 99, 240, 0); } }
@media (prefers-reduced-motion: reduce) { .wp-caret, .wp-dot.you { animation: none; } .trade, .trade svg { transition: none; } }
@media (max-width: 900px) {
  .who-grid { grid-template-columns: 1fr; gap: 40px; margin-top: 40px; }
  .wp { width: 280px; }
  .who-trades { justify-content: center; }
  .who-more { text-align: center; }
}
.wp-t em { white-space: nowrap; }
@media (max-width: 900px) {
  .who-grid { padding: 0; }
  .trade { padding: 10px 14px 10px 12px; font-size: 14px; gap: 8px; }
  .trade svg { width: 18px; height: 18px; }
}
.wp-t b { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.25; }
.who-side { text-align: left; }
@media (max-width: 900px) { .who-side { text-align: center; } }

/* the pill cloud sits centred in its column, like the text above and below it */
.who-trades { justify-content: center; }
.who-side, .who-more { text-align: center; }
