/* Page styles. Brand tokens come from brand.css — do not introduce a colour here. */

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

/* [hidden] MUST WIN, AND WITHOUT THIS IT DOES NOT.
 *
 * The UA stylesheet says `[hidden] { display: none }` at the weakest possible
 * specificity, so ANY class that sets `display` beats it. Two elements here set
 * `display: flex` and are hidden from script — the callback form after it is submitted,
 * and the calculator's totals before there is anything to total — and both stayed on
 * screen. The confirmation "Thanks, I'll be in touch" was rendering directly beneath the
 * form it was confirming.
 *
 * It survived a browser test because the test asserted `element.hidden === true`, which
 * was perfectly true the whole time. The property was set; the pixels disagreed.
 *
 * One rule, at the top, rather than a `[hidden]` override beside every offender — the
 * next element to gain a `display` will be hidden by the same mechanism and nobody will
 * think to check. */
[hidden] { display: none !important; }


body {
  margin: 0;
  background: var(--ark-surface);
  color: var(--ark-body-ink);
  font-family: var(--ark-font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
}

main { width: 100%; max-width: 46rem; margin-inline: auto; padding: 0 20px 72px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* THE RESULT BAND BREAKS OUT OF THE READING COLUMN.
 *
 * The page sets prose at 46rem because that is a comfortable measure for sentences. The
 * two panels above are not sentences — they are a stepped list beside a table — and
 * squeezing a two-column dashboard into a column sized for paragraphs gives both halves
 * about 340px, which is narrower than the step cards can hold a chip and a line of text.
 *
 * `left: 50%` plus a negative half-width is the standard break-out. The width is capped
 * against the VIEWPORT rather than the column, so it can never be wider than the screen —
 * a child wider than the viewport widens documentElement.scrollWidth and the whole page
 * then scrolls sideways. */
.result-top {
  position: relative;
  left: 50%;
  width: min(70rem, calc(100vw - 40px));
  margin-left: calc(min(70rem, calc(100vw - 40px)) / -2);
  margin-bottom: 48px;
  display: grid;
  gap: 24px;
}

/* Side by side once there is genuinely room for two columns. Below that they stack, and
 * the steps come first because they explain what the figures are counting. */
@media (min-width: 62rem) {
  .result-top { grid-template-columns: 1.05fr 0.95fr; align-items: start; }
}

/* Both panels carried margins from when they sat in a vertical stack, and the costing
 * block's 48px top margin left the two columns starting at different heights.
 *
 * NAMED SELECTORS, NOT `.result-top > *`. That was the first attempt and it silently did
 * nothing: `.result-top > *` and `.breakdown` have identical specificity, and
 * `.breakdown` is declared further down the file, so it won. A reset that loses to the
 * thing it is resetting is worse than no reset — it looks handled. */
.result-top > .sec,
.result-top > .breakdown { margin: 0; }

/* The costing panel is a card with 28px of padding, so its heading starts 28px lower
 * than the steps heading beside it — two titles on two different lines, which reads as
 * a mistake rather than a pair. The steps column is not a card, so it takes the offset
 * as padding instead. */
/* BOTH COLUMNS ARE CARDS, so their tops align by construction.
 *
 * The first attempt matched only the HEADINGS — a transparent top rule and equal padding
 * on a column that was otherwise not a card. The headings lined up and the panels did
 * not: the costing card's box started 31px above the steps column's first visible thing,
 * so one side of the band appeared to float higher than the other. Two matching boxes
 * removes the arithmetic entirely.
 *
 * The step rows inside take the page ground rather than white, since they now sit on a
 * white panel — the same distinction the other way round. */
.result-top > .sec--2 {
  padding: 28px 30px;
  background: var(--ark-white);
  border: 1px solid var(--ark-hairline);
  border-top: 3px solid var(--ark-olive);
  border-radius: var(--ark-radius-sm);
}
.result-top .steps__item { background: var(--ark-surface); }
.result-top .steps__item--person { background: #FBF4EF; }

h1, h2 { font-family: var(--ark-font-display); color: var(--ark-ink); line-height: 1.2; }

.skip-link {
  position: absolute; top: 0; left: 0; z-index: 10;
  background: var(--ark-olive); color: #fff; padding: 12px 18px;
  transform: translateY(-110%);
}
.skip-link:focus-visible { transform: translateY(0); }

.masthead { padding: 28px 0 8px; }
.wordmark { margin: 0; font-family: var(--ark-font-display); font-weight: 700; color: var(--ark-ink); }

.intro { padding: 20px 0 32px; }
.intro h1 { margin: 0; font-size: clamp(2rem, 6vw, 2.75rem); letter-spacing: -0.02em; }
.lede { max-width: var(--ark-measure); margin: 18px 0 0; font-size: 1.1875rem; }

/* --- form ---------------------------------------------------------------- */

.field { margin-bottom: 26px; }
.field label { display: block; margin-bottom: 8px; font-weight: 600; color: var(--ark-ink); }
.help  { margin: 0 0 10px; font-size: 0.9375rem; color: var(--ark-muted); }

/* SELECTED BY POSITION, NOT BY TYPE, and that is the fix rather than the style.
 *
 * This was `input[type="text"], textarea`, which silently did not match the gate's
 * `type="email"` — so that field rendered at the browser default: narrow, unpadded,
 * square, beside a full-width one. Nothing errors when a selector misses; the field
 * just looks wrong, and only on the page you were not looking at.
 *
 * The callback offer in §5.5 adds `type="tel"` next, and it would have landed in the
 * same hole. Anything inside a .field is a field. */
.field input, .field textarea {
  display: block; width: 100%; padding: 14px 15px;
  font-family: inherit; font-size: 1rem; line-height: 1.5;
  color: var(--ark-ink); background: #fff;
  border: 1px solid var(--ark-hairline); border-radius: var(--ark-radius-sm);
}
/* ITALIC, AND THAT IS A USABILITY FIX RATHER THAN A FLOURISH.
 *
 * The placeholders are worked examples — "Residential plumbing, six people, Surrey" —
 * and upright, at the contrast AA requires of placeholder text, they read exactly like
 * something the visitor already typed. Seen on the built page: three fields that look
 * filled, above a submit button that is correctly disabled, which is a person wondering
 * what they did wrong.
 *
 * Lightening them would fix the confusion and fail the contrast rule. Italic separates
 * example from content without touching the colour, and it says "this is the shape of
 * an answer" — which is what §5.2 wants them to say. */
.field input::placeholder, .field textarea::placeholder {
  color: var(--ark-muted);
  font-style: italic;
}
textarea { resize: vertical; min-height: 9rem; }

/* The task field is the visual centre of the page — §5.2. */
.field--main textarea { min-height: 11rem; border-color: var(--ark-olive-2); }

:focus-visible { outline: 2px solid var(--ark-olive); outline-offset: 2px; }

.count { margin: 6px 0 0; font-size: 0.875rem; color: var(--ark-muted); min-height: 1.2em; }

.linkish {
  margin-top: 10px; padding: 0; border: 0; background: none;
  font: inherit; font-weight: 600; color: var(--ark-olive);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}

.primary {
  padding: 16px 28px; border: 1px solid transparent; border-radius: var(--ark-radius-sm);
  background: var(--ark-olive); color: #fff;
  font-family: inherit; font-size: 1rem; font-weight: 600; cursor: pointer;
}
.primary:hover:not(:disabled) { background: #2c401f; }
.primary:disabled { opacity: 0.5; cursor: default; }

.submit-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 8px; }
.quiet { margin: 0; font-size: 0.9375rem; color: var(--ark-muted); }

.privacy-note {
  margin: 26px 0 0; font-size: 0.9375rem; color: var(--ark-muted);
  max-width: var(--ark-measure);
}
.privacy-note a, .foot a { color: var(--ark-olive); }

/* --- result -------------------------------------------------------------- */

.result-area { margin-top: 48px; }

.submission-toggle {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 12px 14px; margin-bottom: 24px;
  background: #fff; border: 1px solid var(--ark-hairline);
  border-radius: var(--ark-radius-sm); font: inherit; color: var(--ark-muted);
}
/* Collapsed to two lines with a toggle — §5.3. The submission stays visible above the
   answer so the reader can see what was assessed. */
.submission-preview {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: 0.9375rem;
}
.submission-toggle.is-open .submission-preview { -webkit-line-clamp: unset; }

.waiting { color: var(--ark-muted); font-style: italic; }

/* =========================================================================
 * THE WAIT
 *
 * §5.3 asks for one quiet line before the first token, and that is what this was — after
 * which the page fell silent for three more seconds while the steps and the costing were
 * built, then rearranged itself. The silence was the problem: nothing said more was
 * coming, so the movement read as a fault rather than as progress.
 *
 * THE BAR NEVER GUESSES. It sits at the start of the active stage and does not creep;
 * the shimmer on the active label carries "still working". A bar that animates towards a
 * number somebody guessed will finish before the work does, and then the reader watches
 * a finished page move.
 * ========================================================================= */

.progress { margin: 4px 0 28px; }

/* The whole document appears at once when it is ready. A fade rather than a hard cut:
 * after ten seconds of an empty column, content snapping into place is its own kind of
 * jolt. Nothing moves — only opacity — so it cannot be mistaken for the layout shifting. */
#result:not([hidden]),
#result-top:not([hidden]),
#after-result:not([hidden]) {
  animation: reveal 260ms ease-out both;
}
@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  #result:not([hidden]),
  #result-top:not([hidden]),
  #after-result:not([hidden]) { animation: none; }
}

.progress__stages {
  list-style: none; display: flex; flex-wrap: wrap; gap: 8px 22px;
  margin: 0 0 12px; padding: 0;
  font-size: 0.875rem; color: var(--ark-muted);
}
.progress__stage { display: flex; align-items: center; gap: 8px; }

/* A dot per stage — empty, filling, filled. The state is never colour alone: a done
 * stage also takes a check, and the active one takes weight and ink. */
.progress__stage::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--ark-hairline); background: transparent;
}
.progress__stage.is-active { color: var(--ark-ink); font-weight: 600; }
.progress__stage.is-active::before { border-color: var(--ark-olive); background: var(--ark-olive); }
.progress__stage.is-done { color: var(--ark-olive); }
.progress__stage.is-done::before {
  border-color: var(--ark-olive); background: var(--ark-olive);
}

