/*
 * The landing page.
 *
 * Wider measure than the console and far more air, because the job is different: the
 * console is read by someone who already knows what they came for, and this is read by
 * someone deciding whether to keep reading. Long-form prose sets in the serif, interface
 * furniture in the sans — the same split the rest of the product uses.
 *
 * No animation, no scroll-triggered reveals. The page argues that this product is careful
 * and does not oversell; a landing page that performs at the reader would undercut that
 * before they reached the second heading.
 */

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}

.button {
  display: inline-block;
  padding: 11px 18px;
  border-radius: 9px;
  font: 600 14.5px var(--sans);
  text-decoration: none;
  white-space: nowrap;
}

.button.primary { background: var(--accent); color: #fff; }
.button.primary:hover { background: var(--accent-2); }

.button.ghost {
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--rule-2);
}
.button.ghost:hover { border-color: var(--accent); color: var(--accent); }

a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* ── header ──────────────────────────────────────────────────────────── */

.nav {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  max-width: 1080px; margin: 0 auto;
  padding: 20px 28px;
}

.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); }

.mark {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  font: 600 18px/1 var(--serif);
}

.wordmark { font: 600 21px/1 var(--serif); letter-spacing: .01em; }

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

.nav nav a {
  color: var(--ink-2);
  text-decoration: none;
  font-size: 14.5px;
}
.nav nav a:hover { color: var(--accent); }
.nav nav a.button { color: #fff; background: var(--accent); }
.nav nav a.button:hover { background: var(--accent-2); color: #fff; }

/* ── hero ────────────────────────────────────────────────────────────── */

.hero {
  max-width: 780px;
  margin: 0 auto;
  padding: 64px 28px 72px;
  text-align: center;
}

.eyebrow {
  margin: 0 0 18px;
  font: 600 11.5px/1 var(--sans);
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--bronze);
}

.hero h1 {
  margin: 0;
  font: 600 clamp(31px, 5vw, 48px)/1.16 var(--serif);
  letter-spacing: -.015em;
}

.lede {
  margin: 22px auto 0;
  max-width: 640px;
  font: 17.5px/1.68 var(--serif);
  color: var(--ink-2);
}

.cta { margin-top: 32px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.undercta { margin: 16px 0 0; font-size: 13.5px; color: var(--ink-3); }

/* ── sections ────────────────────────────────────────────────────────── */

.strip {
  max-width: 1080px;
  margin: 0 auto;
  padding: 56px 28px;
  border-top: 1px solid var(--rule);
}

/* A tinted band, so a long page has a rhythm rather than being one undifferentiated column. */
.strip.alt {
  max-width: none;
  background: var(--room);
  border-top: 1px solid var(--rule);
}
/* 1024 = the 1080 measure minus this section's own 28px padding either side, so a heading
   in a tinted band lines up with the heading in the plain band above it. */
.strip.alt > * { max-width: 1024px; margin-inline: auto; }

/*
 * `margin-block`, not the `margin` shorthand.
 *
 * The full-width bands centre their children with `margin-inline: auto` on `> *`. A later
 * `margin: 0 0 28px` would silently reset that to 0 and shove the heading to the very edge
 * of the viewport while the cards below it stayed centred — which is exactly what it did.
 * Setting only the block axis leaves the centring alone.
 */
.strip h2 {
  margin-block: 0 28px;
  font: 600 27px/1.25 var(--serif);
  letter-spacing: -.01em;
}

/* ── the three steps ─────────────────────────────────────────────────── */

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0; padding: 0;
  display: grid;
  gap: 26px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.steps li { counter-increment: step; }

/*
 * The number is generated, not typed. It is decoration on top of an ordered list that
 * already carries the ordering semantically, so a screen reader announces "1" once rather
 * than twice.
 */
.steps li::before {
  content: counter(step);
  display: grid; place-items: center;
  width: 27px; height: 27px;
  margin-bottom: 13px;
  border-radius: 50%;
  background: var(--accent-bg);
  color: var(--accent);
  font: 600 13px/1 var(--mono);
}

.steps h3, .cards h3 {
  margin: 0 0 8px;
  font: 600 16px/1.35 var(--sans);
}

.steps p, .cards p { margin: 0; color: var(--ink-2); font-size: 14.8px; }

.aside {
  margin: 30px 0 0;
  padding: 16px 18px;
  background: var(--bronze-bg);
  border-left: 3px solid var(--bronze);
  border-radius: 0 8px 8px 0;
  color: var(--ink-2);
  font-size: 14.8px;
}

/* ── card grids ──────────────────────────────────────────────────────── */

.cards {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.cards article {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  padding: 22px;
}

/*
 * The limits read in the warning colour, and are not hidden at the bottom of the page.
 * A customer who finds out about the missing bias audit after signing is a worse outcome
 * for us than one who never signs.
 */
.limits article {
  background: var(--warn-bg);
  border-color: color-mix(in srgb, var(--warn) 28%, transparent);
}
.limits h3 { color: var(--warn); }

/* ── the pledge band ─────────────────────────────────────────────────── */

.pledge {
  max-width: none;
  background: var(--ink);
  color: var(--room);
  border-top: 0;
}
.pledge > * { max-width: 760px; margin-inline: auto; }
.pledge h2 { color: #fff; }
.pledge p { margin-block: 0 14px; font: 16.5px/1.7 var(--serif); color: #c9d2de; }
.pledge p:last-child { margin-block-end: 0; }

/* ── plain list ──────────────────────────────────────────────────────── */

.plain { margin-block: 0; padding-left: 20px; color: var(--ink-2); }
.plain li { margin-bottom: 11px; font-size: 15.2px; }

/* ── tail ────────────────────────────────────────────────────────────── */

.tail {
  max-width: 1080px;
  margin: 0 auto;
  padding: 64px 28px 72px;
  text-align: center;
  border-top: 1px solid var(--rule);
}
.tail h2 { margin: 0 0 10px; font: 600 27px/1.25 var(--serif); }
.tail p { margin: 0 0 24px; color: var(--ink-2); }

footer {
  border-top: 1px solid var(--rule);
  padding: 26px 28px 40px;
  text-align: center;
  font-size: 13px;
  color: var(--ink-3);
}
footer span { display: block; }
footer .dim { margin-top: 6px; max-width: 520px; margin-left: auto; margin-right: auto; }

@media (max-width: 640px) {
  .nav { flex-wrap: wrap; gap: 12px; }
  .nav nav { gap: 15px; font-size: 13.5px; flex-wrap: wrap; }
  .hero { padding: 40px 22px 52px; }
  .strip, .tail { padding: 44px 22px; }
}

/* ── pricing ─────────────────────────────────────────────────────────────
 *
 * Three tiers, with the middle one carrying the weight. The numbers are deliberately
 * provisional — the model is settled and the price is not — so the copy says "from" and
 * the foot of the section says why, rather than inventing a figure that has to be walked
 * back with the first customer who quotes it.
 * --------------------------------------------------------------------- */

#pricing .lede { max-width: 44rem; }

.tiers {
  display: grid; gap: 18px; margin-top: 28px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  align-items: start;
}
.tier {
  position: relative; padding: 24px 22px;
  border: 1px solid var(--rule-2); border-radius: 12px; background: var(--card);
}
.tier.featured { border-color: var(--accent); box-shadow: 0 1px 0 var(--accent) inset; }
.ribbon {
  position: absolute; top: -11px; left: 22px; padding: 3px 10px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font: 600 11px/1.6 var(--sans); letter-spacing: 0.04em;
}
.tier h3 { margin: 0 0 6px; font: 600 17px/1.3 var(--sans); }
.tier .price {
  margin: 0 0 4px; font: 400 15px/1.3 var(--sans); color: var(--ink-2);
}
.tier .price b { font: 600 30px/1.1 var(--sans); color: var(--ink); }
.tier .price span { margin-left: 4px; font-size: 13.5px; color: var(--ink-3); }
.tier-line { margin: 0 0 14px; font: 400 13.5px/1.5 var(--sans); color: var(--ink-3); }
.tier ul { margin: 0 0 14px; padding-left: 18px; }
.tier li { margin-bottom: 6px; font: 400 14px/1.55 var(--sans); color: var(--ink); }
.tier-note {
  margin: 0; padding-top: 12px; border-top: 1px solid var(--rule);
  font: 400 13px/1.55 var(--sans); color: var(--ink-3);
}
.pricing-foot {
  margin-top: 20px; font: 400 13.5px/1.6 var(--sans); color: var(--ink-3);
  max-width: 44rem;
}

/* ── asking for access ───────────────────────────────────────────────── */

.access { margin-top: 26px; max-width: 46rem; text-align: left; }
.access .pair {
  display: grid; gap: 14px; margin-bottom: 14px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.access label {
  display: block; margin-bottom: 14px;
  font: 600 12.5px/1.6 var(--sans); color: var(--ink-2);
}
.access .pair label { margin-bottom: 0; }
.access input, .access textarea {
  display: block; width: 100%; margin-top: 5px; padding: 10px 12px; box-sizing: border-box;
  border: 1px solid var(--rule-2); border-radius: 7px; background: var(--card);
  color: var(--ink); font: 400 14.5px/1.4 var(--sans); resize: vertical;
}
.access input:focus, .access textarea:focus { outline: 2px solid var(--accent); border-color: transparent; }
.access-actions {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 4px;
}
.access-actions .warn { color: var(--bad); font: 400 13px/1.5 var(--sans); }
.access .sent { padding: 20px 0; }
.access .sent h3 { margin: 0 0 8px; font: 600 18px/1.3 var(--sans); }
.access .sent p { margin: 0; max-width: 34rem; color: var(--ink-2); }

/* ── the hero, now that it shows something ───────────────────────────── */

/*
 * Two columns above 900px, stacked below.
 *
 * The words stay first in the source either way, so a narrow screen and a screen reader
 * both get the headline before the picture. The picture is the evidence for the headline,
 * not a decoration in front of it.
 */
.hero {
  /*
   * Wider and left-aligned, overriding the single-column hero above.
   *
   * That one was 780px and centred, which is right for a column of prose and wrong the
   * moment a picture sits beside it: the words were squeezed into about three hundred
   * pixels and the headline broke across four lines. Both properties have to be restated
   * here rather than edited above, because /limits still uses the original.
   */
  max-width: 1180px;
  text-align: left;
  padding: 62px 28px 74px;
  display: grid; gap: 52px; align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
}
.hero-words { min-width: 0; }
.hero-words .lede { margin-left: 0; margin-right: 0; max-width: 46ch; }
.hero .cta { justify-content: flex-start; }
.hero .undercta { max-width: 44ch; }

.hero-shot { margin: 0; min-width: 0; }
.hero-shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--rule); border-radius: 10px;
  box-shadow: 0 2px 4px rgba(20, 24, 33, .04), 0 24px 60px -34px rgba(20, 24, 33, .45);
}
.hero-shot figcaption,
.report-shot figcaption {
  font-size: 13px; line-height: 1.55; color: var(--ink-3);
  margin-top: 12px; max-width: 58ch;
}

.report-shot { margin: 0 0 30px; }
.report-shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--rule); border-radius: 10px;
  box-shadow: 0 2px 4px rgba(20, 24, 33, .04), 0 18px 44px -30px rgba(20, 24, 33, .4);
}

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 28px; }
}

