/* Kilter homepage.
   A vertical, editorial layout on a 12-column grid: section names sit in a sticky
   left rail and content is set off-centre to the right. */

:root {
  --paper: #F4F4F1;
  --paper-texture: url("assets/textures/paper.webp") 0 0 / 1024px 600px repeat;
  /* Card tints are see-through so the paper texture shows through them. Over paper
     they come out at about #EAEBE6 and #D8EEE4. */
  --paper-raised: rgb(20 24 22 / 0.045);
  --paper-level: rgb(111 221 176 / 0.22);
  --ink: #141816;
  --ink-soft: #3B423F;
  --muted: #6B726F;
  --quiet: #858B87;
  --line: #D6D9D4;
  /* Brand mint, tuned for light backgrounds: 3.1:1 on paper (graphics and large text),
     5.2:1 for ink text on top of it. Use --mint-deep for small text on paper (4.9:1)
     and --mint-soft for accents on ink (10.8:1). */
  --mint: #009E6F;
  --mint-deep: #007A55;
  --mint-soft: #6FDDB0;
  --night-text: #EDEFEC;
  --night-soft: #B5BDB9;
  --logo-accent: var(--mint);

  --font-sans: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  --gutter: clamp(20px, 5vw, 80px);
  --col-gap: clamp(16px, 2vw, 32px);
  --top-h: 72px;
  --chamfer: 12px;
}

/* ---------- Base ---------- */

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

/* Paper texture: a seamless scan (ambientCG Paper001, CC0) cleaned and recoloured so its
   average is exactly --paper. It's the page's own background, so it scrolls with the page. */
html {
  background: var(--paper-texture), var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  scroll-behavior: smooth;
  scroll-padding-top: var(--top-h);
}

body {
  margin: 0;
}

h1, h2, h3, p, ol, ul, figure {
  margin: 0;
}

/* Avoids one-word last lines where the browser supports it. */
p {
  text-wrap: pretty;
}

ol, ul {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
}

svg {
  display: block;
}

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

:focus-visible {
  outline: 2px solid var(--mint-deep);
  outline-offset: 4px;
}

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 60;
  padding: 12px 16px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* Crooked cards can poke past the edge; clip (unlike hidden) keeps sticky elements working. */
main {
  overflow-x: clip;
}