.progress__track {
  height: 4px; border-radius: 999px; background: var(--ark-hairline); overflow: hidden;
}
.progress__fill {
  display: block; height: 100%; width: 0;
  background: var(--ark-olive);
  border-radius: 999px;
  transition: width 420ms ease-out;
  position: relative;
}
/* The shimmer sits on the TRACK ahead of the fill, so movement means "working" without
 * the bar claiming ground it has not covered. */
.progress__track::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(56, 81, 47, 0.16), transparent);
  transform: translateX(-100%);
  animation: progress-sweep 1.6s ease-in-out infinite;
}
.progress__track { position: relative; }
@keyframes progress-sweep {
  to { transform: translateX(100%); }
}

.progress__status { margin: 10px 0 0; font-size: 0.9375rem; color: var(--ark-muted); }

@media (prefers-reduced-motion: reduce) {
  .progress__track::after { animation: none; }
  .progress__fill { transition: none; }
}

/* --- skeletons, so a promoted panel is never an empty box ---------------- */

.skeleton { display: grid; gap: 12px; padding: 6px 0 4px; }
.skeleton__line {
  display: block; height: 13px; border-radius: 6px;
  background: linear-gradient(90deg, var(--ark-hairline), #F2EFE6, var(--ark-hairline));
  background-size: 200% 100%;
  animation: skeleton-shift 1.4s ease-in-out infinite;
}
.skeleton__line--wide { width: 78%; }
.skeleton__line--short { width: 45%; }
@keyframes skeleton-shift {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton__line { animation: none; }
}

/* =========================================================================
 * THE RESULT
 *
 * This is the product. Everything above it is a form, and everything below it is a
 * follow-up — the six sections between are the only thing the visitor came for, and the
 * only thing they will judge ArkSystems on.
 *
 * SO IT IS SET AS A DOCUMENT RATHER THAN AS A REPLY. §5.4 gives each section a weight —
 * quiet, prominent, numbered, normal, distinct, paired — and the job of this block is to
 * make those weights visible enough that a reader who skims still lands on the two that
 * matter: what kind of job this is, and what should stay with a person.
 *
 * Nothing here decorates. Every rule below is a difference in emphasis the brief asked
 * for, or the whitespace that makes those differences legible.
 * ========================================================================= */

/* --- the header, so it reads as something prepared ---------------------- */

.result-head {
  margin: 8px 0 34px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--ark-hairline);
}
.result-head__eyebrow {
  margin: 0 0 6px;
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  /* Terracotta INK, never the raw hex — 12px is small text and needs 4.5:1. */
  color: var(--ark-terracotta-ink);
}
.result-head__title {
  margin: 0; font-size: clamp(1.5rem, 4vw, 2rem); letter-spacing: -0.02em;
  /* Their own words, so it can be any length. */
  overflow-wrap: anywhere;
}
.result-head__meta {
  margin: 10px 0 0; font-size: 0.875rem; color: var(--ark-muted);
}

