/* ============ Design tokens ============ */
:root {
  --bg: #ffffff;
  --bg-tint: #f4faf8;
  --green-deep: #1e6f5c;
  --green-mid: #2e8b74;
  --green-soft: #5bb39a;
  --green-dark: #0f3d33;
  --sky: #bfe6e0;
  --sky-light: #ddf1ee;
  --sun: #efc75e;
  --ink: #3a3a3a;
  --muted: #7a8580;
  --line: #e3ece8;

  --font-display: "Cormorant", Georgia, serif;
  --font-body: "IBM Plex Sans", system-ui, -apple-system, sans-serif;

  --container: 1100px;
  --header-h: 68px;

  /* Motion: confident, calm deceleration — no bounce, no elastic.
     Matches the organic, editorial mood of the brand. */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-cue: cubic-bezier(0.23, 1, 0.32, 1);
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  color: var(--green-deep);
  line-height: 1.1;
  margin: 0 0 0.5em;
}

h1 {
  font-size: clamp(2.6rem, 6vw, 4.2rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

h2 {
  font-size: clamp(2rem, 4vw, 2.8rem);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

h3 {
  font-family: var(--font-body);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--green-dark);
  letter-spacing: 0.01em;
}

p {
  margin: 0 0 1em;
}

a {
  color: var(--green-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

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

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 24px;
}

.kicker {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--green-soft);
  margin-bottom: 0.4em;
}

/* ============ Buttons ============ */
.btn {
  display: inline-block;
  background: var(--green-deep);
  color: #fff;
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  border: none;
  border-radius: 999px;
  padding: 14px 36px;
  cursor: pointer;
  transition:
    background 0.2s ease,
    transform 0.18s var(--ease-out-quint),
    box-shadow 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
  .btn:hover {
    background: var(--green-mid);
    transform: translateY(-2px);
    box-shadow: 0 8px 20px -8px rgba(30, 111, 92, 0.5);
  }
}

.btn:active {
  transform: translateY(0) scale(0.97);
  box-shadow: none;
}

.btn-small {
  padding: 9px 24px;
  font-size: 0.75rem;
}

/* ============ Header / nav ============ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

/* With JS the header starts transparent so the hero art flows to the very
   top of the screen (as in the reference), and gains its white fill once
   the page scrolls. Without JS it stays solid — always readable. */
.js .site-header {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.js .site-header.scrolled {
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  border-bottom-color: var(--line);
}

.nav-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 68px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.wordmark img {
  width: 168px;
  height: auto;
}

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

.site-nav a:not(.btn) {
  position: relative;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  transition: color 0.2s ease;
}

.site-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -5px;
  width: 100%;
  height: 1.5px;
  background: var(--green-soft);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s var(--ease-out-quint);
}

@media (hover: hover) and (pointer: fine) {
  .site-nav a:not(.btn):hover {
    color: var(--green-deep);
  }

  .site-nav a:not(.btn):hover::after {
    transform: scaleX(1);
  }
}

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  padding: 8px;
  cursor: pointer;
}

.nav-toggle span {
  width: 22px;
  height: 2px;
  background: var(--green-deep);
  border-radius: 2px;
}

/* ============ Hero ============ */
.hero {
  position: relative;
  overflow: hidden;
  /* The hero slides up under the transparent header so the illustration
     reaches the very top of the screen; the padding keeps the copy clear
     of the nav. svh avoids the iOS Safari URL-bar jump that 100vh causes. */
  min-height: 100svh;
  margin-top: calc(-1 * var(--header-h));
  padding-top: var(--header-h);
  display: flex;
  align-items: center;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 40px;
  width: 100%;
  padding-block: 48px;
}

.hero-copy .lede {
  max-width: 42ch;
  color: var(--muted);
  font-size: 1.05rem;
  margin-bottom: 2em;
}

/* Highlighted word in the headline: a hand-drawn sun-yellow swash
   underneath, echoing the sun and organic curves of the illustration. */
.hl {
  position: relative;
  z-index: 0;
  white-space: nowrap;
}

.hl::after {
  content: "";
  position: absolute;
  left: -1%;
  right: -1%;
  bottom: 0.02em;
  height: 0.16em;
  z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12' preserveAspectRatio='none'%3E%3Cpath d='M3 9 Q30 3 60 7 T117 5' fill='none' stroke='%23EFB95C' stroke-width='5' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
}

/* The swash draws in left-to-right once the headline has landed. */
.js .hero .hl::after {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.7s var(--ease-out-expo) 0.75s;
}

.js .hero.loaded .hl::after {
  transform: scaleX(1);
}

/* The illustration bleeds to the screen edge and fills the entire right
   half of the hero. The SVG's slice fit covers the area like a photograph
   (cropping the artwork's left edge as needed) instead of letterboxing,
   so there is never dead white space around it at any viewport. */
.hero-art {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 50%;
}

.hero-art svg {
  width: 100%;
  /* Oversized above the fold so the parallax drift (capped at 50px in
     main.js) never reveals the white hero background at the top edge.
     Kept small: extra height inflates the slice crop, which eats the
     white bottom-left corner of the artwork on laptop screens. */
  height: calc(100% + 60px);
  margin-top: -60px;
}

/* ---- Hero load-in sequence (JS enhancement) ----
   On first paint, the headline, lede, CTA, then the illustration rise and
   fade in one after another. JS-gated so the page is fully visible without
   JS. The hero-copy uses .reveal, so we drive its children directly here
   and let .loaded release them in order. */
.js .hero .hero-load {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.8s var(--ease-out-quint),
    transform 0.8s var(--ease-out-quint);
  transition-delay: calc(var(--seq, 0) * 110ms);
}

.js .hero.loaded .hero-load {
  opacity: 1;
  transform: none;
}

/* The illustration drifts up from the floor a touch later, anchored bottom. */
.js .hero .hero-art {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 1.1s var(--ease-out-expo),
    transform 1.1s var(--ease-out-expo);
  transition-delay: 0.32s;
}

.js .hero.loaded .hero-art {
  opacity: 1;
  transform: none;
}

.js .hero .scroll-cue {
  opacity: 0;
  transition: opacity 0.8s var(--ease-out-quint);
  transition-delay: 1s;
}

.js .hero.loaded .scroll-cue {
  opacity: 1;
}

/* ---- Ambient drift: the organic art invites slow, looping life.
   Sun breathes; clouds drift sideways. Compositor-only (transform/opacity). */
.hero-art .hero-sun {
  transform-box: fill-box;
  transform-origin: center;
  animation: sun-breathe 7s ease-in-out infinite;
}

.hero-art .hero-clouds {
  animation: cloud-drift 14s ease-in-out infinite;
}

@keyframes sun-breathe {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.95;
  }
  50% {
    transform: scale(1.05);
    opacity: 1;
  }
}