.wrap {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.accent {
  color: var(--mint);
}

/* Keeps a hyphenated term such as "10-day" on one line in balanced headlines. */
.nowrap {
  white-space: nowrap;
}

/* ---------- Top bar ---------- */

.topbar {
  position: fixed;
  inset: 0 0 auto;
  z-index: 40;
  height: var(--top-h);
  background: var(--paper-texture), var(--paper);
  border-bottom: 1px solid var(--line);
}

.topbar__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.topbar__logo {
  color: var(--ink);
}

.topbar__logo svg {
  width: auto;
  height: 26px;
}

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

/* How far off level the page still is. Counts down to zero at the bottom. */
.readout {
  display: none;
  align-items: baseline;
  gap: 6px;
  font-size: 14px;
  color: var(--muted);
  white-space: nowrap;
}

.readout__deg {
  min-width: 4.5ch;
  font: 500 13px/1 var(--font-mono);
  text-align: right;
  color: var(--ink);
}

.readout.is-level,
.readout.is-level .readout__deg {
  color: var(--mint-deep);
}

.topbar__progress {
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  background: var(--mint);
  transform: scaleX(0);
  transform-origin: left;
}

/* ---------- Buttons ---------- */

/* The 45-degree corner cut echoes the cut on every stem of the wordmark. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 22px 0 26px;
  background: var(--ink);
  color: var(--paper);
  font: 600 15px/1 var(--font-sans);
  text-decoration: none;
  white-space: nowrap;
  clip-path: polygon(var(--chamfer) 0, 100% 0, 100% 100%, 0 100%, 0 var(--chamfer));
  transition: background-color 0.2s;
}

.btn:hover {
  background: var(--mint-deep);
}

/* clip-path hides outlines, so focus is shown with a colour change and underline instead. */
.btn:focus-visible {
  outline: none;
  background: var(--mint-deep);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.topbar .btn {
  min-height: 42px;
  padding: 0 16px 0 20px;
  font-size: 14px;
}

/* ---------- Shared type ---------- */

.h2 {
  max-width: 18ch;
  font-weight: 600;
  font-stretch: 90%;
  font-size: clamp(34px, 4.2vw, 72px);
  line-height: 1;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.body {
  max-width: 36rem;
  font-size: clamp(16px, 1.15vw, 19px);
  line-height: 1.6;
  color: var(--ink-soft);
}

.h2 + .body {
  margin-top: 28px;
}

/* Readings: a signed number and what it measures, like an instrument. */
.reading__value {
  display: block;
  font-weight: 600;
  font-stretch: 88%;
  font-size: clamp(36px, 3.4vw, 56px);
  line-height: 0.95;
  letter-spacing: -0.045em;
  white-space: nowrap;
}

.reading__what {
  display: block;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* ---------- Hero ---------- */

/* The first screen holds two text elements (the headline and the offer) and the button,
   centred vertically. The photo runs --hero-bleed past the bottom of the screen, so its
   lower slab is cut off by the fold and the page visibly continues. */
.hero {
  padding-top: var(--top-h);
  --hero-bleed: clamp(96px, 18vh, 200px);
}

.hero__grid {
  min-height: calc(100vh - var(--top-h));
  min-height: calc(100svh - var(--top-h));
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: 1fr auto auto 1fr;
  column-gap: var(--col-gap);
}

.hero__title {
  position: relative;
  z-index: 1;
  grid-column: 1 / span 8;
  grid-row: 2;
  font-weight: 600;
  font-stretch: 88%;
  font-size: clamp(52px, 8vw, 148px);
  line-height: 0.92;
  letter-spacing: -0.045em;
  text-wrap: balance;
}

/* The stack photo bleeds off the right edge and past the bottom of the first screen. Its
   background is pure white and it's multiplied onto the page like ink on paper: white
   lets the paper texture through, shadows darken it, and its hard bottom edge (white)
   disappears where it ends inside the next section's top padding. Its left and top edges
   fade out, so the slabs sit on the page itself and the headline can overlap the empty
   paper on its left. The negative bottom margin is the bleed: the box grows by that much
   below the grid, and the image is pushed down inside it so the lower slab meets the fold.
   The bottom quarter fades out too: the slab's shadow reaches the image's bottom edge, which
   otherwise showed as a hard line across the proof readings. The fade starts below the fold. */
.hero__photo {
  position: relative;
  grid-column: 7 / -1;
  grid-row: 1 / -1;
  min-height: 520px;
  /* Reach the window's right edge even when the page is wider than the 1440px wrap. */
  margin-right: calc(-1 * var(--gutter) - max(0px, (100vw - 1440px) / 2));
  margin-bottom: calc(-1 * var(--hero-bleed));
}

.hero__photo img {
  position: absolute;
  top: 6%;
  left: -4%;
  width: 112%;
  height: 112%;
  object-fit: cover;
  object-position: 72% 50%;
  mix-blend-mode: multiply;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 22%),
    linear-gradient(to bottom, transparent, #000 14%, #000 75%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 22%),
    linear-gradient(to bottom, transparent, #000 14%, #000 75%, transparent);
  mask-composite: intersect;
}

.hero__intro {
  position: relative;
  z-index: 1;
  grid-column: 1 / span 5;
  grid-row: 3;
  margin-top: clamp(28px, 5vh, 56px);
}

/* The offer, above the fold: name, price, guarantee, in one line. */
.hero__offer {
  max-width: 30rem;
  font-weight: 600;
  font-size: clamp(16px, 1.2vw, 19px);
  line-height: 1.45;
  color: var(--ink);
}

.hero__offer .accent {
  color: var(--mint-deep);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 28px;
  margin-top: 32px;
}

/* ---------- Sections ---------- */

.section {
  padding: clamp(96px, 14vh, 168px) 0;
  border-top: 1px solid var(--line);
}

.section__grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--col-gap);
  row-gap: clamp(40px, 6vh, 72px);
}

/* Section name, pinned in the left margin while the section scrolls past. */
.rail {
  grid-column: 1 / span 3;
  grid-row: 1;
  align-self: start;
  position: sticky;
  top: calc(var(--top-h) + 28px);
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-weight: 500;
  font-size: 15px;
}

.rail__num {
  font: 500 12px/1 var(--font-mono);
  color: var(--mint-deep);
}

.section__body {
  grid-column: 4 / -1;
}

/* ---------- 01 On the level (proof) ---------- */

/* Three results in a row, where a logo bar would go on a typical page. */
.readings {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--col-gap);
  margin-top: clamp(32px, 5vh, 52px);
  border-top: 1px solid var(--ink);
}

.readings li {
  display: flex;
  flex-direction: column;
  padding: 20px 0 8px;
}

.readings .reading__value {
  margin-bottom: 8px;
}

.cases {
  display: grid;
  row-gap: clamp(56px, 9vh, 104px);
}

.case__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.case__client {
  font-weight: 600;
  font-size: 17px;
}

.case__kind {
  font: 500 12px/1 var(--font-mono);
  color: var(--muted);
}

/* Testimonials open with the wordmark's 45-degree slash instead of quotation marks:
   no stars, no headshots, no carousel. */
.quote {
  max-width: 52rem;
  margin-top: clamp(28px, 5vh, 48px);
}

.quote__mark {
  width: 20px;
  height: auto;
  margin-bottom: 20px;
  fill: var(--mint);
}

.quote blockquote {
  margin: 0;
  font-weight: 600;
  font-stretch: 92%;
  font-size: clamp(26px, 2.6vw, 44px);
  line-height: 1.12;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}

.quote figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin-top: 24px;
  font-size: 15px;
  color: var(--ink-soft);
}

.quote__name {
  font-weight: 600;
  color: var(--ink);
}

/* ---------- 02 Off kilter (the problem) ---------- */

/* Columns 3-10 of the section grid: centred on the page (a 12-column grid's middle is
   between columns 6 and 7) and starting after the sticky rail's text, so the rail never
   slides over it. The grid's row gap spaces it from the headline above. */
.banner {
  grid-column: 3 / 11;
}

/* Like the hero: the photo's lighting was flattened so its floor is pure white, it's
   multiplied onto the paper, and its edges feather out, so the objects sit on the page. */
.banner img {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 4%, #000 96%, transparent),
    linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 4%, #000 96%, transparent),
    linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent);
  mask-composite: intersect;
}