/* ── the line where two sections of caveats used to be ───────────────── */

/*
 * Deliberately quiet, and deliberately still here.
 *
 * The honesty is part of what is being sold, so removing the link would be the wrong kind of
 * tidying. But five warning-coloured cards mid-scroll, read by somebody still working out
 * what this is, is a confession before an introduction. One line, and the page it opens is
 * unedited.
 */
.strip.honest { padding-top: 34px; padding-bottom: 34px; }
.strip.honest p { margin: 0; }
.strip.honest a {
  font: 500 16px/1.5 var(--sans); color: var(--accent); text-decoration: none;
}
.strip.honest a:hover { text-decoration: underline; }
.honest-note {
  font-size: 13.5px; color: var(--ink-3); margin-top: 7px !important; max-width: 62ch;
}

/* ── the founder's note ──────────────────────────────────────────────── */

/*
 * Set in the serif and narrow, because it is the one part of the page written by a person
 * rather than by the product. It is the only proof available before there are customers,
 * and it reads as proof only if it looks like someone wrote it.
 */
.strip.founder p {
  font: 400 17px/1.65 var(--serif); color: var(--ink-2);
  max-width: 58ch; margin: 0 0 15px;
}
.founder-sign {
  font: 500 13.5px/1.5 var(--sans) !important; color: var(--ink-3);
  margin-top: 20px !important;
}