@keyframes cloud-drift {
  0%,
  100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(-14px);
  }
}

/* ============ Scroll affordance ============ */
.scroll-cue {
  position: absolute;
  /* Centered under the copy column — the art now owns the right half. */
  left: 25%;
  bottom: 22px;
  transform: translateX(-50%);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--green-soft);
  text-decoration: none;
}

.scroll-cue .scroll-track {
  width: 22px;
  height: 34px;
  border: 1.5px solid var(--green-soft);
  border-radius: 999px;
  display: flex;
  justify-content: center;
  padding-top: 6px;
}

.scroll-cue .scroll-dot {
  width: 3px;
  height: 7px;
  border-radius: 999px;
  background: var(--green-soft);
  animation: scroll-cue-drift 1.9s cubic-bezier(0.23, 1, 0.32, 1) infinite;
}

@keyframes scroll-cue-drift {
  0% {
    opacity: 0;
    transform: translateY(-3px);
  }
  35% {
    opacity: 1;
  }
  70% {
    opacity: 0;
    transform: translateY(9px);
  }
  100% {
    opacity: 0;
    transform: translateY(9px);
  }
}

/* ============ Sections ============ */
.section {
  padding-block: 96px;
}

.section-tint {
  background: var(--bg-tint);
}

/* ============ Grids & cards ============ */
.grid {
  display: grid;
  gap: 24px;
  margin-top: 48px;
}

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