/* Crooked cards that straighten as you scroll (main.js sets the transforms). */
.pile {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-top: clamp(8px, 2vh, 24px);
}

.pile__card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 20px;
  min-height: 116px;
  padding: 18px 18px 20px;
  background: var(--paper-raised);
  font-family: var(--font-mono);
  clip-path: polygon(12px 0, 100% 0, 100% 100%, 0 100%, 0 12px);
  transition: background-color 0.35s;
  will-change: transform;
}

.pile__tilt {
  min-height: 1em;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.pile__name {
  font-size: 15px;
  line-height: 1.4;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.pile__card.is-level {
  background: var(--paper-level);
}

.pile__card.is-level .pile__tilt {
  color: var(--mint-deep);
}

.pile__after {
  margin-top: clamp(28px, 4vh, 44px);
}

/* ---------- 03 The stack (dark) ---------- */

.section--dark {
  background: var(--ink);
  color: var(--night-text);
  border-top: 0;
}

.section--dark .rail__num {
  color: var(--mint-soft);
}

.section--dark .body {
  color: var(--night-soft);
}

.section--dark :focus-visible {
  outline-color: var(--mint-soft);
}

.stack__intro {
  grid-column: 4 / -1;
  grid-row: 1;
}

/* The figure stays pinned while the three steps scroll past it. */
.stack__figure {
  grid-column: 4 / span 4;
  grid-row: 2;
  align-self: start;
  position: sticky;
  top: calc(var(--top-h) + 10vh);
}

.stack__svg {
  width: 100%;
  max-width: 340px;
  height: auto;
  overflow: visible;
}

.stack__slab {
  will-change: transform, opacity;
}

.stack__face { fill: var(--night-text); }
.stack__face--accent { fill: var(--mint); }

.stack__text {
  font: 500 6.4px var(--font-mono);
  letter-spacing: 0.9px;
  fill: var(--ink);
}

.services {
  grid-column: 8 / -1;
  grid-row: 2;
}

.service {
  min-height: 64vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: opacity 0.4s;
}

.js .service {
  opacity: 0.4;
}

.js .service.is-active {
  opacity: 1;
}

.service__num {
  font: 500 12px/1 var(--font-mono);
  color: var(--mint-soft);
}

.service__title {
  margin: 12px 0 14px;
  font-weight: 600;
  font-stretch: 92%;
  font-size: clamp(26px, 2.4vw, 40px);
  letter-spacing: -0.03em;
}

.service p:last-child {
  max-width: 30rem;
  font-size: clamp(16px, 1.1vw, 18px);
  line-height: 1.6;
  color: var(--night-soft);
}

/* ---------- 04 The Level Check (offer) ---------- */

/* The layers drawing and the list of what's included share a row, laid out like the
   stack section: drawing in columns 4-7, list from column 8. */
.offer__figure {
  grid-column: 4 / span 4;
  align-self: start;
}

.offer__figure img {
  display: block;
  width: 100%;
  height: auto;
}

.deliverables {
  grid-column: 8 / -1;
  align-self: start;
}

.deliverables li {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 20px 0;
  border-top: 1px solid var(--line);
}

.deliverables li:first-child {
  border-top-color: var(--ink);
}

.deliverables__num {
  min-width: 24px;
  font: 500 12px/1 var(--font-mono);
  color: var(--mint-deep);
}

.deliverables h3 {
  font-weight: 600;
  font-stretch: 92%;
  font-size: clamp(20px, 1.6vw, 26px);
  letter-spacing: -0.02em;
}

/* The terms, on ink with the 45-degree cut. The guarantee is one sentence, named and signed.
   Not on the page since 2026-11-03 (the pricing model isn't settled); kept for when it returns. */
.offer {
  max-width: 64rem;
  padding: clamp(28px, 4vw, 56px);
  background: var(--ink);
  color: var(--night-text);
  clip-path: polygon(24px 0, 100% 0, 100% 100%, 0 100%, 0 24px);
}

.offer :focus-visible {
  outline-color: var(--mint-soft);
}

.offer__terms {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px var(--col-gap);
  margin: 0;
  padding-bottom: 28px;
  border-bottom: 1px solid rgb(237 239 236 / 0.22);
}

.offer__terms dt {
  font-size: 14px;
  color: var(--night-soft);
}

.offer__terms dd {
  margin: 8px 0 0;
  font: 500 16px/1.35 var(--font-mono);
  color: var(--night-text);
}

.offer__guarantee {
  max-width: 40rem;
  margin-top: 32px;
}

.offer__guarantee-name {
  margin-bottom: 12px;
  font: 500 12px/1 var(--font-mono);
  color: var(--mint-soft);
}

.offer__guarantee-name + p {
  font-weight: 500;
  font-size: clamp(20px, 1.6vw, 26px);
  line-height: 1.35;
  letter-spacing: -0.015em;
}

.offer__sign {
  margin-top: 14px;
  font-size: 15px;
  color: var(--mint-soft);
}

.offer__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 24px;
  margin-top: 36px;
}

.offer__note {
  font: 500 13px/1.4 var(--font-mono);
  color: var(--night-soft);
}

/* ---------- 05 Straight answers (objections) ---------- */

.faq {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--col-gap);
}