/* The line under the access form that names a real address. */
.sent-note { font-size: 13.5px; color: var(--ink-3); margin-top: 10px; }
.sent-note a { color: var(--accent); }

/*
 * A hero with no picture beside it — the caveats page.
 *
 * The landing hero became a two-column grid when it gained a screenshot. This one is prose
 * only, and inheriting the grid would leave it stranded in the left half of the page.
 */
.hero.solo {
  grid-template-columns: 1fr;
  max-width: 780px;
  text-align: center;
}

/* ── the problem, stated before the solution ─────────────────────────── */

/*
 * Three failures of the thing being replaced, numbered because they are not a sequence but
 * a count — a reader should register "three" without adding them up. The numeral is the
 * only decoration; everything else is the sentence.
 */
.problems {
  display: grid; gap: 26px; margin-top: 30px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.problems article { position: relative; padding-left: 42px; }
.pnum {
  position: absolute; left: 0; top: -2px;
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bad-bg); color: var(--bad);
  font: 600 13.5px/1 var(--sans);
}
.problems h3 { margin: 0 0 8px; font: 600 16px/1.35 var(--sans); }
.problems p { margin: 0; font-size: 14.5px; line-height: 1.62; color: var(--ink-2); }

.problem-turn {
  margin: 34px 0 0; padding-top: 22px; border-top: 1px solid var(--rule);
  font: 400 17px/1.65 var(--serif); color: var(--ink); max-width: 62ch;
}

/*
 * Below the steps, not inside one.
 *
 * These first went into step three, which is where the words they illustrate are. Inside a
 * three-column grid that turned one column into a full-height tower and pushed step four out
 * on its own. They are evidence for the whole section, so they sit under all of it.
 */
.proof-shots {
  display: grid; gap: 26px; margin: 30px 0 0;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
}
@media (max-width: 760px) { .proof-shots { grid-template-columns: 1fr; } }
.proof-shots figure { margin: 0; }
.proof-shots img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--rule); border-radius: 8px;
  box-shadow: 0 1px 3px rgba(20, 24, 33, .05), 0 14px 34px -26px rgba(20, 24, 33, .4);
}
.proof-shots figcaption {
  font-size: 12.5px; line-height: 1.5; color: var(--ink-3); margin-top: 9px;
}

/* ── the five seats ──────────────────────────────────────────────────── */

/*
 * A hiring manager could read this whole page without learning whether it covers the job
 * they are hiring for. These say so, in the product's own words — the copy is lifted from
 * engine/domains.ts so the page and the thing cannot describe themselves differently.
 */