.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid > * {
  min-width: 0;
}

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 28px 24px;
  transition:
    transform 0.32s var(--ease-out-quint),
    box-shadow 0.32s var(--ease-out-quint),
    border-color 0.32s var(--ease-out-quint);
}

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    transform: translateY(-4px);
    border-color: var(--sky);
    box-shadow: 0 18px 36px -20px rgba(15, 61, 51, 0.28);
  }

  /* Ghost cards are placeholders — lift, but no heavy shadow on dashed edges. */
  .card-ghost:hover {
    transform: translateY(-3px);
    box-shadow: none;
  }
}

.card p {
  font-size: 0.92rem;
  color: var(--muted);
  margin-bottom: 0;
}

.glyph {
  width: 32px;
  height: 32px;
  color: var(--green-mid);
  margin-bottom: 16px;
}

.work-card .tag {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-deep);
  background: var(--sky-light);
  border-radius: 999px;
  padding: 4px 12px;
  margin-bottom: 16px;
}

.work-card .tag-live {
  background: #e3f5d9;
  color: #2e6b2e;
}

.card-links {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 16px;
}

.card-links a {
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

.card-links a:hover {
  text-decoration: underline;
}

/* Arrow links: the arrow nudges right on hover. */
.arrow {
  display: inline-block;
  margin-left: 0.4em;
  transition: transform 0.25s var(--ease-out-quint);
}

@media (hover: hover) and (pointer: fine) {
  .card-links a:hover .arrow,
  .arrow-link:hover .arrow {
    transform: translateX(4px);
  }
}

.card-ghost {
  background: transparent;
  border-style: dashed;
}

.card-ghost .tag {
  background: transparent;
  border: 1px solid var(--sky);
}

/* ============ Process steps (timeline) ============ */
/* A connecting line threads through four nodes — horizontal on desktop,
   vertical on mobile. The line and node markers use the brand palette
   (--sky line, --green-mid nodes). The node row sits at a fixed offset
   from the top of each step so the line passes cleanly through every dot. */
:root {
  --node: 16px;          /* node diameter */
  --node-row: 26px;      /* distance from a step's top to its node centre */
}

.steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  list-style: none;
  margin: 48px 0 0;
  padding: 0;
}

.steps li {
  position: relative;
  /* Clear the node + number that sit on the line. */
  padding-top: calc(var(--node-row) + 26px);
}

/* The node marker for each step, centred on the line. */
.steps li::before {
  content: "";
  position: absolute;
  top: var(--node-row);
  left: 0;
  width: var(--node);
  height: var(--node);
  margin-top: calc(var(--node) / -2);
  border-radius: 999px;
  background: var(--green-mid);
  /* A soft ring lifts the node off the line without a hard glow. */
  box-shadow: 0 0 0 4px var(--bg), 0 0 0 6px var(--sky-light);
  transition:
    background-color 0.3s ease,
    box-shadow 0.3s var(--ease-out-quint);
}

/* The connecting line, drawn as a thin bar behind the nodes. */
.timeline-line {
  position: absolute;
  top: var(--node-row);
  left: 0;
  right: 0;
  height: 2px;
  margin-top: -1px;
  background: var(--sky);
  /* Sits behind the nodes; nodes paint over its ends. */
  z-index: 0;
}

.steps li,
.step-num,
.steps h3,
.steps p {
  position: relative;
  z-index: 1;
}

.step-num {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--green-soft);
  display: block;
  margin-bottom: 8px;
  transition: color 0.25s ease;
}

/* Hovering a step wakes its stretch of the timeline: the node deepens and
   its ring swells, the numeral darkens to match. Color/ring only — no
   movement, in keeping with the calm editorial mood. */
@media (hover: hover) and (pointer: fine) {
  .steps li:hover::before {
    background: var(--green-deep);
    box-shadow: 0 0 0 4px var(--bg), 0 0 0 8px var(--sky);
  }

  .steps li:hover .step-num {
    color: var(--green-deep);
  }
}

.steps p {
  font-size: 0.92rem;
  color: var(--muted);
  margin-bottom: 0;
}

/* ---- Fluid draw (JS enhancement) ----
   The line grows along its length as the section enters view, then the
   steps + their nodes cascade in behind the advancing edge. The line is
   the lead element (--i 0); the four steps trail at --i 1..4 via the
   existing stagger wiring in main.js. Compositor-only: scaleX / opacity. */
/* Scoped under .steps so these win the cascade over the later, equal-specificity
   `.js .reveal` base rule (the line carries .reveal for the IntersectionObserver). */
