/* ==========================================================================
   Benchline Technical website styles.
   One plain CSS file, no build step. Sections follow the page top to bottom.
   Motion rule for the whole file: only transform and opacity ever animate.
   ========================================================================== */

/* The brand typeface is served from this site, so nothing loads from another website. */
@font-face {
  font-family: "Schibsted Grotesk";
  src: url("fonts/SchibstedGrotesk-Variable.ttf") format("truetype");
  font-weight: 400 900; /* one variable file covers every weight used below */
  font-display: swap;   /* show text straight away in a fallback font while this loads */
}

/* Brand tokens (from BRAND.md). Every colour on the site comes from this list. */
:root {
  --paper: #FFFFFF;      /* the page */
  --navy: #16233A;       /* Datum Navy: all text and line work */
  --brass: #A8782A;      /* Survey Brass: accent lines only, never text */
  --brass-ink: #7E5A1E;  /* Brass Ink: small brass-coloured text that still passes contrast */
  --slate: #5B6472;      /* secondary text */
  --hairline: #D8DCE2;   /* row separators */
  --concrete: #EFECE6;   /* panel fill in the drawings */
  --font: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
  --gutter: 20px;        /* side margin on phones */
  --header-h: 60px;      /* sticky header height: the scroll scene pins just below it */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);      /* things arriving */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);  /* things moving across the screen */
}
@media (min-width: 900px) {
  :root { --gutter: 40px; --header-h: 76px; }
}

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

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

html {
  scroll-padding-top: calc(var(--header-h) + 20px); /* linked headings stop below the sticky header */
  -webkit-text-size-adjust: 100%;                   /* stop phones inflating text in landscape */
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; } /* menu links glide to their section; off for reduced motion */
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--navy);
  font: 430 1.0625rem/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word; /* a long email address can never push the page sideways */
  overflow-x: clip;          /* safety net against sideways scroll; clip keeps sticky working */
}