/* --- the sections ------------------------------------------------------- */

.sec { margin-bottom: 40px; }
.sec h2 {
  margin: 0 0 12px; font-size: 1.3125rem; letter-spacing: -0.01em;
}
.sec p { margin: 0 0 14px; }
.sec p:last-child { margin-bottom: 0; }
.sec ol, .sec ul { margin: 0; padding-left: 1.35em; }
.sec li { margin-bottom: 12px; }

/* Each section fades up as it lands, so a reader watching text arrive sees it settle
 * into place rather than jump. Cheap, and it is what makes streaming feel composed
 * rather than twitchy. */
.sec { animation: sec-in 320ms ease-out both; }
@keyframes sec-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* §5.4 section 1 — quiet, small. It is a restatement, and a restatement that shouts is
 * the reader being told what they just typed. */
.sec--0 {
  margin-bottom: 34px; padding-left: 16px;
  border-left: 2px solid var(--ark-hairline);
  color: var(--ark-muted);
}
.sec--0 h2 {
  font-family: var(--ark-font-body);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ark-muted);
  margin-bottom: 6px;
}
.sec--0 p { font-size: 0.9375rem; }

/* §5.4 section 2 — PROMINENT, and the heading/body relationship is INVERTED to do it.
 *
 * Everywhere else the heading is display type and the body is prose. Here the heading
 * drops to a small label and the ANSWER takes the display face, because "what kind of
 * job is this" is the single most valuable sentence on the page — it is the finding, and
 * a finding set in the same 17px as everything around it reads as another paragraph.
 *
 * This is the one place a reader who reads nothing else should still leave with
 * something. */