.strip-lede {
  font: 400 16.5px/1.65 var(--serif); color: var(--ink-2);
  max-width: 64ch; margin: 0 0 30px;
}
.domains {
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}
.domains article {
  background: var(--card); border: 1px solid var(--rule); border-radius: 10px;
  padding: 20px 22px;
}
.domains h3 { margin: 0 0 6px; font: 600 15.5px/1.3 var(--sans); }
.domains .who {
  margin: 0 0 11px; font: 500 12.5px/1.5 var(--sans); color: var(--bronze);
}
.domains p { margin: 0; font-size: 14px; line-height: 1.62; color: var(--ink-2); }

.langs {
  margin-top: 30px; padding: 22px 24px;
  background: var(--sunken); border-radius: 10px;
}
.langs h3 { margin: 0 0 12px; font: 600 15px/1.3 var(--sans); }
.langs ul { margin: 0; padding-left: 20px; }
.langs li { font-size: 14.5px; line-height: 1.65; color: var(--ink-2); margin-bottom: 7px; }
.langs b { color: var(--ink); font-weight: 600; }
.langs-note { margin: 12px 0 0; font-size: 13.5px; color: var(--ink-3); }

/* The one disclosure that is legal rather than promotional. */
.pledge-note {
  margin-top: 20px !important; font-size: 13.5px !important; opacity: .72;
}

/*
 * Pricing was a bare <section> where every other band is a .strip, so it inherited none of
 * the page's max-width and its heading sat hard against the left edge. Adding the class is
 * the fix; this note exists because the symptom looked like a broken heading rather than a
 * missing wrapper.
 */
#pricing.strip { padding-top: 56px; }

/*
 * Four steps, four columns.
 *
 * The grid was auto-fitting to three, which left step four alone on a second row looking
 * like an afterthought rather than the last quarter of the sequence. They are a sequence,
 * so they read across.
 */
@media (min-width: 1000px) {
  .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ── the comparison, drawn ───────────────────────────────────────────── */

/*
 * Two screenshots stood in the hero in turn and both failed the same way: a photograph of a
 * screen shows that software exists and says nothing about what changes for the buyer. This
 * is built instead, so it can scale, animate, stay sharp, and say the one thing a hiring
 * manager is buying — you stop seeing only the answer.
 *
 * The left side is deliberately drained of colour and the right is not. That contrast is the
 * argument; the words only confirm it.
 */
.compare {
  margin: 0; display: grid; gap: 18px;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: stretch;
}
@media (max-width: 760px) { .compare { grid-template-columns: 1fr; } }

.compare-side {
  border: 1px solid var(--rule); border-radius: 12px; padding: 18px;
  background: var(--card); display: flex; flex-direction: column; gap: 14px;
}
.compare-side.before { background: var(--sunken); border-style: dashed; }
.compare-side.after { box-shadow: 0 2px 4px rgba(20,24,33,.04), 0 22px 54px -34px rgba(20,24,33,.45); }

.compare-tag {
  font: 600 10.5px/1 var(--sans); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-3);
}
.compare-tag.on { color: var(--accent); }

/* A take-home, as the reader remembers it: pages of it, and one line that matters. */
.doc {
  border: 1px solid var(--rule-2); border-radius: 8px; background: var(--card);
  padding: 16px; display: flex; flex-direction: column; gap: 8px; flex: 1;
}
.doc-line { height: 7px; border-radius: 4px; background: var(--rule); }
.doc-line.short { width: 58%; }
.doc-verdict {
  margin-top: 8px; font: 500 15px/1.4 var(--serif); color: var(--ink-2);
}

.compare-note { margin: 0; font-size: 13px; line-height: 1.55; color: var(--ink-3); }
.compare-note em { display: block; margin-top: 5px; font-style: normal; color: var(--ink-2); }

.mini-report {
  border: 1px solid var(--rule-2); border-left: 3px solid var(--teal);
  border-radius: 0 9px 9px 0; background: var(--card);
  padding: 15px 17px; flex: 1;
}
/*
 * A line rather than a verdict and a number.
 *
 * "Advance" beside a large percentage stood here, and the percentage was the biggest thing
 * above the fold. Every screening tool on the market hands over a number, so leading with one
 * placed this product in that category and then competed on arithmetic — while the thing it
 * actually has, and they do not, is the row of squares underneath.
 */
.mini-top { display: flex; align-items: baseline; gap: 12px; }
.mini-top b {
  font: 600 16.5px/1.25 var(--serif); color: var(--teal);
  letter-spacing: -.01em;
}
.mini-why {
  margin: 9px 0 14px; font: 400 13.5px/1.55 var(--serif); color: var(--ink-2);
}

/* Nine decisions, and whether each was checked before it was committed to. */
.trail { display: flex; gap: 6px; }
.d {
  width: 100%; height: 26px; border-radius: 4px; display: block;
  background: var(--rule);
}
.d.ok { background: var(--teal); }
.d.miss { background: var(--warn); }
.d.bare { background: var(--rule-2); }

.trail-key {
  display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 10px;
  font: 400 11.5px/1.4 var(--sans); color: var(--ink-3);
}
.trail-key span { display: inline-flex; align-items: center; gap: 5px; }
.trail-key .d { width: 10px; height: 10px; border-radius: 3px; }