.faq__item {
  padding: 22px 0 34px;
  border-top: 1px solid var(--line);
}

.faq__item h3 {
  font-weight: 600;
  font-size: clamp(18px, 1.35vw, 22px);
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.faq__item p {
  max-width: 34rem;
  margin-top: 10px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* ---------- 06 In kilter (contact + footer) ----------
   The section sits on a close-up of the mint slab, cropped to the slab itself. All the
   text is one block on the slab's long side, left of the chamfered corner (about 59%
   across): label and headline in ink on the lit face, blurb and email in light text.
   The owner chose to let the light text run over the mint face rather than leave a gap;
   it measures about 3:1 there (below the 4.5:1 guideline for small text).
   The photo keeps its own aspect ratio and is never cropped on wide screens, so the text
   stays in the same place on the slab at every width. */

/* The photo and the text share the first grid row, and the footer gets its own row, so
   it always starts below both, however tall the text gets. */
.contact {
  display: grid;
  background: var(--ink);
  color: var(--night-text);
  --logo-accent: var(--mint-soft);
}

.contact__photo {
  grid-area: 1 / 1;
  align-self: start;
  position: relative;
  aspect-ratio: 1672 / 753;
}

.contact__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
}

/* Starts 4% down the photo (0.45 of the width tall, so 1.8% of the width; padding
   percentages are of the width). 22% is about as far left as the headline can go:
   further left, the face's diagonal bottom edge rises into the headline's last line.
   The column stops short of the bright glint under the corner. */