.sec--1 {
  margin-bottom: 44px; padding: 26px 28px;
  background: var(--ark-white);
  border: 1px solid var(--ark-hairline);
  border-top: 3px solid var(--ark-olive);
  border-radius: var(--ark-radius-sm);
}
.sec--1 h2 {
  font-family: var(--ark-font-body);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ark-terracotta-ink);
  margin-bottom: 10px;
}
.sec--1 p {
  font-family: var(--ark-font-display);
  font-size: clamp(1.125rem, 2.6vw, 1.375rem);
  line-height: 1.45;
  color: var(--ark-ink);
}

/* §5.4 section 3 — numbered, GENEROUS SPACING, and a spine down the left.
 *
 * The rule connecting the markers is what turns a numbered list into a sequence: these
 * steps happen in order and each one hands to the next, which is the actual claim the
 * section is making. */
.sec--2 ol:not(.steps) {
  list-style: none; padding-left: 0; margin: 0;
  counter-reset: step; position: relative;
}
/* The spine was a hairline first and was invisible against the cream ground — present
 * in the DOM, aligned to the pixel, and doing nothing. A connector nobody can see is
 * dead CSS, so it takes the section tint at 3px, which reads as a soft thread between
 * the markers without competing with them. */
.sec--2 ol:not(.steps)::before {
  content: ""; position: absolute; left: 12.5px; top: 14px; bottom: 14px;
  width: 3px; border-radius: 2px; background: var(--ark-green-soft);
}
.sec--2 ol:not(.steps) li {
  counter-increment: step; position: relative;
  padding-left: 46px; margin-bottom: 20px;
}
.sec--2 ol:not(.steps) li:last-child { margin-bottom: 0; }
.sec--2 ol:not(.steps) li::before {
  content: counter(step);
  position: absolute; left: 0; top: 1px;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--ark-olive); color: #fff;
  font-family: var(--ark-font-body);
  font-size: 0.8125rem; font-weight: 700; line-height: 28px; text-align: center;
}