h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
h1, h2, h3 { font-weight: 640; text-wrap: balance; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
img { height: auto; } /* a picture that shrinks to fit keeps its proportions */

/* Large type is set tight; small type is left open (size-specific tracking). */
h1 { font-size: clamp(2.75rem, 11.6vw, 7rem); line-height: 0.98; letter-spacing: -0.035em; }
h2 { font-size: clamp(2rem, 5.2vw, 3.5rem); line-height: 1.04; letter-spacing: -0.028em; }
h3 { font-size: clamp(1.3rem, 2.3vw, 1.7rem); line-height: 1.15; letter-spacing: -0.015em; font-weight: 620; }

a { color: inherit; text-decoration-line: underline; text-decoration-color: var(--brass); text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:hover { text-decoration-color: var(--navy); text-decoration-thickness: 2px; }

/* One visible focus ring for every keyboard-reachable thing. */
:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; border-radius: 2px; }

/* Shared building blocks */
.wrap { width: min(100% - 2 * var(--gutter), 1160px); margin-inline: auto; }
.lead { font-size: clamp(1.125rem, 1.7vw, 1.375rem); line-height: 1.45; max-width: 34em; }
.muted { color: var(--slate); }
.label { font-size: 0.8125rem; font-weight: 600; color: var(--brass-ink); letter-spacing: 0.01em; }
.note { font-size: 0.875rem; color: var(--slate); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
html:not(.js) .js-only { display: none; } /* hide controls that only work with scripts on */
[data-contact="phone"], [data-contact="abn"] { white-space: nowrap; } /* a phone number or ABN never breaks across two lines */

/* Lets keyboard users jump past the header. Off-screen until focused. */
.skip-link { position: absolute; left: var(--gutter); top: -100px; z-index: 30; padding: 10px 14px; background: var(--navy); color: #fff; }
.skip-link:focus { top: 10px; }

/* Buttons: instant press feedback, large enough to tap. */
.button {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 22px;
  background: var(--navy); color: #fff; border: 1px solid var(--navy); border-radius: 3px;
  font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: transform 140ms var(--ease-out), opacity 140ms ease;
}
.button:active { transform: scale(0.97); }
.button.quiet { background: var(--paper); color: var(--navy); }
.button.small { min-height: 40px; padding: 0 16px; font-size: 0.9375rem; }
@media (hover: hover) and (pointer: fine) {
  .button:hover { opacity: 0.86; } /* gated so a tap on a phone does not leave a stuck hover */
}

/* ---------- Header ---------- */

.site-header {
  position: sticky; top: 0; z-index: 20; height: var(--header-h);
  background: rgba(255, 255, 255, 0.94); border-bottom: 1px solid var(--hairline);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header { background: rgba(255, 255, 255, 0.82); -webkit-backdrop-filter: saturate(160%) blur(16px); backdrop-filter: saturate(160%) blur(16px); }
}
@media (prefers-reduced-transparency: reduce) {
  .site-header { background: var(--paper); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.site-header .wrap { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* Brand rule: the full logo is never shown under 180 px wide, so phones get the glyph. */
.logo { display: block; flex: none; }
.logo .logo-full { display: none; width: 180px; height: auto; }
.logo .logo-glyph { width: 40px; height: 40px; }
@media (min-width: 900px) {
  .logo .logo-full { display: block; }
  .logo .logo-glyph { display: none; }
}

.header-actions { display: flex; align-items: center; gap: 8px; }
.nav-links { display: none; }
.nav-links a { font-size: 0.9375rem; text-decoration: none; padding: 10px 2px; }
.nav-links a:hover { text-decoration: underline; text-decoration-color: var(--brass); }
@media (min-width: 900px) {
  .nav-links { display: flex; gap: 28px; margin-right: 20px; }
  .menu { display: none; }
}

/* Phone menu: a native <details>, so it opens and closes with scripts off. */
.menu { position: relative; }
.menu summary { display: flex; align-items: center; min-height: 44px; padding: 0 12px; font-size: 0.9375rem; font-weight: 600; cursor: pointer; list-style: none; }
.menu summary::-webkit-details-marker { display: none; }
.menu ul { position: absolute; right: 0; top: calc(100% + 8px); min-width: 230px; padding: 6px 0; background: var(--paper); border: 1px solid var(--navy); }
.menu li + li { border-top: 1px solid var(--hairline); }
.menu a { display: block; padding: 13px 18px; text-decoration: none; }

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

.hero { padding-block: clamp(44px, 9vh, 104px) clamp(56px, 10vh, 120px); }

/* The headline is "dimensioned end to end", the same idea as the logo. */
.headline { display: inline-block; } /* shrink-wraps, so the dimension line is exactly as long as the words */
.headline-dim { display: flex; align-items: center; gap: 14px; position: relative; margin-top: clamp(18px, 3vw, 34px); padding-inline: 1px; font-size: clamp(0.8125rem, 1.5vw, 1.0625rem); font-weight: 600; letter-spacing: 0.01em; line-height: 1; color: var(--brass-ink); }
.headline-dim .rule { flex: 1; height: 2px; background: var(--brass); }
.headline-dim .rule:nth-child(2) { transform-origin: left; }  /* each half is drawn from its end towards the words */
.headline-dim .rule:nth-child(4) { transform-origin: right; }
/* End marks: an upright witness line with a 45 degree tick, as on a drawing (two small SVGs in the HTML). */
.end-mark { position: absolute; top: 50%; width: 22px; height: 22px; margin-top: -11px; fill: none; stroke: var(--brass); stroke-width: 2; }
.end-mark:first-child { left: -11px; }
.end-mark:last-child { right: -11px; }

.hero-body { display: grid; gap: 36px; margin-top: clamp(36px, 6vw, 72px); }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 26px; margin-top: 28px; }
.hero-actions + .note { margin-top: 16px; max-width: 30em; }

/* A drawing-style title block holding the plain business facts. */
.title-block { align-self: end; border-top: 1px solid var(--navy); font-size: 0.9375rem; }
.title-block div { display: grid; grid-template-columns: 6.5em 1fr; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--hairline); }
.title-block div:last-child { border-bottom-color: var(--navy); }
.title-block dt { color: var(--slate); }
@media (min-width: 900px) {
  .hero-body { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: 80px; }
}

/* The one orchestrated moment on page load: the dimension line draws in. */
@media (prefers-reduced-motion: no-preference) {
  .headline-dim .rule { animation: rule-draw 900ms var(--ease-out) 200ms both; }
  .headline-dim .text, .end-mark { animation: fade-in 500ms ease 700ms both; }
}
@keyframes rule-draw { from { transform: scaleX(0); } }
@keyframes fade-in { from { opacity: 0; } }

/* ---------- Scene: how a take-off is built ----------
   Default layout is plain and static: a heading, four steps and the totals.
   It is what you get with scripts off, with reduced motion, or on a very short screen.
   The pinned, scroll-driven version is switched on further down. */

.scene-intro { padding-top: clamp(40px, 7vw, 96px); }
.scene-intro h2 + p { margin-top: 18px; }

.stage { padding-block: 36px clamp(48px, 8vw, 96px); }
.steps { display: grid; gap: 28px; }
.step h3 { margin-block: 6px 8px; }
.step p:last-child { color: var(--slate); max-width: 30em; }
@media (min-width: 900px) {
  .steps { grid-template-columns: repeat(4, 1fr); gap: 36px; }
}

.figures { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 36px; padding-top: 14px; border-top: 1px solid var(--navy); }
.figure dt { font-size: 0.8125rem; color: var(--slate); }
.figure dd { font-size: clamp(1.5rem, 6.4vw, 2.75rem); font-weight: 600; letter-spacing: -0.02em; line-height: 1.1; white-space: nowrap; } /* no tabular figures: in this typeface they widen the full stop (BRAND.md) */
.figure dd small { font-size: 0.45em; font-weight: 500; letter-spacing: 0; color: var(--slate); }

.stage-visual { display: none; } /* the film only exists in the pinned version */

/* ---------- The drawing (shared by the scene and the hands-on piece) ---------- */

.elevation { overflow: visible; font-family: var(--font); }                 /* panels may fly outside the drawing's box */
.elevation line, .elevation rect, .elevation path { vector-effect: non-scaling-stroke; } /* lines stay hairline-thin at any drawing size */
.ghost { fill: none; stroke: var(--hairline); stroke-width: 1px; stroke-dasharray: 3 3; }
.ground { stroke: var(--navy); stroke-width: 2px; }
.panel-face { fill: var(--concrete); stroke: var(--navy); stroke-width: 1.25px; }
.opening rect { fill: var(--paper); stroke: var(--navy); stroke-width: 1px; }
.opening path { fill: none; stroke: var(--slate); stroke-width: 1px; opacity: 0.45; }
.mark { fill: var(--navy); font-weight: 620; }
.dim-line, .dim-marks line { stroke: var(--brass); stroke-width: 1px; }
.dim-label { fill: var(--brass-ink); font-weight: 560; }

.thumb { overflow: visible; flex: none; } /* small to-scale sketch of one panel in the table */

/* Schedule table, set out like the tables in Benchline documents: thin rules, no boxes. */
/* Rules are drawn on the cells, not the rows, so a row that is still faded out hides its rule too. */
.schedule { width: 100%; border-collapse: separate; border-spacing: 0; font-size: clamp(0.8125rem, 1.6vw, 0.9375rem); line-height: 1.2; }
.schedule th, .schedule td { padding: 7px 4px; text-align: left; font-weight: 430; white-space: nowrap; }
.schedule .num { text-align: right; }           /* figures line up on the right, as in a ledger */
.thumb rect { vector-effect: non-scaling-stroke; }
.thumb .opening path { display: none; }         /* the cross is too fine for a sketch this small */
.schedule thead th, .schedule thead td { font-size: 0.75rem; font-weight: 560; color: var(--slate); border-top: 1px solid var(--navy); border-bottom: 1px solid var(--navy); }
.schedule tbody th, .schedule tbody td { border-bottom: 1px solid var(--hairline); }
.schedule tbody th { font-weight: 620; }
.schedule tfoot th, .schedule tfoot td { font-weight: 660; border-top: 3px double var(--navy); padding-top: 9px; }
.schedule tr.is-picked td:first-child { box-shadow: inset 3px 0 0 var(--brass); } /* marks the row of the panel you picked */

/* ---------- Hands-on piece ---------- */

.hands-on { padding-block: clamp(64px, 10vw, 136px); border-top: 1px solid var(--hairline); }
.hands-on h2 + p { margin-top: 18px; }

/* Two-way switch between the drawing and the table. */
.view-toggle { display: inline-flex; margin-top: 28px; border: 1px solid var(--navy); border-radius: 3px; }
.view-toggle button { min-height: 44px; padding: 0 20px; background: none; border: 0; font: inherit; font-size: 0.9375rem; font-weight: 600; color: var(--navy); cursor: pointer; touch-action: manipulation; }
.view-toggle button[aria-pressed="true"] { background: var(--navy); color: #fff; }

.explorer { display: grid; gap: 32px; margin-top: 28px; }
.explorer-view .elevation { width: 100%; height: auto; max-height: 76vh; }
.explorer-view .schedule { max-width: 560px; }
.explorer .note { margin-top: 14px; }
@media (min-width: 900px) {
  .explorer { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: 72px; align-items: start; }
}

.pick { cursor: pointer; outline: none; } /* focus is shown by the selection frame instead */
.selection { fill: none; stroke: var(--brass); stroke-width: 3px; pointer-events: none; }
.elevation:has(.pick:focus-visible) .selection { stroke: var(--navy); } /* keyboard focus gets the stronger navy frame */
@media (hover: hover) and (pointer: fine) {
  .pick:hover .mark { text-decoration: underline; }
}

/* The read-out: how one panel's numbers are built. */
.readout { border-top: 1px solid var(--navy); }
.readout h3 { padding-block: 14px 4px; font-size: clamp(2rem, 4vw, 2.75rem); letter-spacing: -0.03em; }
.readout h3 + p { padding-bottom: 12px; }
.readout dl div { display: grid; grid-template-columns: 7.5em 1fr; gap: 12px; padding: 10px 0; border-top: 1px solid var(--hairline); }
.readout dt { color: var(--slate); font-size: 0.9375rem; }
.readout dd span { display: block; }
.readout .is-total { border-top-color: var(--navy); font-weight: 640; }

/* ---------- How a job runs ---------- */

.job { padding-block: clamp(64px, 10vw, 136px); border-top: 1px solid var(--hairline); }
.job-grid { display: grid; gap: 44px; }
.job-head h2 + p { margin-top: 18px; }
@media (min-width: 900px) {
  .job-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: 80px; }
  .job-head { position: sticky; top: calc(var(--header-h) + 48px); align-self: start; } /* the heading waits while the steps scroll past */
}

.job-steps { position: relative; }
/* The job line: a grey track with a brass line that is drawn down it as you scroll. */
.job-track, .job-line { position: absolute; left: 15px; top: 16px; bottom: 0; width: 2px; margin-left: -1px; }
.job-track { background: var(--hairline); }
.job-line { background: var(--brass); transform-origin: top; }

.job-steps > ol > li { position: relative; padding: 0 0 clamp(40px, 6vw, 68px) 58px; }
.job-steps > ol > li:last-child { padding-bottom: 0; }
/* Step numbers sit in grid bubbles, like the grid-line bubbles on a drawing. */
.bubble { position: absolute; left: 0; top: -2px; width: 32px; height: 32px; display: grid; place-items: center; background: var(--paper); border: 1px solid var(--navy); border-radius: 50%; font-size: 0.875rem; font-weight: 620; }
.job-steps h3 + p { margin-top: 8px; max-width: 34em; color: var(--slate); }

/* What a delivery spells out, shown with made-up notes from the sample building. */
.sample-notes { margin-top: 24px; padding-top: 14px; border-top: 1px solid var(--navy); max-width: 36em; }
.sample-notes h4 { margin: 18px 0 6px; font-size: 1rem; font-weight: 620; }
.sample-notes li { padding: 8px 0; border-top: 1px solid var(--hairline); font-size: 0.9375rem; }

/* ---------- Scope ---------- */

.scope { padding-block: clamp(64px, 10vw, 136px); border-top: 1px solid var(--hairline); }
.scope-grid { display: grid; gap: 44px; margin-top: clamp(32px, 5vw, 56px); }
.scope-list h3 { padding-bottom: 14px; border-bottom: 1px solid var(--navy); }
.scope-list li { padding: 13px 0; border-bottom: 1px solid var(--hairline); }
.scope-list p { margin-top: 16px; color: var(--slate); }
.about { margin-top: clamp(44px, 6vw, 72px); max-width: 38em; }
@media (min-width: 900px) {
  .scope-grid { grid-template-columns: 1fr 1fr; gap: 80px; }
}

/* ---------- Questions ---------- */

.questions { padding-block: clamp(64px, 10vw, 136px); border-top: 1px solid var(--hairline); }
.questions-list { margin-top: clamp(28px, 4vw, 48px); max-width: 780px; border-top: 1px solid var(--navy); }
.questions details { border-bottom: 1px solid var(--hairline); }
.questions summary { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 20px 0; font-size: clamp(1.0625rem, 2vw, 1.25rem); font-weight: 600; cursor: pointer; list-style: none; }
.questions summary::-webkit-details-marker { display: none; }
/* A plus sign that becomes a minus sign when the answer is open. */
.questions summary::after { content: "+"; flex: none; width: 1em; text-align: center; font-size: 1.5rem; font-weight: 400; line-height: 1; }
.questions details[open] summary::after { content: "\2212"; }
.questions details p { padding: 0 44px 22px 0; color: var(--slate); max-width: 40em; }

/* ---------- Enquiry flow ---------- */

.enquiry { padding-block: clamp(64px, 10vw, 136px); border-top: 1px solid var(--navy); }
.enquiry h2 + p { margin-top: 18px; }
.enquiry-plain { margin-top: 28px; max-width: 36em; } /* shown only when scripts are off */

.flow { margin-top: 36px; max-width: 760px; }
.flow-progress { height: 2px; background: var(--hairline); }
.flow-progress span { display: block; height: 100%; background: var(--brass); transform-origin: left; transform: scaleX(0.2); transition: transform 420ms var(--ease-in-out); }
.flow-count { margin-top: 12px; }

.q { min-width: 0; margin: 0; padding: 22px 0 0; border: 0; }
.q legend { padding: 0; }
.q h3 { font-size: clamp(1.6rem, 4.6vw, 2.5rem); letter-spacing: -0.025em; outline-offset: 6px; }

/* Large tappable answers, ruled like a schedule rather than boxed like cards. */
.choices { margin-top: 22px; border-top: 1px solid var(--navy); }
.choice {
  display: flex; align-items: center; gap: 16px; width: 100%; min-height: 68px; padding: 14px 6px;
  background: none; border: 0; border-bottom: 1px solid var(--hairline);
  font: inherit; font-size: clamp(1.0625rem, 2.6vw, 1.3rem); font-weight: 560; color: var(--navy); text-align: left; cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transform-origin: left; transition: transform 160ms var(--ease-out);
}
.choice::before { content: ""; flex: none; width: 16px; height: 16px; border: 1.5px solid var(--navy); } /* tick box */
.choice[aria-pressed="true"]::before { background: var(--navy); box-shadow: inset 0 0 0 3px var(--paper); }
.choice:active { transform: scale(0.985); }
@media (hover: hover) and (pointer: fine) {
  .choice:hover { transform: translateX(8px); }
  .choice:hover:active { transform: translateX(8px) scale(0.985); }
}

.field { margin-top: 22px; }
.field label { display: block; margin-bottom: 6px; font-size: 0.9375rem; font-weight: 600; }
.field input { width: 100%; min-height: 52px; padding: 12px 14px; background: var(--paper); border: 1px solid var(--slate); border-radius: 3px; font: inherit; color: var(--navy); } /* 17 px text: phones do not zoom in on focus */
.field input[aria-invalid="true"] { border: 2px solid var(--navy); }
.field-error { margin-top: 8px; padding-left: 10px; border-left: 3px solid var(--brass); font-size: 0.9375rem; font-weight: 600; }
.field-error:empty { display: none; }
.q .note { margin-top: 14px; }
.q .button { margin-top: 26px; }

.summary { margin-top: 22px; padding: 20px 0; border-block: 1px solid var(--navy); white-space: pre-wrap; }
.summary-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin-top: 24px; }
.summary-actions .button { margin-top: 0; }
.copy-status { min-height: 1.5em; margin-top: 12px; font-size: 0.9375rem; font-weight: 600; }
.flow-back { margin-top: 26px; padding: 10px 0; background: none; border: 0; font: inherit; font-size: 0.9375rem; color: var(--slate); text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: 0.22em; cursor: pointer; }

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

.site-footer { padding-block: 56px 40px; border-top: 1px solid var(--navy); font-size: 0.9375rem; }
.footer-grid { display: grid; gap: 36px; }
.footer-grid h2 { margin-bottom: 10px; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.01em; color: var(--brass-ink); }
.footer-grid li { padding: 4px 0; }
.footer-grid img { width: 180px; height: auto; margin-bottom: 18px; }
.footer-base { margin-top: 44px; padding-top: 18px; border-top: 1px solid var(--hairline); color: var(--slate); font-size: 0.875rem; }
.footer-base p + p { margin-top: 6px; }
@media (min-width: 900px) {
  .footer-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) minmax(0, 3fr); gap: 64px; }
}

/* ---------- Plain pages (privacy, 404) ---------- */

.plain { padding-block: clamp(48px, 8vw, 104px) clamp(64px, 10vw, 120px); }
.plain h1 { font-size: clamp(2.5rem, 8vw, 4.5rem); }
.plain .prose { margin-top: 30px; max-width: 40em; }
.plain h2 { margin: 44px 0 12px; font-size: clamp(1.3rem, 2.6vw, 1.6rem); letter-spacing: -0.015em; line-height: 1.2; }
.plain p + p { margin-top: 14px; }
.plain .hero-actions { margin-top: 32px; }

/* ==========================================================================
   The pinned scroll scene.
   Only when scripts are on (.js), the visitor has not asked for reduced motion,
   and the screen is tall enough to hold the stage. The same test is in script.js.

   How it works: .scene-track is a tall strip. .stage sticks to the screen while
   the strip scrolls past, and everything marked .sd plays between its own
   --from and --to (fractions of that pinned scroll). Scrolling back plays it backwards.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) and (min-height: 540px) {
  .js .scene-track { height: 520vh; height: 520svh; }
  .js .stage {
    position: sticky; top: var(--header-h);
    height: calc(100vh - var(--header-h)); height: calc(100svh - var(--header-h)); /* svh: the height with the phone's address bar showing */
    display: grid; grid-template-rows: auto minmax(0, 1fr) auto; row-gap: 14px; padding-block: 18px 20px;
  }

  /* The four steps share one spot and cross-fade, instead of stacking. */
  .js .steps { display: grid; grid-template-columns: 1fr; gap: 0; }
  .js .step { grid-area: 1 / 1; }
  .js .step:nth-child(1) { animation-name: step-first; }
  .js .step:nth-child(n + 2) { animation-name: step-mid; }
  .js .step:last-child { animation-name: step-last; }

  .js .figures { margin-top: 0; }

  /* The drawing and its table share one spot too, so one can turn into the other. */
  .js .stage-visual { display: grid; min-height: 0; pointer-events: none; }
  .js .stage-visual > * { grid-area: 1 / 1; min-height: 0; min-width: 0; }
  .js .stage-visual .elevation { width: 100%; height: 100%; }
  .js .stage-visual .schedule { align-self: center; justify-self: center; max-width: 540px; }

  /* What each kind of part does when its turn comes. */
  .js .panel { transform-box: fill-box; animation-name: panel-in; animation-timing-function: var(--ease-out); }        /* lowered into place */
  .js .dim-line { transform-box: fill-box; transform-origin: 0 0; animation-name: line-draw; animation-timing-function: var(--ease-out); } /* drawn from one end */
  .js .dim-marks { animation-name: fade-in; }
  .js .opening { transform-box: fill-box; transform-origin: center; animation-name: opening-in; animation-timing-function: var(--ease-out); } /* cut out */
  .js .furniture { animation-name: fade-out; }                                                                           /* dimensions clear away */
  .js .flight { transform-box: fill-box; transform-origin: 0 0; animation-name: fly; animation-timing-function: var(--ease-in-out); } /* panel travels to its table row */
  .js .schedule .sd { animation-name: fade-in; }

  /* Browsers with native scroll-driven animation: the scroll position is the clock. */
  @supports (animation-timeline: view()) {
    .js .scene-track { view-timeline: --scene block; view-timeline-inset: var(--header-h) 0px; }
    .js .sd {
      animation-duration: auto; animation-fill-mode: both;
      animation-timeline: --scene;
      animation-range: contain calc(var(--from) * 100%) contain calc(var(--to) * 100%);
    }
    .js .sd:not(.panel, .dim-line, .opening, .flight) { animation-timing-function: linear; }
    /* The job line is drawn so its tip stays 60% of the way down the screen. */
    .js .job-line { animation: line-down linear both; animation-timeline: view(); animation-range: cover 40vh cover calc(100% - 60vh); }
  }

  /* Other browsers: each animation is paused and script.js moves its playhead on scroll. */
  @supports not (animation-timeline: view()) {
    .js .sd, .js .job-line { animation-duration: 1s; animation-fill-mode: both; animation-play-state: paused; }
    .js .sd:not(.panel, .dim-line, .opening, .flight) { animation-timing-function: linear; }
    .js .job-line { animation-name: line-down; animation-timing-function: linear; }
  }

  /* Used for an instant while script.js measures where each panel has to fly to. */
  .js .measuring .sd { animation: none !important; }
}