.contact__text {
  grid-area: 1 / 1;
  align-self: start;
  position: relative;
  padding: 1.8% 46% 0 22%;
}

/* Here the rail is a label above the headline instead of a sticky margin note. */
.contact .contact__rail {
  position: static;
  margin-bottom: 20px;
  color: var(--ink);
}

.contact .rail__num {
  color: var(--ink);
}

.contact :focus-visible {
  outline-color: var(--paper);
}

.contact__title {
  max-width: 9ch;
  color: var(--ink);
  font-weight: 600;
  font-stretch: 88%;
  font-size: clamp(36px, 5.2vw, 104px);
  line-height: 0.9;
  letter-spacing: -0.05em;
}

.contact .body {
  margin: 24px 0 28px;
  color: var(--night-text);
}

/* The page's final call to action: the same "Book a Level Check" every other button points
   here with, now opening an email, plus the address itself for people who'd rather copy it. */
.contact__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
}

/* Mint with ink text (5.2:1) and a thin ink outline, so it holds its shape where it
   overlaps the mint face. clip-path would cut a normal border off the 45-degree corner,
   so the button itself is ink and the mint fill is a pseudo-element inset by the outline
   width, with its own chamfer pulled in to match. */
.btn--mint {
  position: relative;
  background: var(--ink);
  color: var(--ink);
}

.btn--mint::before {
  content: "";
  position: absolute;
  inset: 1.5px;
  z-index: -1;
  background: var(--mint);
  clip-path: polygon(calc(var(--chamfer) - 1px) 0, 100% 0, 100% 100%, 0 100%, 0 calc(var(--chamfer) - 1px));
  transition: background-color 0.2s;
}

.btn--mint:hover,
.btn--mint:focus-visible {
  background: var(--ink);
}

.btn--mint:hover::before,
.btn--mint:focus-visible::before {
  background: var(--mint-soft);
}