/* §5.4 section 4 — normal. The honest obstacle, and it stays plain: dressing up the
 * difficult part is how a page stops being believed. */
.sec--3 { margin-bottom: 40px; }

/*
 * §5.4 section 5 — "What should stay with a person".
 *
 * This section earns the trust and MUST NOT read as a footnote. The brief gives it a
 * terracotta rule and a tinted ground; it also gets the most padding of anything on the
 * page, because presence is what stops a reader treating it as a caveat at the end.
 *
 * THE HEADING DOES THE WORK, NOT THE COLOUR. §15 forbids colour alone carrying meaning,
 * so the distinction is structural — its own inset block with its own padding, which
 * survives greyscale, high-contrast mode and a stylesheet that fails to load.
 */
.sec--4 {
  margin: 44px 0; padding: 28px 30px;
  background: var(--ark-green-soft);
  border-left: 4px solid var(--ark-terracotta);
  border-radius: 0 var(--ark-radius-sm) var(--ark-radius-sm) 0;
}
.sec--4 h2 { color: var(--ark-ink); font-size: 1.375rem; }
.sec--4 p { color: var(--ark-body-ink); }

/* §5.4 section 6 — "two cards or a clearly separated pair".
 *
 * Side by side above 34rem, because two things you can do this week are a PAIR — stacked
 * they read as the first two of a longer list that got cut off, which undersells a
 * section whose whole point is that it is short and finishable. */
.sec--5 ol {
  list-style: none; padding-left: 0; margin: 0;
  counter-reset: step;
  display: grid; gap: 16px;
}
@media (min-width: 34rem) {
  .sec--5 ol { grid-template-columns: 1fr 1fr; }
}
.sec--5 li {
  counter-increment: step; position: relative; margin: 0;
  padding: 44px 20px 20px;
  background: var(--ark-white);
  border: 1px solid var(--ark-hairline);
  border-top: 3px solid var(--ark-olive-2);
  border-radius: var(--ark-radius-sm);
}
.sec--5 li::before {
  content: counter(step);
  position: absolute; left: 20px; top: 16px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--ark-olive); color: #fff;
  font-family: var(--ark-font-body);
  font-size: 0.75rem; font-weight: 700; line-height: 22px; text-align: center;
}

/* =========================================================================
 * THE STEPS, DRAWN
 *
 * Same words the model wrote, in the same order §5.4 fixes. What changes is that each
 * one now says WHO DOES IT — which the prose implied and the reader had to carry in
 * their head across seven items. A plain numbered list is where people stop reading at
 * step two, and this section is where the argument actually lives.
 *
 * THREE COLUMNS INSIDE THE CARD: number, chip, text. The first version hung the number
 * off the list as a ::before inherited from the prose styling, so it sat straddling the
 * card's left border — half on the page, half on the card — and the chip floated in a
 * column far too wide for it. Everything is inside the card's own padding now and every
 * card's text starts on the same left edge.
 * ========================================================================= */

.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.steps__item {
  display: grid;
  grid-template-columns: 1.75rem 6.75rem 1fr;
  gap: 12px;
  align-items: start;
  padding: 15px 18px;
  background: var(--ark-white);
  border: 1px solid var(--ark-hairline);
  border-left: 3px solid var(--ark-olive-2);
  border-radius: var(--ark-radius-sm);
}

/* Sits on the first line of the text, not the top of the card — a two-line step
 * otherwise leaves the number floating above its own sentence. The line-height matches
 * the text's so they share a centre. */