.js .steps .timeline-line {
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
  /* The reveal base also sets blur/translate; override to a clean scale. */
  filter: none;
  transition:
    transform 1.1s var(--ease-out-expo),
    opacity 0.5s var(--ease-out-expo);
  transition-delay: calc(var(--i) * 70ms);
}

.js .steps .timeline-line.in {
  opacity: 1;
  transform: scaleX(1);
}

/* Nodes pop on after the line edge reaches them. Scale from a visible
   0.4 (never 0), settling with the same calm curve as the line. */
/* Per-property delays: the entrance stagger applies to transform/opacity
   only, while the hover channels (background, ring) stay at 0s so hover
   feedback is always immediate. */
.js .steps li::before {
  transform: scale(0.4);
  opacity: 0;
  transition:
    transform 0.55s var(--ease-out-expo) calc(var(--i) * 70ms + 220ms),
    opacity 0.55s var(--ease-out-expo) calc(var(--i) * 70ms + 220ms),
    background-color 0.3s ease 0s,
    box-shadow 0.3s var(--ease-out-quint) 0s;
}

.js .steps li.in::before {
  transform: scale(1);
  opacity: 1;
}

/* ============ About ============ */
.about-wrap {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 48px;
  align-items: start;
}

.about-copy p {
  font-size: 1.02rem;
}

/* ============ Contact ============ */
.contact-wrap {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 48px;
  align-items: start;
}

.contact-intro p {
  color: var(--muted);
  max-width: 38ch;
}

.alt-contact {
  font-size: 0.92rem;
}

.copy-btn {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-deep);
  background: transparent;
  border: 1px solid var(--sky);
  border-radius: 999px;
  padding: 3px 12px;
  margin-left: 8px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.copy-btn:hover {
  background: var(--sky-light);
}

.copy-btn.copied {
  background: var(--green-deep);
  border-color: var(--green-deep);
  color: #fff;
}

.contact-form {
  display: grid;
  gap: 18px;
}

.field {
  display: grid;
  gap: 6px;
}

.field label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-dark);
}

.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  width: 100%;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--green-soft);
  outline-offset: 1px;
  border-color: var(--green-soft);
}

.field textarea {
  resize: vertical;
}

.contact-form .btn {
  justify-self: start;
}

.hidden-field {
  display: none;
}

.form-status {
  font-size: 0.9rem;
  margin: 0;
  min-height: 1.2em;
}

.form-status.ok {
  color: var(--green-deep);
}

.form-status.err {
  color: #a04040;
}

/* ============ Footer ============ */
.site-footer {
  border-top: 1px solid var(--line);
  padding-block: 48px 28px;
  background: var(--bg-tint);
}

.footer-cols {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 32px;
  padding-bottom: 36px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}

.footer-brand p {
  font-size: 0.88rem;
  color: var(--muted);
  max-width: 36ch;
  margin: 0;
}

.footer-brand .wordmark {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--green-deep);
  margin-bottom: 10px;
}

.footer-col {
  display: grid;
  align-content: start;
  gap: 8px;
}

.footer-col h4 {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin: 0 0 6px;
}

.footer-col a {
  font-size: 0.88rem;
  color: var(--muted);
  text-decoration: none;
}

.footer-col a:hover {
  color: var(--green-deep);
}