.contact__email {
  padding-bottom: 3px;
  border-bottom: 1px solid currentColor;
  font: 500 15px/1.3 var(--font-mono);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.contact__email:hover {
  color: var(--mint-soft);
}

.footer {
  grid-area: 2 / 1;
  position: relative;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 28px;
  margin-top: clamp(48px, 8vh, 88px);
  padding-top: 20px;
  padding-bottom: 28px;
  border-top: 1px solid rgba(237, 239, 236, 0.25);
  color: var(--night-soft);
  font-size: 14px;
}

.footer__logo {
  width: auto;
  height: 22px;
  color: var(--night-text);
}

.footer__top {
  color: var(--night-text);
  font-weight: 600;
  text-decoration: none;
}

/* ---------- Medium screens ---------- */

@media (min-width: 720px) {
  .readout {
    display: flex;
  }
}

@media (max-width: 1020px) {
  .offer__terms {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 28px;
  }
}

/* ---------- Narrow screens: one column ---------- */

@media (max-width: 860px) {
  /* Photo on top, then the headline and the offer. The button lands at or below the fold on
     most phones, which is the scroll cue here. */
  .hero__grid {
    min-height: 0;
    grid-template-rows: auto auto auto;
    align-content: start;
    padding-bottom: clamp(32px, 6vh, 56px);
  }

  .hero__photo {
    grid-column: 1 / -1;
    grid-row: 1;
    height: 46vh;
    min-height: 300px;
    margin: 0 calc(-1 * var(--gutter)) 8px;
  }

  .hero__photo img {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-position: 76% 62%;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 78%, transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 78%, transparent);
  }

  .hero__title {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .hero__intro {
    grid-column: 1 / -1;
    grid-row: 3;
  }

  /* One compact row per reading: the number on the left, what it measures on the right. */
  .readings {
    grid-template-columns: 1fr;
  }

  .readings li {
    display: grid;
    grid-template-columns: 6.5rem 1fr;
    column-gap: 16px;
    align-items: center;
    padding: 14px 0;
    border-bottom: 1px solid var(--line);
  }

  .readings .reading__value {
    margin: 0;
    font-size: 36px;
  }

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

  .offer__figure,
  .deliverables {
    grid-column: 1 / -1;
  }

  .offer__figure {
    max-width: 420px;
  }

  .rail {
    grid-column: 1 / -1;
    grid-row: auto;
    position: static;
  }

  .section__body,
  .banner,
  .stack__intro,
  .services {
    grid-column: 1 / -1;
  }

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

  /* The stack pins to the top of the screen and the steps scroll underneath. */
  .stack__figure {
    grid-column: 1 / -1;
    grid-row: auto;
    z-index: 2;
    top: var(--top-h);
    padding: 16px 0;
    background: var(--ink);
  }

  .stack__svg {
    max-width: 150px;
  }

  /* Back in source order, so the rail label sits above the headline as in every other section. */
  .stack__intro,
  .services {
    grid-row: auto;
  }

  .service {
    min-height: 56vh;
  }
}

/* Tablets and small laptops: a taller 16:9 crop that trims the white background on the
   left, so the label and headline (which don't shrink as fast as the photo) keep clear of
   the face's diagonal edge. */
@media (min-width: 600px) and (max-width: 1100px) {
  .contact__photo {
    aspect-ratio: 16 / 9;
  }

  .contact__photo img {
    object-position: 61% 0;
  }

  /* 9% down the photo (0.5625 of the width tall, so 5% of the width). */
  .contact__text {
    padding-top: 5%;
    padding-right: 49%;
  }
}

/* Phones: a taller 4:5 crop of the long face, with the chamfered corner near the right
   edge. The text starts 10% down the photo (1.25 x the width tall, so 12.5% of the width). */
@media (max-width: 599px) {
  .contact__photo {
    aspect-ratio: 4 / 5;
  }

  .contact__photo img {
    object-position: 39% 0;
  }

  .contact__text {
    padding: 12.5% 18% 0 var(--gutter);
  }

  .contact__title {
    font-size: 36px;
  }

  .contact .body {
    font-size: 15px;
  }

  .footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    margin-top: 40px;
  }
}

@media (max-width: 520px) {
  .topbar .btn {
    padding: 0 12px 0 16px;
    font-size: 13px;
  }

  .topbar__logo svg {
    height: 22px;
  }
}

/* ---------- Reduced motion ---------- */

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

  .js .service {
    opacity: 1;
    color: inherit;
  }
}