/* Wide screens: words and totals on the left, the drawing on the right. */
@media (prefers-reduced-motion: no-preference) and (min-height: 540px) and (min-width: 900px) {
  .js .stage { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: minmax(0, 1fr) auto; column-gap: 72px; padding-block: 36px 40px; }
  .js .steps { grid-column: 1; grid-row: 1; align-self: center; }
  .js .figures { grid-column: 1; grid-row: 2; }
  .js .stage-visual { grid-column: 2; grid-row: 1 / 3; }
  .js .step h3 { font-size: clamp(1.9rem, 3vw, 2.6rem); letter-spacing: -0.025em; margin-block: 10px 14px; }
  .js .step p:last-child { font-size: 1.125rem; }
}

@keyframes panel-in { from { opacity: 0; transform: translateY(-30%); } }
@keyframes line-draw { from { transform: scaleX(0); } }
@keyframes line-down { from { transform: scaleY(0); } }
@keyframes opening-in { from { opacity: 0; transform: scale(0.9); } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes fly { 78% { opacity: 1; } to { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--k)); } }
@keyframes step-first { 0%, 86% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-12px); } }
@keyframes step-mid { 0% { opacity: 0; transform: translateY(12px); } 14%, 86% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-12px); } }
@keyframes step-last { 0% { opacity: 0; transform: translateY(12px); } 14%, 100% { opacity: 1; transform: none; } }