.footer-row {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

.footer-row p {
  margin: 0;
  font-size: 0.88rem;
  color: var(--muted);
}

/* ============ Scroll reveal (JS enhancement) ============ */
/* A softer, more fluid entrance: more travel, a whisper of scale, and a
   brief blur that sharpens as it settles. --i is set per-child in JS so
   grid/step children cascade; it defaults to 0 for standalone reveals. */
.js .reveal {
  --i: 0;
  opacity: 0;
  transform: translateY(22px) scale(0.985);
  filter: blur(6px);
  transition:
    opacity 0.85s var(--ease-out-quint),
    transform 0.85s var(--ease-out-quint),
    filter 0.85s var(--ease-out-quint);
  transition-delay: calc(var(--i) * 70ms);
}

.js .reveal.in {
  opacity: 1;
  transform: none;
  filter: blur(0);
}

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

  /* Reveals, hero load-in, and the illustration entrance all settle
     instantly with no movement or blur. */
  .js .reveal,
  .js .hero .hero-load,
  .js .hero .hero-art,
  .js .hero .scroll-cue,
  .js .hero .hl::after {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
    transition-delay: 0s;
  }

  /* Timeline: the line shows full, nodes show in place, no draw or pop. */
  .js .steps .timeline-line,
  .js .steps .timeline-line.in {
    opacity: 1;
    transform: scaleX(1);
    transition: none;
    transition-delay: 0s;
  }

  .js .steps li::before,
  .js .steps li.in::before {
    transform: scale(1);
    opacity: 1;
    transition: none;
    transition-delay: 0s;
  }

  /* Kill all ambient/looping motion. */
  .scroll-cue .scroll-dot,
  .hero-art .hero-sun,
  .hero-art .hero-clouds {
    animation: none;
  }

  /* No hover lift / arrow nudge / press travel. */
  .card,
  .btn,
  .arrow,
  .site-nav a:not(.btn)::after {
    transition: none;
  }
}

/* ============ Responsive ============ */
@media (max-width: 900px) {
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }

  .grid-3 {
    grid-template-columns: 1fr;
  }

  /* Timeline goes vertical: line down the left gutter, nodes stacked on it,
     content indented to the right. One continuous line, not 2x2 fragments. */
  .steps {
    grid-template-columns: 1fr;
    gap: 28px;
    --node-row: 12px;       /* node centre measured from each step's top */
    --rail: 9px;            /* line x-position from the step's left edge */
  }

  .steps li {
    padding-top: 0;
    padding-left: 40px;
  }

  .steps li::before {
    top: var(--node-row);
    left: var(--rail);
    margin-top: 0;
    margin-left: calc(var(--node) / -2);
  }

  .timeline-line {
    top: var(--node-row);
    bottom: var(--node-row);
    left: var(--rail);
    right: auto;
    width: 2px;
    height: auto;
    margin-top: 0;
    margin-left: -1px;
  }

  /* Vertical draw: grow downward from the first node. */
  .js .steps .timeline-line {
    transform: scaleY(0);
    transform-origin: top center;
  }

  .js .steps .timeline-line.in {
    transform: scaleY(1);
  }

  .about-wrap,
  .contact-wrap {
    grid-template-columns: 1fr;
    gap: 24px;
  }

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

  .footer-brand {
    grid-column: 1 / -1;
  }

  /* Keep the mobile hero as one composed panel: copy sits above the
     illustration instead of pushing it into a separate row. */
  .hero {
    min-height: 100svh;
    align-items: center;
  }

  .hero-grid {
    grid-template-columns: 1fr;
    padding-block: 0;
  }

  .hero-copy {
    position: relative;
    z-index: 1;
    text-align: center;
  }

  .hero-copy h1 {
    font-weight: 700;
  }

  .hero-copy .lede {
    color: var(--ink);
    font-weight: 500;
    margin-inline: auto;
  }

  .hero-art {
    position: absolute;
    inset: 0;
    width: 100%;
  }

  .hero-art svg {
    width: 100%;
    height: 100%;
    margin-top: 0;
    opacity: 0.48;
    object-fit: cover;
    object-position: center;
  }

  .scroll-cue {
    display: none;
  }
}

@media (max-width: 640px) {
  .section {
    padding-block: 64px;
  }

  .grid-4 {
    grid-template-columns: 1fr;
  }

  .nav-toggle {
    display: flex;
  }

  /* Mobile nav is always in the DOM and absolutely positioned, so the
     open/close transition never reflows the page. It eases down from the
     header instead of snapping on. */
  .site-nav {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
    background: #fff;
    border-bottom: 1px solid var(--line);
    padding: 20px 24px 24px;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition:
      opacity 0.26s var(--ease-out-quint),
      transform 0.26s var(--ease-out-quint),
      visibility 0s linear 0.26s;
  }

  .site-nav.open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition:
      opacity 0.26s var(--ease-out-quint),
      transform 0.26s var(--ease-out-quint),
      visibility 0s;
  }

  /* The hamburger morphs to an X when open. */
  .nav-toggle span {
    transition:
      transform 0.26s var(--ease-out-quint),
      opacity 0.2s ease;
    transform-origin: center;
  }

  .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);
  }
}