/* ── motion ──────────────────────────────────────────────────────────── */

/*
 * Enough to feel alive, not enough to perform at the reader.
 *
 * The page sells careful judgement, so it should not bounce. Everything here is one gesture:
 * a short rise and fade as a section arrives, and the nine decision blocks growing in
 * sequence — which is the one animation that carries meaning rather than decorating, because
 * it is the order the candidate actually worked in.
 *
 * All of it is opt-out. Under prefers-reduced-motion nothing moves and nothing is hidden,
 * which matters more than usual here: the reveal works by starting at zero opacity, so a
 * failure to honour the preference would leave a reader with a blank page.
 */
@media (prefers-reduced-motion: no-preference) {
  /*
   * Hidden only once JavaScript has promised to unhide it.
   *
   * The first version keyed off `.reveal` alone, and `.reveal` is added by script — so any
   * failure between adding the class and the observer firing left the section invisible for
   * good. It shipped that way, and a full-page render showed one screen of content above a
   * blank page: everything below the fold had never intersected, so it never appeared.
   *
   * The gate is on the root element, set once, immediately before the observer is attached.
   * No script, no hiding. A thrown error between the two, no hiding. And a timer unhides
   * everything regardless a few seconds in, because content that cannot be read is a worse
   * outcome than an animation that does not play.
   */
  html.motion .reveal {
    opacity: 0; transform: translateY(14px);
    transition: opacity .55s cubic-bezier(.22,.61,.36,1),
                transform .55s cubic-bezier(.22,.61,.36,1);
  }
  html.motion .reveal.shown { opacity: 1; transform: none; }

  .hero-words > *, .compare-side { opacity: 0; animation: rise .6s cubic-bezier(.22,.61,.36,1) forwards; }
  .hero-words > *:nth-child(1) { animation-delay: .05s; }
  .hero-words > *:nth-child(2) { animation-delay: .12s; }
  .hero-words > *:nth-child(3) { animation-delay: .19s; }
  .hero-words > *:nth-child(4) { animation-delay: .26s; }
  .hero-words > *:nth-child(5) { animation-delay: .33s; }
  .compare-side.before { animation-delay: .34s; }
  .compare-side.after  { animation-delay: .46s; }

  @keyframes rise {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
  }

  /* The decision blocks arrive in the order they were made. */
  .trail .d { transform: scaleY(.12); transform-origin: bottom; opacity: .3; }
  .shown .trail .d,
  .compare .trail .d {
    animation: grow .42s cubic-bezier(.22,.61,.36,1) forwards;
  }
  .trail .d:nth-child(1) { animation-delay: .70s; }
  .trail .d:nth-child(2) { animation-delay: .77s; }
  .trail .d:nth-child(3) { animation-delay: .84s; }
  .trail .d:nth-child(4) { animation-delay: .91s; }
  .trail .d:nth-child(5) { animation-delay: .98s; }
  .trail .d:nth-child(6) { animation-delay: 1.05s; }
  .trail .d:nth-child(7) { animation-delay: 1.12s; }
  .trail .d:nth-child(8) { animation-delay: 1.19s; }
  .trail .d:nth-child(9) { animation-delay: 1.26s; }
  .trail-key .d { animation: none !important; transform: none; opacity: 1; }

  @keyframes grow {
    to { transform: scaleY(1); opacity: 1; }
  }

  /*
   * The trap's bars draw themselves.
   *
   * The section they sit in is the argument the whole page rests on, and it was static — the
   * animation in this file was all written for the hero's markup and none of it reached the
   * graphic that replaced the screenshots. A bar that grows is read as a measurement being
   * taken; one that is simply there is read as decoration.
   *
   * The right-hand panel starts fractionally later, so the two are read in order: what the
   * total says, then what the payroll says. That ordering is the point of the graphic.
   */
  .trap .bt i { transform: scaleX(0); transform-origin: left; }
  .shown .trap .bt i, html:not(.motion) .trap .bt i {
    animation: draw .6s cubic-bezier(.22,.61,.36,1) forwards;
  }
  .shown .trap-side .bars li:nth-child(1) .bt i { animation-delay: .10s; }
  .shown .trap-side .bars li:nth-child(2) .bt i { animation-delay: .18s; }
  .shown .trap-side .bars li:nth-child(3) .bt i { animation-delay: .26s; }
  .shown .trap-side.on .bars li:nth-child(1) .bt i { animation-delay: .46s; }
  .shown .trap-side.on .bars li:nth-child(2) .bt i { animation-delay: .54s; }
  .shown .trap-side.on .bars li:nth-child(3) .bt i { animation-delay: .62s; }

  @keyframes draw { to { transform: scaleX(1); } }

  /* The setup rows arrive one after another, the way a form is filled in. */
  .setup-row { opacity: 0; }
  .shown .setup-row, html:not(.motion) .setup-row {
    animation: rise .5s cubic-bezier(.22,.61,.36,1) forwards;
  }
  .shown .setup-row:nth-child(1) { animation-delay: .04s; }
  .shown .setup-row:nth-child(2) { animation-delay: .11s; }
  .shown .setup-row:nth-child(3) { animation-delay: .18s; }
  .shown .setup-row:nth-child(4) { animation-delay: .25s; }
  .shown .setup-row:nth-child(5) { animation-delay: .32s; }

  .button, .tier, .domains article { transition: transform .18s ease, box-shadow .18s ease; }
  .button:hover { transform: translateY(-1px); }
  .domains article:hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(20,24,33,.04), 0 16px 34px -26px rgba(20,24,33,.4);
  }
}