.steps__number {
  width: 1.75rem; height: 1.75rem; border-radius: 50%;
  background: var(--ark-olive); color: #fff;
  font-family: var(--ark-font-body);
  font-size: 0.8125rem; font-weight: 700;
  line-height: 1.75rem; text-align: center;
}

/* THE WORD CARRIES THE MEANING, NOT THE COLOUR — §15, and here it matters more than
 * usual: "a person still decides this" is the reassurance the whole tool is selling.
 * Left to a colour it would vanish in greyscale, in high-contrast mode, and for a
 * reader who cannot separate olive from terracotta. */
.steps__tag {
  display: block;
  font-size: 0.625rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 5px 6px; border-radius: 999px; text-align: center; white-space: nowrap;
  /* Nudged down so the chip's cap-height lines up with the first line of the sentence
   * beside it rather than with the top of its own box. */
  margin-top: 2px;
}
.steps__item--ai .steps__tag { color: var(--ark-olive); background: var(--ark-green-soft); }
.steps__item--person {
  border-left-color: var(--ark-terracotta);
  background: #FDFBF8;
}
.steps__item--person .steps__number { background: var(--ark-terracotta-ink); }
.steps__item--person .steps__tag { color: var(--ark-terracotta-ink); background: #F6E9E1; }

.steps__text { margin: 0; }

@media (max-width: 30rem) {
  /* The chip moves under the number rather than shrinking to a column too narrow to
   * hold "AI RUNS THIS" without breaking mid-word. */
  .steps__item { grid-template-columns: 1.75rem 1fr; gap: 8px 12px; }
  .steps__tag { grid-column: 2; justify-self: start; margin-top: 0; }
  .steps__text { grid-column: 2; }
}

/* =========================================================================
 * WHAT IT IS COSTING — a calculator, not a forecast
 *
 * See the long note in views/page.ts. The short version: every figure is an editable
 * input, including the two the model suggested, because a number the reader can change
 * is an assumption they own and the same number printed beside a field is a claim we
 * made. THE INPUTS ARE STYLED LOUDER THAN THE TOTAL on purpose — the assumptions are
 * the honest part.
 * ========================================================================= */

.breakdown {
  margin: 48px 0 0; padding: 28px 30px;
  background: var(--ark-white);
  border: 1px solid var(--ark-hairline);
  border-top: 3px solid var(--ark-terracotta);
  border-radius: var(--ark-radius-sm);
}
/* Identical metrics to `.sec h2`, so the shared box structure above actually
 * lands both headings on the same line. */
.breakdown h2 { margin: 0 0 12px; font-size: 1.3125rem; line-height: 1.2; }
.breakdown__lede { margin: 0 0 24px; color: var(--ark-body-ink); }
.breakdown__caveat {
  margin: 22px 0 0; padding-top: 18px;
  border-top: 1px solid var(--ark-hairline);
  font-size: 0.9375rem; color: var(--ark-muted);
}

/* The split bar. Proportion at a glance, with the count printed above it — the number
 * is the fact, the bar is the shape of it. */
.split { margin: 0 0 26px; }
.split__caption { margin: 0 0 10px; font-weight: 600; color: var(--ark-ink); }
.split__bar {
  display: flex; gap: 2px; height: 14px; overflow: hidden;
  border-radius: 999px;
}
.split__seg { display: block; border-radius: 2px; }
.split__seg--ai { background: var(--ark-olive-2); }
/* Not colour alone: the person segments are also striped, so the split survives
 * greyscale and a printer. */
.split__seg--person {
  background: var(--ark-terracotta);
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 3px,
    rgba(255, 255, 255, 0.45) 3px, rgba(255, 255, 255, 0.45) 6px
  );
}
.split__key {
  display: flex; gap: 18px; flex-wrap: wrap;
  list-style: none; margin: 10px 0 0; padding: 0;
  font-size: 0.8125rem; color: var(--ark-muted);
}
.split__key li { display: flex; align-items: center; gap: 7px; }
.split__swatch { width: 14px; height: 14px; border-radius: 4px; display: inline-block; }
.split__swatch--ai { background: var(--ark-olive-2); }
.split__swatch--person {
  background: var(--ark-terracotta);
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 3px,
    rgba(255, 255, 255, 0.45) 3px, rgba(255, 255, 255, 0.45) 6px
  );
}

/* TWO BY TWO, not auto-fit. auto-fit gave three columns and left the fourth field
 * stranded on a row of its own next to a large empty space — and because the labels are
 * different lengths, one wrapped to two lines and knocked its input out of alignment
 * with the other two. A fixed pair of columns keeps the four inputs on one baseline
 * whatever the labels do. */
.calc {
  display: grid; gap: 18px 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 30rem) {
  .calc { grid-template-columns: 1fr 1fr; }
}
/* The label may wrap; the inputs still line up, because each field puts its input on the
 * second row of its own two-row grid and the rows are sized together. */
.calc__field { display: grid; grid-template-rows: auto auto; align-content: start; }
.calc__field label { align-self: end; }
.calc__field label {
  display: block; margin-bottom: 6px;
  font-size: 0.875rem; font-weight: 600; color: var(--ark-ink);
  line-height: 1.35;
}
.calc__input {
  display: block; width: 100%; padding: 11px 12px;
  font-family: inherit; font-size: 1.0625rem; font-variant-numeric: tabular-nums;
  color: var(--ark-ink); background: var(--ark-surface);
  border: 1px solid var(--ark-hairline); border-radius: var(--ark-radius-sm);
}
.calc__input::placeholder { color: var(--ark-muted); font-style: italic; }
.calc__hint { margin: 8px 0 0; font-size: 0.8125rem; color: var(--ark-muted); }

.calc__out { margin-top: 24px; padding-top: 22px; border-top: 1px solid var(--ark-hairline); }
.calc__prompt { margin: 0; color: var(--ark-muted); }

/* Three rows, because a difference shown without the two figures it came from is a
 * number the reader has to take on trust — and the first version showed exactly that. */
.outcome { width: 100%; border-collapse: collapse; }
.outcome__caption {
  caption-side: top; text-align: left;
  margin-bottom: 10px; font-size: 0.8125rem; color: var(--ark-muted);
}
.outcome th, .outcome td { padding: 9px 0; text-align: right; }
.outcome thead th {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ark-muted); border-bottom: 1px solid var(--ark-hairline);
}
.outcome tbody th {
  text-align: left; font-weight: 400; color: var(--ark-body-ink);
  padding-right: 12px;
}
.outcome td { font-variant-numeric: tabular-nums; color: var(--ark-ink); }

/* The difference is the row that matters, so it gets the rule above it and the weight —
 * the same way a total sits at the foot of an invoice. It is arrived at, not asserted. */
.outcome__row--diff th, .outcome__row--diff td {
  border-top: 2px solid var(--ark-ink);
  padding-top: 12px;
  font-weight: 700; color: var(--ark-ink);
}
.outcome__row--diff td {
  font-family: var(--ark-font-display);
  font-size: 1.25rem; letter-spacing: -0.01em;
}
.outcome__row--diff th { font-weight: 700; }

/* --- the gate, §5.1 ------------------------------------------------------ */

/* The gate is deliberately NOT a panel or a card. It is two fields where the questions
 * will be, in the same column and the same type — so passing it reads as continuing
 * rather than as clearing a checkpoint. Anything that frames it as a barrier makes it
 * one. */
.gate { max-width: 26rem; }
.gate .quiet { margin-top: 18px; }

.gate-error {
  margin: 14px 0 0; padding: 12px 14px;
  /* Terracotta INK for text — the raw brand hex fails AA at this size. See brand.css. */
  color: var(--ark-terracotta-ink);
  background: #fff; border: 1px solid var(--ark-terracotta);
  border-radius: var(--ark-radius-sm); font-size: 0.9375rem;
}

/* The spent-invite notice, §5.6. Quiet: it explains a change, it does not warn. A
 * spent link still works, so anything that reads as an error would be a lie. */
.notice {
  margin: 0 0 28px; padding: 14px 16px;
  background: var(--ark-green-soft);
  border-left: 3px solid var(--ark-terracotta);
  border-radius: var(--ark-radius-sm);
  font-size: 0.9375rem; color: var(--ark-body);
}
.notice a { color: var(--ark-olive); }