/* ── the second audience ─────────────────────────────────────────────── */

/*
 * Two customers, one engine. A course creator needs a capstone with their name on it; a
 * hiring manager needs a first-stage filter. The page spoke only to the second, so half the
 * outreach had nowhere to land.
 */
.course-split {
  display: grid; gap: 30px; margin-top: 26px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.course-split h3 { margin: 0 0 12px; font: 600 15.5px/1.3 var(--sans); }
.course-split .plain { margin: 0; padding-left: 20px; }
.course-split li {
  font-size: 14.5px; line-height: 1.62; color: var(--ink-2); margin-bottom: 9px;
}
.course-cta {
  margin: 30px 0 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.course-note { font-size: 13.5px; color: var(--ink-3); }

/* A moment's highlight on the field a choice just filled in. */
.just-set {
  animation: flash 1.1s ease-out;
}
@keyframes flash {
  0%   { box-shadow: 0 0 0 0 var(--accent); }
  15%  { box-shadow: 0 0 0 3px var(--accent-bg); }
  100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
}

/* The tier buttons sit at the bottom of each card, aligned across the row. */
.tier { display: flex; flex-direction: column; }
.tier-pick { margin-top: auto; align-self: flex-start; }
.tier .tier-note { margin-bottom: 18px; }

.access-grid select {
  width: 100%; padding: 10px 11px;
  border: 1px solid var(--rule-2); border-radius: 7px;
  background: var(--card); color: var(--ink);
  font: 400 14.5px/1.3 var(--sans);
}

/* ── the signpost to the course page ─────────────────────────────────── */

.courses-nudge {
  display: flex; align-items: center; gap: 30px; flex-wrap: wrap;
  justify-content: space-between;
}
.courses-nudge h2 { margin-bottom: 8px; }
.courses-nudge p { margin: 0; max-width: 60ch; }
.courses-nudge .button { flex: none; }

/* ── what works today, against what does not ─────────────────────────── */

/*
 * Two columns that must not look like a feature comparison.
 *
 * This is a product being honest about what is not built yet, and the usual two-column
 * treatment — ticks on one side, crosses on the other — would read as us against a
 * competitor. So neither column is marked wrong: one is labelled as working and one as being
 * built, and the second is quieter rather than negative.
 */
.state-split {
  display: grid; gap: 22px; grid-template-columns: 1fr 1fr; margin-top: 8px;
}
.state-col {
  border: 1px solid var(--rule); border-radius: 10px;
  padding: 18px 20px; background: var(--card);
}
.state-col:last-child { background: transparent; border-style: dashed; }
.state-tag {
  display: inline-block; margin-bottom: 10px;
  font: 600 10.5px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
}
.state-tag.on { color: var(--good); }

.one-col { grid-template-columns: 1fr; }
.one-col .hero-words { max-width: 62ch; }

@media (max-width: 860px) {
  .shot-pair, .state-split { grid-template-columns: 1fr; }
}


/* ── the trap, drawn ─────────────────────────────────────────────────────
 *
 * Three browser screenshots stood where this does, and they were the wrong tool twice over.
 * A 2720px capture scaled into a thousand-pixel column sets its type at about nine pixels, so
 * it proved a tool existed and said nothing else — and what needs saying is not what the
 * interface looks like. It is what the data does to somebody who trusts it.
 *
 * So the argument is drawn: the report everyone in the company reads, and the same question
 * asked of the rows underneath it. It scales, it stays sharp, it reads at any width, and it
 * says the one thing that sells this product.
 * --------------------------------------------------------------------- */

.trap {
  margin: 0 0 30px;
  display: grid; gap: 16px; grid-template-columns: 1fr 1fr;
}
.trap-side {
  border: 1px solid var(--rule); border-radius: 10px;
  padding: 16px 18px; background: var(--card);
}
.trap-side.on { border-color: var(--accent); box-shadow: var(--shadow); }
.trap-tag {
  display: block; margin-bottom: 14px;
  font: 600 10.5px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
}
.trap-tag.on { color: var(--accent); }

.bars { list-style: none; margin: 0 0 14px; padding: 0; }
.bars li {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: 108px 1fr 44px;
  padding: 5px 0;
}
.bl { font: 400 12.5px/1.3 var(--sans); color: var(--ink-2); }
.bt { height: 15px; background: var(--sunken); border-radius: 3px; overflow: hidden; }
.bt i { display: block; height: 100%; background: var(--ink-3); border-radius: 3px; }
/*
 * The missing third, and the channel that actually pays.
 *
 * Two colours only, and both earn their place: the gap is the finding, and the winner is what
 * you do about it. Everything else stays neutral so the eye lands on those two and not on a
 * chart that has been decorated.
 */
.bt i.gap { background: var(--bad); }
.bt i.good { background: var(--teal); }
.bn {
  font: 500 12px/1.3 var(--mono); color: var(--ink-2);
  text-align: right; font-variant-numeric: tabular-nums;
}
.trap-note { margin: 0; font: 400 13px/1.55 var(--sans); color: var(--ink-2); }
.trap-side.on .trap-note b { color: var(--ink); }

/* ── what a recruiter sets up ────────────────────────────────────────── */

.setup {
  border: 1px solid var(--rule); border-radius: 10px; overflow: hidden;
  background: var(--card);
}
.setup-row {
  display: grid; gap: 20px; grid-template-columns: 150px 1fr;
  padding: 15px 20px; border-top: 1px solid var(--rule);
}
.setup-row:first-child { border-top: 0; }
.setup-k {
  font: 600 11px/1.5 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3);
}
.setup-v b { display: block; font: 600 14.5px/1.45 var(--sans); color: var(--ink); }
.setup-v span {
  display: block; margin-top: 4px;
  font: 400 13.5px/1.55 var(--sans); color: var(--ink-2); max-width: 66ch;
}

@media (max-width: 820px) {
  .trap { grid-template-columns: 1fr; }
  .setup-row { grid-template-columns: 1fr; gap: 6px; }
}

/*
 * The backstop covers the new graphics too.
 *
 * Everything animated here starts invisible or at zero width, so anything that stops the
 * reveal running — a crawler, a print, a throttled background tab, a script that died —
 * would leave the argument of the page as a set of empty bars. The four-second backstop in
 * landing.js adds `.shown` to every section; these make sure the same is true before the
 * root class is ever set, which is the window where a failure would be permanent.
 */
html:not(.motion) .setup-row { opacity: 1; }
html:not(.motion) .trap .bt i { transform: scaleX(1); }
@media print {
  .setup-row { opacity: 1 !important; animation: none !important; }
  .trap .bt i { transform: scaleX(1) !important; animation: none !important; }
}

/*
 * One concrete trap per seat.
 *
 * The seats section listed what each kind of analyst covers and gave no example of what
 * actually goes wrong, so a page selling five different assessments illustrated exactly one
 * of them — the same missing-attribution example, eight times over. A finance buyer read the
 * whole page and saw nothing about a budget.
 *
 * These are the real traps from each seat's own questions. They are what make the difference
 * between the five seats concrete rather than asserted.
 */
.domains .catch {
  margin: 12px 0 0; padding-top: 12px;
  border-top: 1px solid var(--rule);
  font: 400 13px/1.55 var(--sans); color: var(--ink-2);
}
.domains .catch b { color: var(--ink); font-weight: 600; }

/*
 * The route to a real report, which the page did not have.
 *
 * A finished one has been at /sample the whole time — same engine, same bands, same checks —
 * and nothing pointed at it. "What do I get back" is the hiring manager's actual question and
 * the answer was one click away and invisible.
 */
.see-one {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 26px 0 0;
}
.see-one span {
  font: 400 13.5px/1.5 var(--sans); color: var(--ink-2); max-width: 46ch;
}
/*
 * Room to breathe beside the button.
 *
 * `flex-wrap` plus a 46ch cap left this sentence in a column about twenty characters wide on
 * a desktop — nine lines of text next to a button, which reads as a caption that has gone
 * wrong. `flex: 1` lets it take the width the row actually has.
 */
.see-one span { flex: 1; min-width: 260px; max-width: 62ch; }

/* ── the six measures ───────────────────────────────────────────────────
 *
 * The section this page exists for. Everything above it argues that a take-home cannot tell
 * you what you need; this says what we can tell you instead, and it is the only part a
 * competitor cannot copy by writing better prose.
 *
 * Three columns rather than the two the old three-card grid produced, because six is the
 * number and six reads as a set. They are deliberately equal in weight — no highlighted
 * "main" one — since the argument is that a person is rarely the same on all six, and
 * promoting one would undercut it.
 *
 * The heading of each is set in the serif that the report sets its band labels in. These are
 * the same words in both places and they should look like it.
 * --------------------------------------------------------------------- */

.measures {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  margin-top: 26px;
}
.measures article {
  background: var(--card); border: 1px solid var(--rule); border-radius: 12px;
  padding: 20px 22px;
}
.measures h3 {
  margin: 0 0 8px;
  font: 600 16.5px/1.3 var(--serif); color: var(--ink); letter-spacing: -.01em;
}
.measures p { margin: 0; font: 400 14px/1.62 var(--sans); color: var(--ink-2); }
.measures em { font-style: italic; color: var(--ink); }

/* ── the two candidates ─────────────────────────────────────────────────
 *
 * The demonstration under the claim, and the one graphic on this page whose numbers are
 * produced by a check rather than chosen by a writer.
 *
 * It borrows the bar components from the finance graphic above it deliberately: two pictures
 * making the same visual argument in two different visual languages would read as two
 * unrelated assertions. What differs is the frame — this one is a comparison of people, so
 * the two sides are equal and side by side, where the finance one is a correction and its
 * second side is emphasised.
 *
 * The good side is teal rather than green-versus-red across the pair. Red on candidate A
 * would be the page passing a verdict on a person, and the point being made is subtler than
 * that: A is not a bad person, A is a person you cannot see with an answer key.
 * --------------------------------------------------------------------- */

.split { margin: 30px 0 0; }
.split-lede {
  margin: 0 0 16px; text-align: center;
  font: 400 15.5px/1.6 var(--sans); color: var(--ink-2);
}
.split-lede b { color: var(--ink); font-weight: 600; }

.split-grid {
  display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.split-side {
  background: var(--card); border: 1px solid var(--rule); border-radius: 12px;
  padding: 18px 20px;
}
.split-side.on { border-color: var(--teal); }

/*
 * Wider columns than the finance graphic, because these rows carry sentences.
 *
 * The shared `.bars` grid is sized for that other picture, whose labels are one word
 * ("Planned", "Actual") and whose figures are four characters. Here both ends are the
 * product's own vocabulary — "Quotes figures they can back" against "never overclaimed" —
 * and at 108px and 44px they each wrapped onto two lines, which turned a row meant to be
 * read across into three stacked fragments.
 *
 * The bar gives up the width. It is the least informative part of the row: the number beside
 * it is exact and the label says what is being counted, while the bar only has to show which
 * of the two sides is longer.
 */
/*
 * The three figures are the same measure on both sides, so they are worded to line up:
 * "7 overclaimed" against "0 overclaimed" rather than against "never overclaimed". A reader
 * comparing two cards should be comparing numbers, not parsing two ways of saying a count.
 */
.split .bars li { grid-template-columns: 150px 1fr 104px; }
.split .bl { line-height: 1.45; }
.split .bn { white-space: nowrap; }
.split-tag {
  display: block; margin-bottom: 14px;
  font: 600 10.5px/1 var(--sans); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-3);
}
.split-tag.on { color: var(--teal); }
.split-note {
  margin: 0; font: 400 13px/1.6 var(--sans); color: var(--ink-2);
}

/*
 * The line that says what the picture was for.
 *
 * A comparison graphic without a conclusion underneath it makes the reader do the work of
 * deciding what they were shown, and about half of them will decide something else.
 */
.split-out {
  margin: 18px 0 0; text-align: center; max-width: 62ch; margin-inline: auto;
  font: 400 14.5px/1.6 var(--sans); color: var(--ink-2);
}
.split-out b { color: var(--ink); font-weight: 600; }

/* ── the limit, stated ──────────────────────────────────────────────────
 *
 * Set apart from the six rather than as a seventh card, because it is not one of them — it
 * is the boundary around them. Bronze, which is the one colour in this palette that carries
 * neither good news nor bad, so a limit reads as a fact rather than as an apology.
 * --------------------------------------------------------------------- */

.notmeasured {
  margin: 30px 0 0; padding: 18px 22px;
  background: var(--bronze-bg); border-left: 3px solid var(--bronze); border-radius: 0 10px 10px 0;
}
.notmeasured h3 {
  margin: 0 0 7px; font: 600 15px/1.35 var(--sans); color: var(--bronze-2);
}
.notmeasured p {
  margin: 0; max-width: 74ch; font: 400 14px/1.62 var(--sans); color: var(--ink-2);
}

/*
  The away ladder, on the page that has to sell it.

  ── Why a numbered list and not the usual card grid ──────────────────────

  Because it is genuinely a sequence, and the structure should say so. The rest of this page
  uses cards for sets of parallel things — five seats, six measures — where order carries
  nothing. Here the whole argument is that the consequence escalates, and a reader who takes
  the third row for an alternative to the first has misunderstood the product.

  The marker is the trigger rather than a number, for the same reason: "second departure"
  is the information, and "02" would be decoration standing where information fits.
*/
.ladder {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  gap: 0;
  max-width: 60rem;
}
.ladder li {
  display: grid;
  grid-template-columns: minmax(9.5rem, 12rem) minmax(0, 1fr);
  gap: 18px;
  padding: 16px 0;
  border-top: 1px solid var(--rule);
}
.ladder li:last-child { border-bottom: 1px solid var(--rule); }

/*
  The trigger, set apart from the consequence.

  Small caps rather than a heading, so it reads as a label on the row rather than as the
  start of a new section — the consequence beside it is the sentence that matters.
*/
.ladder-when {
  font: 600 12px/1.5 var(--sans);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: 2px;
}
.ladder-what { color: var(--ink-2); line-height: 1.6; }
.ladder-what b { color: var(--ink); font-weight: 600; }

/*
  The three things a buyer asks immediately afterwards.

  All three are concessions or limits rather than claims, which is why they sit under the
  ladder in smaller type instead of becoming three more cards. A limit presented with the
  same weight as a feature reads as a feature nobody quite believes.
*/
.watching-notes {
  display: grid;
  gap: 14px;
  margin: 28px 0 0;
  max-width: 60rem;
}
.watching-notes p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-2);
}
.watching-notes b { color: var(--ink); font-weight: 600; }

@media (max-width: 620px) {
  /* The label stops being a column and becomes a line above what it labels. */
  .ladder li { grid-template-columns: 1fr; gap: 6px; }
}