.stream-error {
  margin-top: 18px; padding: 14px 16px;
  /* Terracotta INK for text — the raw brand hex fails AA at this size. See brand.css. */
  color: var(--ark-terracotta-ink);
  background: #fff; border: 1px solid var(--ark-terracotta);
  border-radius: var(--ark-radius-sm); font-size: 0.9375rem;
}
.retry-row { margin-top: 18px; }

/* --- below the result, §5.5 ---------------------------------------------- */

.after { margin-top: 44px; }

.after__row {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding-bottom: 32px; border-bottom: 1px solid var(--ark-hairline);
}

/* The PDF is an <a>, not a <button>, because a download is a navigation. It has to look
 * identical to the other primary actions, so it borrows .primary and only restores what
 * an anchor loses. */
a.primary { display: inline-block; text-decoration: none; }

.secondary {
  display: inline-block; padding: 12px 20px;
  font-family: inherit; font-size: 1rem; font-weight: 600;
  color: var(--ark-olive); background: transparent;
  border: 1.5px solid var(--ark-olive); border-radius: var(--ark-radius-sm);
  cursor: pointer;
}
.secondary:hover:not(:disabled) { background: var(--ark-green-soft); }
.secondary:disabled { opacity: 0.5; cursor: default; }

/* §14 puts terracotta on the callback panel, and §5.5 sets it apart. It is the only
 * block below the result that asks for anything, so it is the only one with a frame. */
.callback {
  margin: 32px 0; padding: 26px 24px;
  background: #fff;
  border: 1px solid var(--ark-hairline);
  border-left: 3px solid var(--ark-terracotta);
  border-radius: var(--ark-radius-sm);
}
.callback h2 { margin: 0 0 8px; font-size: 1.25rem; }
.callback p { margin: 0 0 18px; }
.callback__form { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.callback__form .field { margin-bottom: 0; flex: 1 1 15rem; }
.callback__done { margin: 0; font-weight: 600; color: var(--ark-olive); }
.callback__error {
  margin: 14px 0 0; color: var(--ark-terracotta-ink); font-size: 0.9375rem;
}

.email-copy { margin: 32px 0; }

/* The checkbox is UNCHECKED and must stay so — §5.5(c). The label wraps the input so the
 * whole line is a hit target, which matters more on a phone than the extra markup costs. */
.checkbox {
  display: flex; align-items: flex-start; gap: 10px;
  margin-top: 14px; font-size: 0.9375rem; color: var(--ark-body);
  cursor: pointer; max-width: 34rem;
}
.checkbox input { margin: 2px 0 0; width: 1.05rem; height: 1.05rem; accent-color: var(--ark-olive); }

.email-copy__status { margin: 14px 0 0; font-size: 0.9375rem; color: var(--ark-olive); }
.email-copy__status.is-error { color: var(--ark-terracotta-ink); }

.start-another { margin: 28px 0 0; font-size: 0.9375rem; }
.start-another a { color: var(--ark-olive); }

/* §5.5(e). Quiet, and it stays quiet — it is a disclosure, not a reassurance to sell
 * with. */
.model-note {
  margin: 24px 0 0; padding-top: 20px;
  border-top: 1px solid var(--ark-hairline);
  font-size: 0.875rem; color: var(--ark-muted);
}

/* §5.5(f). The one call to action on the page. */
.closing { margin: 36px 0 0; }
.closing h2 { margin: 0 0 8px; font-size: 1.375rem; }
.closing p { margin: 0 0 20px; max-width: var(--ark-measure); }

@media (max-width: 30rem) {
  .callback__form { align-items: stretch; }
  .callback__form .primary { width: 100%; }
}

.foot { margin-top: 56px; padding-top: 20px; border-top: 1px solid var(--ark-hairline); font-size: 0.9375rem; }

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  /* The section entrance is a nicety. For a reader who has asked for less motion it is
   * removed entirely rather than shortened — `both` on the animation means a disabled
   * one would otherwise leave every section stuck at opacity 0. */
  .sec { animation: none; }
}
