/* Verigrant marketing site: one stylesheet, no framework, and one small script
 * that only sharpens what already works without it.
 *
 * Six documents share it: the home page, the three audience pages, plus
 * /for-agents.html and /security.html. Components are named for what they are
 * rather than for the page they first appeared on, because the second page to
 * want a three-up of cards should not need a second set of rules.
 *
 * Light is the default and dark is a `prefers-color-scheme` override rather
 * than a toggle: a toggle needs script and a stored preference, and the site
 * has nothing else that needs either. Every colour below is a variable so the
 * two themes differ in one block and nowhere else.
 *
 * The palette is the app's (web/static/styles.css), with the same accent and
 * the same ink, so arriving at /app from here does not feel like a different
 * product. The light theme darkens the accent to #0b6e58, because the app's
 * #4cc2a5 is a mid-tone chosen against a near-black background and does not
 * carry text on white.
 *
 * Sizes are tokens too. Type, vertical rhythm, radii and control height are
 * each set once at the top and referenced everywhere below, so the whole site
 * moves together when one of them changes and no page can drift into a scale
 * of its own. */

:root {
  color-scheme: light dark;

  /* Colour ---------------------------------------------------------- */

  --bg: #ffffff;
  --bg-soft: #f4f8fa;
  --surface: #ffffff;
  --surface-2: #eaf0f4;
  --line: #dde5eb;
  --line-strong: #c7d3dc;
  /* A divider between two sections of the same colour. Lighter than --line so
     it reads as a change of subject rather than as a seam. */
  --hairline: rgba(15, 23, 32, 0.08);
  --footer-bg: #eef3f6;
  --text: #0f1720;
  --muted: #55697c;
  --accent: #0b6e58;
  --accent-strong: #085546;
  --accent-soft: rgba(11, 110, 88, 0.08);
  --accent-line: rgba(11, 110, 88, 0.28);
  --accent-ink: #ffffff;
  --shadow-sm: 0 1px 2px rgba(15, 23, 32, 0.05);
  --shadow: 0 1px 2px rgba(15, 23, 32, 0.05), 0 12px 32px -18px rgba(15, 23, 32, 0.35);
  /* What a card rises into on hover, and what the front page's illustrations
     and panels sit on. Deeper and softer than --shadow, which is a resting
     shadow that has to stay quiet under long pages of prose. */
  --shadow-lift: 0 2px 4px rgba(15, 23, 32, 0.06), 0 26px 50px -26px rgba(15, 23, 32, 0.45);

  /* The front page's atmosphere. --accent-glow is the wash behind the hero,
     --band-a and --band-b the closing call to action, and --warn the colour of
     the side of the comparison that is going badly. None of them appear on the
     inner pages, which are argument rather than sales. */
  --accent-glow: rgba(11, 110, 88, 0.18);
  --accent-wash: rgba(11, 110, 88, 0.05);
  --band-a: #0b6e58;
  --band-b: #07483f;
  --band-ink: #ffffff;
  --band-muted: rgba(255, 255, 255, 0.78);
  --band-line: rgba(255, 255, 255, 0.24);
  --warn: #b0533c;
  --warn-soft: rgba(176, 83, 60, 0.08);
  --warn-line: rgba(176, 83, 60, 0.28);

  /* The code specimens keep the app's dark palette in both themes. A token and
     a JSON body are machine text; showing them on the terminal colours they
     actually appear in reads truer than restyling them per theme. */
  --code-bg: #0f1720;
  --code-text: #e8eef4;
  --code-muted: #7d90a3;
  --code-accent: #4cc2a5;
  --code-line: #2a3b4c;

  /* Type ------------------------------------------------------------
     One scale for six pages. The headings are set with clamp so they grow with
     the viewport, but they are capped well short of filling the screen: a
     headline the reader has to pan across is not read faster for being large. */

  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-base: 1.0625rem;
  --text-lede: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);
  --size-h1: clamp(2.25rem, 4.5vw, 3.5rem);
  --size-h2: clamp(1.6rem, 3vw, 2.25rem);
  --size-h3: clamp(1.125rem, 1.4vw, 1.25rem);
  --leading: 1.6;
  --leading-tight: 1.16;

  /* Space -----------------------------------------------------------
     Every section on every page uses --section-y top and bottom, so the page
     has one rhythm rather than a band per component. --section-gap is the
     distance from a section heading to the thing it introduces. */

  --container: 1120px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --section-y: clamp(1.75rem, 4vh, 3rem);
  --section-gap: clamp(1.25rem, 2.5vw, 1.85rem);
  --measure: 62ch;
  --header-h: 4rem;

  /* Shape ------------------------------------------------------------ */

  --radius-xs: 6px;
  --radius-sm: 10px;
  --radius: 14px;
  --radius-lg: 18px;
  --radius-pill: 999px;
  --control-h: 2.5rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1720;
    --bg-soft: #131e28;
    --surface: #16212c;
    --surface-2: #1e2c3a;
    --line: #263646;
    --line-strong: #35495c;
    --hairline: rgba(232, 238, 244, 0.09);
    --footer-bg: #0b131b;
    --text: #e8eef4;
    --muted: #97a8b9;
    --accent: #4cc2a5;
    --accent-strong: #6ad3b9;
    --accent-soft: rgba(76, 194, 165, 0.12);
    --accent-line: rgba(76, 194, 165, 0.34);
    --accent-ink: #04241c;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 16px 40px -24px rgba(0, 0, 0, 0.9);
    --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 28px 56px -28px rgba(0, 0, 0, 1);

    --accent-glow: rgba(76, 194, 165, 0.22);
    --accent-wash: rgba(76, 194, 165, 0.06);
    --band-a: #12483c;
    --band-b: #0a2b31;
    --band-ink: #eefaf6;
    --band-muted: rgba(238, 250, 246, 0.76);
    --band-line: rgba(120, 220, 195, 0.24);
    --warn: #e08d72;
    --warn-soft: rgba(224, 141, 114, 0.1);
    --warn-line: rgba(224, 141, 114, 0.3);

    --code-bg: #0b131b;
    --code-line: #22323f;
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Anchored sections land below the sticky header instead of under it. */
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--text-base) / var(--leading) system-ui, -apple-system, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  line-height: var(--leading-tight);
  letter-spacing: -0.021em;
  margin: 0 0 0.6rem;
  text-wrap: balance;
}

h1 {
  font-size: var(--size-h1);
  letter-spacing: -0.032em;
}
h2 {
  font-size: var(--size-h2);
  letter-spacing: -0.026em;
}
h3 {
  font-size: var(--size-h3);
  line-height: 1.3;
}

/* A reading measure rather than a column width: prose that runs the full width
   of the container is scanned, not read. */
p {
  margin: 0 0 1rem;
  max-width: var(--measure);
}

a {
  color: var(--accent);
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--accent-strong);
}

a:focus-visible,
summary:focus-visible,
.button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

code,
kbd {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.88em;
}

/* Shared furniture ------------------------------------------------------ */

/* One container for the whole site, header and footer included, so nothing
   sits a few pixels off the column above it. */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Present to a screen reader, absent to a sighted one. Used for the table
   caption, which names what the rows are for without repeating the heading
   above it on screen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius-sm);
}

/* Buttons ----------------------------------------------------------------
   Two kinds and no more: one filled primary per view, and a bordered ghost for
   everything beside it. Both are the same height and the same radius as the
   square controls in the header, so a row of them lines up wherever it lands. */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  padding: 0.6rem 1.15rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-weight: 620;
  font-size: var(--text-sm);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.14s ease, border-color 0.14s ease, color 0.14s ease,
    box-shadow 0.14s ease;
}

.button-primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--shadow-sm);
}

.button-primary:hover {
  background: var(--accent-strong);
  color: var(--accent-ink);
}

.button-ghost {
  border-color: var(--line-strong);
  color: var(--text);
  background: var(--surface);
}

.button-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

.button:active {
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .button {
    transition: none;
  }
}

/* There is deliberately no small pill or bubble label above a section heading
   anywhere on this site. A tinted, uppercase, letter spaced chip announcing the
   subject of the heading directly beneath it says nothing the heading does not,
   and it reads as decoration rather than as writing. Where a section needs to
   name its subject before its heading, it says so in an ordinary sentence in
   the flow of the page. */

.lede {
  font-size: var(--text-lede);
  color: var(--muted);
}

/* Vertical rhythm --------------------------------------------------------
   One padding for every section on every page. Separation is carried by the
   change of background between a section and its neighbour, and where two
   neighbours share a background, by a hairline that is lighter than a border
   so the page reads as continuous rather than as stacked panels. */

section {
  padding-block: var(--section-y);
}

section:not(.alt) + section:not(.alt) {
  border-top: 1px solid var(--hairline);
}

/* Wider than a paragraph's measure, because a heading is scanned in one pass
   and the lede under it is still held to `--measure` by the rule on `p`. */
.section-head {
  max-width: 40rem;
  margin-bottom: var(--section-gap);
}

.section-head :last-child {
  margin-bottom: 0;
}

.alt {
  background: var(--bg-soft);
}

/* Header ----------------------------------------------------------------
   The wordmark at one end, and at the other a single cluster: the call to
   action, the account link, the menu. Evenly spaced and the same height, so
   the right side reads as one control rather than as three things that
   happened to end up next to each other. */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

/* Frosted where the browser can do it, opaque where it cannot. The mix stays
   high enough that nothing scrolling underneath shows through as a seam. */
@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))) {
  .site-header {
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
  }
}

.site-header > .wrap {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  margin-right: auto;
}

.brand:hover {
  color: var(--text);
}

.brand img {
  width: 1.625rem;
  height: 1.625rem;
  border-radius: var(--radius-xs);
}

.header-cta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* The call to action in the bar is the same height as the controls beside it
   and no louder than it needs to be. The page's own primary button is the one
   that should carry weight. */
.header-cta .button {
  min-height: var(--control-h);
  padding: 0 0.95rem;
}

/* The two square controls beside the call to action: the account link and the
   menu. They are the same size and the same box so the pair reads as one unit
   rather than as a link that happens to sit next to a button. */
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-h);
  height: var(--control-h);
  padding: 0;
  flex: none;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease, background-color 0.14s ease;
}

.icon-button:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

.icon-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* The menu is a `details` element, so the hamburger opens it with no script at
   all and carries its own expanded state for a screen reader. The script beside
   it only adds the two conveniences a native disclosure lacks: closing on
   Escape and closing when the reader clicks somewhere else.

   It is present at every width, desktop included. The bar carries one button
   and one account link at any size, and everywhere else on the site is behind
   this one control, so a reader learns a single place to look. */
.menu {
  position: relative;
}

.menu > summary {
  list-style: none;
}

.menu > summary::-webkit-details-marker {
  display: none;
}

.menu[open] > summary {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

.menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.5rem);
  z-index: 40;
  min-width: 14.5rem;
  padding: 0.4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.menu-panel ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-panel a {
  display: block;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-xs);
  color: var(--text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 550;
  white-space: nowrap;
}

.menu-panel a:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

.menu-panel a[aria-current="page"] {
  color: var(--accent);
}

/* The account pair at the foot of the menu is the same destination as the two
   controls in the bar, so a line separates them from the pages above. */
.menu-rule {
  margin-top: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--line);
}

/* On a narrow phone the wordmark, a call to action and two square controls are
   already the whole width, so the button gives up its padding first. The square
   controls keep their size, because they are the two things on the bar that
   have to be hit with a thumb. */
@media (max-width: 26rem) {
  .site-header > .wrap {
    gap: 0.5rem;
  }

  .header-cta .button {
    padding-inline: 0.7rem;
    font-size: 0.9rem;
  }

  .brand {
    font-size: 1rem;
  }
}

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

.hero {
  background: radial-gradient(ellipse 80% 60% at 12% -20%, var(--accent-soft), transparent 65%),
    var(--bg);
}

.hero p {
  font-size: var(--text-lede);
  color: var(--muted);
}

/* The hero is one column of words, so its width is set here instead of by a
   grid track. It is wider than `--measure`, which is a reading measure for
   body copy: a headline still scans at 46rem, and narrowing it would leave the
   h1 wrapping early against a lot of empty page. The subpages put the same
   class on a paragraph, which does want the reading measure. */
.hero-copy {
  max-width: 46rem;
}

p.hero-copy {
  max-width: var(--measure);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.cta-note {
  margin-top: 1.1rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* A specimen of machine text: a session, a token, a JSON body. It is what the
   deeper pages illustrate themselves with, in place of a diagram. */
.specimen {
  background: var(--code-bg);
  color: var(--code-text);
  border: 1px solid var(--code-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.7;
}

.specimen-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--code-line);
  color: var(--code-muted);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--code-accent);
  flex: none;
}

.specimen pre {
  margin: 0;
  padding: 1rem 0.9rem;
  overflow-x: auto;
  white-space: pre;
}

.specimen .k {
  color: var(--code-accent);
}
.specimen .c {
  color: var(--code-muted);
}

/* Cards and grids ------------------------------------------------------- */

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.15rem, 2.5vw, 1.5rem);
}

/* On a soft band the card is the paler of the two, which is the only cue it
   needs. A shadow as well would read as a raised panel on a page that has
   none. */
.alt .card {
  border-color: var(--line);
  box-shadow: var(--shadow-sm);
}

.card h3 {
  margin-bottom: 0.4rem;
}

.card p {
  margin: 0;
  max-width: none;
  color: var(--muted);
  font-size: var(--text-sm);
}

.card p + p {
  margin-top: 0.7rem;
}

/* Two-column feature block: prose on one side, a list on the other. */
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}

@media (min-width: 62rem) {
  .split {
    grid-template-columns: 1fr 1fr;
  }
}

.footnote {
  margin-top: 1.1rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

.checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

/* A checklist sitting under something else in the same column, a specimen or a
   table, rather than opposite it. */
.checklist-tight {
  margin-top: 1.5rem;
  gap: 0.85rem;
  font-size: var(--text-sm);
}

.checklist li {
  position: relative;
  padding-left: 1.9rem;
  color: var(--muted);
  max-width: var(--measure);
}

.checklist li strong {
  display: block;
  color: var(--text);
  font-weight: 620;
}

/* The tick is drawn with a border rather than a glyph so it never falls back
   to a system emoji, which would colour differently in each theme. */
.checklist li::before {
  content: "";
  position: absolute;
  left: 0.25rem;
  top: 0.55rem;
  width: 0.62rem;
  height: 0.34rem;
  border-left: 2.2px solid var(--accent);
  border-bottom: 2.2px solid var(--accent);
  transform: rotate(-45deg);
}

/* A definition-style table for the grant state machine. */
.states {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1.5rem;
  font-size: var(--text-sm);
}

.states th,
.states td {
  text-align: left;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.states th {
  font-weight: 620;
  color: var(--muted);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.states td:last-child {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.86rem;
  white-space: nowrap;
}

.states tr:last-child td {
  border-bottom: 0;
}

/* The grant-state table's right column is a status line, so it is monospace
   and never wraps. The scope and tool tables are prose in that column, so this
   modifier hands it back to the body font, and lets the first column be the
   machine-readable one instead. */
.states-text td:last-child {
  font-family: inherit;
  font-size: inherit;
  white-space: normal;
}

.states-text td:first-child {
  white-space: nowrap;
  color: var(--text);
}

/* Below 34rem a three-column tool table is unreadable at any font size, so the
   middle column, what each tool needs, folds under the name it belongs to. */
@media (max-width: 34rem) {
  .states-text,
  .states-text tbody,
  .states-text tr,
  .states-text td {
    display: block;
    width: auto;
  }

  .states-text thead {
    display: none;
  }

  .states-text tr {
    padding-block: 0.7rem;
    border-bottom: 1px solid var(--line);
  }

  .states-text td {
    border-bottom: 0;
    padding: 0.1rem 0;
  }

  /* A stacked cell has lost its column header, so the one that would be
     ambiguous on its own carries its label with it. */
  .states-text td[data-label]::before {
    content: attr(data-label) ": ";
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    color: var(--muted);
  }
}

/* FAQ ------------------------------------------------------------------- */

.faq {
  max-width: var(--measure);
  display: grid;
  gap: 0.5rem;
}

.faq details {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0 1.1rem;
}

.faq details[open] {
  border-color: var(--line-strong);
}

.faq summary {
  cursor: pointer;
  padding: 0.9rem 0;
  font-weight: 620;
  font-size: var(--text-base);
  line-height: 1.4;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.faq summary::-webkit-details-marker {
  display: none;
}

/* A plus that becomes a minus, drawn in CSS. `details` gives the whole
   disclosure behaviour with no script, and this is the only affordance it is
   missing. */
.faq summary::after {
  content: "+";
  color: var(--accent);
  font-size: 1.3rem;
  font-weight: 400;
  line-height: 1;
  flex: none;
}

.faq details[open] summary::after {
  content: "\2212";
}

.faq details p {
  margin: 0 0 1rem;
  max-width: none;
  color: var(--muted);
  font-size: var(--text-sm);
}

/* Closing call to action ------------------------------------------------ */

.closing {
  text-align: center;
}

.closing .section-head,
.closing p {
  margin-inline: auto;
}

.closing .cta-row {
  justify-content: center;
}

/* Footer ----------------------------------------------------------------
   The page ends on a band of its own, a shade off the body in both themes, so
   the reader can see the bottom of the document rather than infer it. */

.site-footer {
  background: var(--footer-bg);
  border-top: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vh, 3.5rem);
  color: var(--muted);
  font-size: var(--text-sm);
}

.footer-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  margin-bottom: 2.5rem;
}

.footer-grid h2 {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.85rem;
}

.footer-grid ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.footer-grid a {
  color: var(--text);
  text-decoration: none;
}

.footer-grid a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.colophon {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.colophon p {
  margin: 0;
}

/* ======================================================================
   Components added with the repositioning
   ====================================================================== */

/* A block addressed to a machine rather than to the reader. It is set apart
   because the register changes: the sentences inside are instructions to an
   agent, and running them on into the surrounding prose would read as though
   the page had started talking to the wrong audience. */
.callout {
  margin: 1.5rem 0 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--accent-line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
}

.callout h3 {
  margin-bottom: 0.45rem;
  font-size: 1rem;
}

.callout p {
  margin: 0;
  color: var(--muted);
  font-size: var(--text-sm);
}

.callout p + p {
  margin-top: 0.6rem;
}

.callout code {
  color: var(--text);
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* Endpoint list ----------------------------------------------------------
   A definition list of machine addresses. Two columns where there is room, so
   the URL and what it is for sit on one line; stacked below that, because a
   URL is the one string on the page that must not be allowed to wrap badly to
   fit a narrow column. */

.dl {
  display: grid;
  gap: 0.85rem 1.5rem;
  margin: 1.5rem 0 0;
}

@media (min-width: 44rem) {
  .dl {
    grid-template-columns: minmax(12rem, auto) 1fr;
    align-items: baseline;
  }
}

.dl dt {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text);
  overflow-wrap: anywhere;
}

.dl dd {
  margin: 0;
  color: var(--muted);
  font-size: var(--text-sm);
}

@media (max-width: 43.99rem) {
  .dl dd {
    margin-top: -0.5rem;
  }
}

/* Subpage hero -----------------------------------------------------------
   /for-agents.html and /security.html open with a heading and a paragraph and
   no two-column grid: neither page is selling, so neither needs an
   illustration opposite the words. */

.page-hero {
  background: radial-gradient(ellipse 80% 60% at 12% -20%, var(--accent-soft), transparent 65%),
    var(--bg);
}

/* The same heading column as the home page's hero, so a reader moving between
   the two sees the title break in the same place on the page. */
.page-hero h1 {
  max-width: 46rem;
}

.page-hero p {
  font-size: var(--text-lede);
  color: var(--muted);
}

/* A trail of crumbs back to the front door. Subpages are reached from the
   homepage and from search, and the second kind of arrival has no back button
   worth pressing. */
.crumbs {
  margin: 0 0 1.25rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

.crumbs a {
  text-decoration: none;
}

.crumbs a:hover {
  text-decoration: underline;
}

/* A single column of prose for a page that is all argument, such as the
   security page's long sections, where a `.split` would only ever have one
   side. */
.prose {
  max-width: var(--measure);
}

.prose h3 {
  margin-top: 2rem;
  font-size: var(--size-h3);
}

.prose h3:first-child {
  margin-top: 0;
}

/* ======================================================================
   The slider: one segmented control, used twice
   ====================================================================== */

/* Two things on this site ask the reader to slide between three positions: the
   home page asks which audience they belong to, and every audience page asks
   how much detail they want about how it works. Both are the same control.
 *
 * It is built out of radio buttons and sibling selectors rather than script.
 * That buys three things at once: the arrow keys already move between the
 * positions, a screen reader already announces the group and which position is
 * chosen, and the control still works with no script at all, opening on the
 * first position exactly as it does with script. The script beside it adds one
 * thing only, which is that a link carrying a position in its address opens on
 * that position. */

.slider {
  position: relative;
}

/* Focusable but not visible. Kept in the flow rather than pushed off screen so
   that focusing one does not scroll the page sideways. */
.slider-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

/* How many positions the track carries. Three is the number it was built for
   and stays the default, so nothing that already used the control has to say
   anything. A track with a different number of positions sets `--positions`
   once on the `.slider` and the columns, the thumb width and the travel all
   follow from it. */
.slider-2 {
  --positions: 2;
}

.slider-4 {
  --positions: 4;
}

.slider-control {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--positions, 3), 1fr);
  padding: 0.3rem;
  margin-bottom: 1.75rem;
  max-width: 34rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}

/* The part that actually slides. It is exactly one position wide, so moving it
   by its own width lands it exactly on the next one. */
.slider-thumb {
  position: absolute;
  top: 0.3rem;
  left: 0.3rem;
  bottom: 0.3rem;
  width: calc((100% - 0.6rem) / var(--positions, 3));
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--accent-line);
  box-shadow: var(--shadow-sm);
  transition: transform 0.24s ease;
}

@media (prefers-reduced-motion: reduce) {
  .slider-thumb {
    transition: none;
  }
}

.slider-control label {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  min-height: 2.5rem;
  padding: 0.5rem;
  border-radius: var(--radius-pill);
  text-align: center;
  font-weight: 620;
  font-size: var(--text-sm);
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.14s ease;
}

.slider-control label:hover {
  color: var(--text);
}

@media (max-width: 30rem) {
  .slider-control label {
    padding-inline: 0.2rem;
    font-size: 0.84rem;
  }
}

/* One rule per position, three positions. The panel a position owns is the
   panel in the same place in its own list, so nothing here names a page. */
.slider-panel {
  display: none;
}

.slider-input:nth-of-type(1):checked ~ .slider-panels > .slider-panel:nth-child(1),
.slider-input:nth-of-type(2):checked ~ .slider-panels > .slider-panel:nth-child(2),
.slider-input:nth-of-type(3):checked ~ .slider-panels > .slider-panel:nth-child(3),
.slider-input:nth-of-type(4):checked ~ .slider-panels > .slider-panel:nth-child(4) {
  display: block;
}

.slider-input:nth-of-type(1):checked ~ .slider-control label:nth-of-type(1),
.slider-input:nth-of-type(2):checked ~ .slider-control label:nth-of-type(2),
.slider-input:nth-of-type(3):checked ~ .slider-control label:nth-of-type(3),
.slider-input:nth-of-type(4):checked ~ .slider-control label:nth-of-type(4) {
  color: var(--accent);
}

.slider-input:nth-of-type(2):checked ~ .slider-control .slider-thumb {
  transform: translateX(100%);
}

.slider-input:nth-of-type(3):checked ~ .slider-control .slider-thumb {
  transform: translateX(200%);
}

.slider-input:nth-of-type(4):checked ~ .slider-control .slider-thumb {
  transform: translateX(300%);
}

/* The radio itself is invisible, so its focus ring is drawn on the label that
   stands in for it. */
.slider-input:nth-of-type(1):focus-visible ~ .slider-control label:nth-of-type(1),
.slider-input:nth-of-type(2):focus-visible ~ .slider-control label:nth-of-type(2),
.slider-input:nth-of-type(3):focus-visible ~ .slider-control label:nth-of-type(3),
.slider-input:nth-of-type(4):focus-visible ~ .slider-control label:nth-of-type(4) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The home page's audience choice used to be a single track wrapped in a card,
   and those rules lived here. That question is now asked by the application
   itself on the front door, over the working sample rather than over a set of
   paragraphs, so nothing on this site is scoped to `.selector` any more. The
   track above is still what each audience page uses to offer its own depth. */

/* The numbered steps a how it works panel is made of. The number is drawn in a
   circle rather than left to a list marker, because the three panels must line
   up with each other as the reader slides between them. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  counter-reset: step;
  max-width: var(--measure);
}

.steps li {
  position: relative;
  padding-left: 3rem;
  color: var(--muted);
  counter-increment: step;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.05rem;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
  font-size: var(--text-sm);
}

.steps li strong {
  display: block;
  color: var(--text);
  font-weight: 620;
  margin-bottom: 0.15rem;
}

.steps code {
  color: var(--text);
  overflow-wrap: anywhere;
}

/* The homepage footer is the colophon alone, with no link grid above it, so
   the rule that separates the two would be a second line under the footer's
   own border. */
.site-footer > .wrap > .colophon:first-child {
  padding-top: 0;
  border-top: 0;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
}

.footer-links a {
  color: var(--text);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ======================================================================
   The selling pages
   ======================================================================

   Everything below is scoped to `body.home` and `body.landing`. The home page
   carries the first; the three audience pages carry the second. They are the
   same shape and the two names exist only so a rule can say which page it came
   from. The two remaining documents, /for-agents.html and /security.html, carry
   neither: a reader arrives on one having already decided they are interested,
   and a long left column of prose is the right shape for that.

   A selling page has the opposite job. It has to hold someone who has not
   decided anything yet, so it is built as a stack of bands on a single centre
   line, each one a different colour from the one above it, each one carrying a
   drawing rather than only words.

   The scoping matters more than it looks. `.hero`, `.card`, `.grid` and
   `.closing` are all shared with the reference pages, so the rules that make a
   selling page loud are written as overrides rather than as changes to the
   components themselves. Nothing here can reach the other two documents.

   Drawings are inline SVG with no external files. Every fill and stroke in
   them is a theme variable, which is the reason they are inline: an <img> is
   a fixed set of colours and would be wrong in one of the two themes. */

/* The axis ---------------------------------------------------------------
   One centre line from the header to the footer. The container narrows a
   little from the site default, because a centred column reads as a column
   only while the eye can take in both edges at once. It is set on the body so
   the header and the footer narrow with the page and the wordmark stays flush
   with the hero beneath it. */

:is(.home, .landing) {
  --container: 1080px;
}

:is(.home, .landing) main {
  text-align: center;
}

/* Prose is still held to a reading measure; centring it means centring the
   measure rather than letting the line run to the container's edge. */
:is(.home, .landing) main p,
:is(.home, .landing) main .section-head,
:is(.home, .landing) main .hero-copy {
  margin-inline: auto;
}

:is(.home, .landing) main .cta-row {
  justify-content: center;
}

/* A deeper rhythm than the inner pages use. The front page is scrolled, and a
   band needs air around it to read as a band. Separation is carried entirely
   by the change of colour from one band to the next, so the hairline the inner
   pages draw between two same-coloured sections is dropped here: no two
   neighbours on this page share a background. */
:is(.home, .landing) main > section {
  padding-block: clamp(3rem, 7vh, 5rem);
  border-top: 0;
}

:is(.home, .landing) main .section-head {
  max-width: 46rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

:is(.home, .landing) main .section-head p {
  font-size: var(--text-lede);
  color: var(--muted);
}

/* Two words of the headline in the accent, as a gradient rather than a flat
   fill so the colour moves across the line. The colour is set first and the
   clip second, so a browser that cannot clip a background to text still shows
   the words in the accent instead of showing nothing at all. */
.grad {
  color: var(--accent);
  background: linear-gradient(96deg, var(--accent), var(--accent-strong) 52%, var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .grad {
    color: transparent;
  }
}

/* Cards that rise ---------------------------------------------------------
   One hover behaviour, shared by every card on the page. It is a class rather
   than a rule on `.card`, because the inner pages use `.card` for reference
   material that should not move when a cursor crosses it. */

.lift {
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

:is(.home, .landing) main .lift:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: var(--accent-line);
}

@media (prefers-reduced-motion: reduce) {
  :is(.home, .landing) main .lift,
  :is(.home, .landing) main .lift:hover {
    transition: none;
    transform: none;
  }
}

/* Scroll reveal -----------------------------------------------------------
   Sections fade up as they arrive. The hidden state is behind `.js` on the
   root element, which the page sets in a line of script in the head: if the
   script never runs, nothing is ever hidden, and the page reads exactly as it
   does now with the animation simply absent. That ordering is the whole point.
   Hiding first and revealing later would leave a blank page behind any failure.

   Under `prefers-reduced-motion` the rule is dropped in CSS as well as skipped
   in script, so neither half can reintroduce the movement on its own. */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.55s ease, transform 0.55s ease;
  transition-delay: var(--d, 0ms);
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Illustrations -----------------------------------------------------------
   The palette every inline drawing on the page paints with. Named for the role
   rather than for the shape, so the same class is the card surface in the hero
   and the node surface in the flow diagram. */

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

.illus text {
  font-family: inherit;
  letter-spacing: -0.01em;
}

.illus .f-surface {
  fill: var(--surface);
}
.illus .f-panel {
  fill: var(--bg-soft);
}
.illus .f-muted {
  fill: var(--surface-2);
}
.illus .f-soft {
  fill: var(--accent-soft);
}
.illus .f-accent {
  fill: var(--accent);
}
.illus .f-ink {
  fill: var(--text);
}
.illus .f-none {
  fill: none;
}
.illus .s-line {
  stroke: var(--line-strong);
}
.illus .s-soft {
  stroke: var(--line);
}
.illus .s-accent {
  stroke: var(--accent);
}
.illus .s-accent-line {
  stroke: var(--accent-line);
}
.illus .s-surface {
  stroke: var(--surface);
}
.illus .s-warn {
  stroke: var(--warn);
}
.illus .s-warn-line {
  stroke: var(--warn-line);
}
.illus .f-warn-soft {
  fill: var(--warn-soft);
}
.illus .t-ink {
  fill: var(--text);
  font-weight: 640;
}
.illus .t-muted {
  fill: var(--muted);
}
.illus .t-accent {
  fill: var(--accent);
  font-weight: 640;
}

/* A line icon, drawn at 24 and placed in a tinted badge. Every step, benefit
   and proof point on the page uses this pair, which is what keeps a grid of
   eight different drawings looking like one set. */

.icon {
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-badge {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin: 0 auto 1rem;
  border-radius: var(--radius);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
}

.icon-badge-round {
  border-radius: 50%;
}

.icon-badge-sm {
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: 0.75rem;
}

.icon-badge-sm .icon {
  width: 1.15rem;
  height: 1.15rem;
}

/* 1. Hero -----------------------------------------------------------------
   A wash of accent behind the headline, then the drawing under it rather than
   beside it: the page is one centred column, and a two-column hero would break
   that axis in the first screenful. */

:is(.home, .landing) main > section.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(3.25rem, 8vh, 5.5rem) clamp(3rem, 7vh, 5rem);
  background: linear-gradient(180deg, var(--accent-wash), transparent 55%), var(--bg);
}

/* The glow. A single wide ellipse bled off the top of the band, sitting behind
   the content and taking no clicks. */
:is(.home, .landing) .hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: -18rem;
  width: min(78rem, 150%);
  height: 38rem;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, var(--accent-glow), transparent 62%);
  pointer-events: none;
}

:is(.home, .landing) .hero h1 {
  max-width: 20ch;
  margin-inline: auto;
}

:is(.home, .landing) .hero .hero-copy {
  max-width: 44rem;
}

:is(.home, .landing) .hero p {
  max-width: 40rem;
  font-size: var(--text-lede);
  color: var(--muted);
}

.hero-art {
  max-width: 40rem;
  margin: clamp(2.25rem, 5vw, 3.25rem) auto 0;
  filter: drop-shadow(0 16px 26px rgba(15, 23, 32, 0.1));
}

@media (prefers-color-scheme: dark) {
  .hero-art {
    filter: drop-shadow(0 16px 30px rgba(0, 0, 0, 0.45));
  }
}

/* The permission chip lifts a little away from the card it belongs to, which
   is the one thing on the page that says the grant is a separate object the
   reader can pick up and put down. */
.hero-art .float {
  animation: float 7s ease-in-out infinite;
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-7px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-art .float {
    animation: none;
  }
}

:is(.home, .landing) .hero .hero-note {
  margin-top: 1.25rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* 2. Proof band -----------------------------------------------------------
   Four claims on one strip. The dividers are the grid's own gap showing the
   panel colour through a one pixel gutter, so they land correctly at four
   columns, at two and at one without a rule per breakpoint. */

/* Lifted into the bottom of the hero rather than placed under it, so the first
   scroll of the page is one composition instead of a headline followed by a
   row of claims. */
:is(.home, .landing) main > section.proof {
  padding-block: 0;
  margin-top: clamp(-3.25rem, -4vw, -1.75rem);
}

.proof-strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}

@media (min-width: 40rem) {
  .proof-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 62rem) {
  .proof-strip {
    grid-template-columns: repeat(4, 1fr);
  }
}

.proof-item {
  padding: clamp(1.35rem, 3vw, 1.85rem) 1.15rem;
  background: linear-gradient(180deg, var(--surface), var(--bg-soft));
}

.proof-item strong {
  display: block;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.proof-note {
  display: block;
  margin-top: 0.3rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* 3. The problem ----------------------------------------------------------
   Two cards that are meant to be read against each other, with the join
   marked. On a wide screen the marker is the middle column of a three column
   grid; on a narrow one it drops into the stack between them and still reads
   as the hinge. */

.contrast {
  display: grid;
  gap: 1.25rem;
  align-items: stretch;
}

@media (min-width: 58rem) {
  .contrast {
    grid-template-columns: 1fr auto 1fr;
    gap: 1.5rem;
  }
}

.contrast-vs {
  display: grid;
  place-items: center;
}

.contrast-vs span {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-sm);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.contrast-card {
  padding: clamp(1.4rem, 3vw, 2rem);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  text-align: center;
}

.contrast-card h3 {
  margin-bottom: 1.25rem;
  font-size: clamp(1.1rem, 1.8vw, 1.3rem);
}

/* The bad side is tinted and the good side is the accent, so the pair reads
   before either heading is. */
.contrast-bad {
  border-color: var(--warn-line);
  background: linear-gradient(180deg, var(--warn-soft), transparent 70%), var(--surface);
}

.contrast-good {
  border-color: var(--accent-line);
  background: linear-gradient(180deg, var(--accent-soft), transparent 70%), var(--surface);
  box-shadow: var(--shadow);
}

/* The line naming which side of the comparison a card is. It used to be a
   tinted pill, and it is now an ordinary short line of text: the two cards are
   already told apart by their colour and by their headings, so a chip on top of
   both was saying a third time what the reader had understood twice. The
   colour is kept, because that is the part doing the work. */
.contrast-tag {
  margin-bottom: 0.6rem;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 620;
}

.contrast-bad .contrast-tag {
  color: var(--warn);
}

.contrast-good .contrast-tag {
  color: var(--accent);
}

/* A list of short lines with a mark against each. The list itself is an
   inline block, so it is centred as a block while its lines stay left aligned
   against their marks: centred text with a hanging marker reads as neither. */
.mark-list {
  display: inline-block;
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}

.mark-list li {
  position: relative;
  padding-left: 1.9rem;
  color: var(--muted);
  font-size: var(--text-sm);
  max-width: 26rem;
}

.mark-list li + li {
  margin-top: 0.85rem;
}

/* Both marks are drawn rather than typed, for the same reason the checklist's
   is: a glyph would fall back to a system emoji and colour itself. */
.mark-yes li::before {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: 0.5rem;
  width: 0.62rem;
  height: 0.34rem;
  border-left: 2.2px solid var(--accent);
  border-bottom: 2.2px solid var(--accent);
  transform: rotate(-45deg);
}

.mark-no li::before,
.mark-no li::after {
  content: "";
  position: absolute;
  left: 0.25rem;
  top: 0.72rem;
  width: 0.8rem;
  height: 2.2px;
  border-radius: 2px;
  background: var(--warn);
}

.mark-no li::before {
  transform: rotate(45deg);
}

.mark-no li::after {
  transform: rotate(-45deg);
}

/* 4 and 5. Step and benefit grids -----------------------------------------
   Four across on a wide screen, two on a tablet, one on a phone. The columns
   are declared rather than left to auto-fit, so four cards never resolve to a
   row of three and a widow. */

.quad {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 38rem) {
  .quad {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64rem) {
  .quad {
    grid-template-columns: repeat(4, 1fr);
  }
}

.trio {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 52rem) {
  .trio {
    grid-template-columns: repeat(3, 1fr);
  }
}

:is(.home, .landing) .card {
  text-align: center;
  border-radius: var(--radius-lg);
  padding: clamp(1.35rem, 3vw, 1.75rem);
  box-shadow: var(--shadow-sm);
}

:is(.home, .landing) .card p {
  max-width: none;
  margin-inline: 0;
}

.step-n {
  display: block;
  margin-bottom: 0.35rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

/* 6. The flow -------------------------------------------------------------
   One drawing of the whole idea, read left to right. Below about 46rem there
   is no honest way to keep four nodes and their labels legible across the
   width of a phone, so the diagram keeps its size and the reader scrolls it
   sideways, rather than shrinking to type nobody can read. */

.flow-scroll {
  overflow-x: auto;
  padding-bottom: 0.5rem;
  -webkit-overflow-scrolling: touch;
}

.flow-scroll > .illus {
  min-width: 44rem;
}

.flow-caption {
  margin-top: 1.5rem;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* 7. Pick your side -------------------------------------------------------
   The three audience cards. The whole card is not a link, because each one
   carries a named link a screen reader can read out of context, but the card
   still lifts so the pointer knows it is a target. */

.side-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.side-card .side-link {
  margin-top: auto;
  padding-top: 0.9rem;
  font-weight: 640;
  font-size: var(--text-sm);
  text-decoration: none;
}

.side-card .side-link:hover {
  text-decoration: underline;
}

/* 8. The security line ----------------------------------------------------
   One sentence in a bordered strip, sized to itself rather than to the
   container: it is a footnote to the page, not a section of it. */

:is(.home, .landing) main > section.trustline {
  padding-block: clamp(2rem, 4vh, 2.75rem);
}

.trustline-inner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  max-width: 46rem;
  padding: 0.9rem 1.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  margin-block: 0;
  font-size: var(--text-sm);
  color: var(--muted);
  text-align: center;
}

.trustline-inner .icon {
  width: 1.15rem;
  height: 1.15rem;
  color: var(--accent);
}

.trustline-inner a {
  font-weight: 640;
  text-decoration: none;
  border-bottom: 1px solid var(--accent-line);
}

.trustline-inner a:hover {
  border-bottom-color: currentColor;
}

/* 9. Closing band ---------------------------------------------------------
   The one band on the site that sets its own colours rather than the theme's.
   It is the last thing on the page and it is meant to end the argument, so it
   is the only place that carries the accent as a field instead of as a
   detail. */

:is(.home, .landing) main > section.closing {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3.5rem, 8vh, 5.5rem);
  border-top: 1px solid var(--band-line);
  background: linear-gradient(145deg, var(--band-a), var(--band-b));
  color: var(--band-ink);
}

:is(.home, .landing) .closing::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 55% 70% at 50% 0%, rgba(255, 255, 255, 0.14), transparent 65%);
  pointer-events: none;
}

:is(.home, .landing) .closing > .wrap {
  position: relative;
}

:is(.home, .landing) .closing h2 {
  color: var(--band-ink);
  max-width: 20ch;
  margin-inline: auto;
}

:is(.home, .landing) main .closing p {
  max-width: 38rem;
  color: var(--band-muted);
  font-size: var(--text-lede);
}

/* On a coloured field the filled accent button disappears into the ground, so
   the primary inverts: the page's ink becomes the button and the band's colour
   becomes its label. */
.button-invert {
  background: var(--band-ink);
  color: var(--band-a);
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, 0.6);
}

.button-invert:hover {
  background: var(--band-ink);
  color: var(--band-b);
  box-shadow: 0 14px 28px -12px rgba(0, 0, 0, 0.7);
}

.button-onband {
  border-color: var(--band-line);
  color: var(--band-ink);
  background: transparent;
}

.button-onband:hover {
  border-color: var(--band-ink);
  color: var(--band-ink);
  background: rgba(255, 255, 255, 0.1);
}

:is(.home, .landing) .closing .band-note {
  margin-top: 1.35rem;
  font-size: var(--text-sm);
  color: var(--band-muted);
}

:is(.home, .landing) .closing a:focus-visible,
:is(.home, .landing) .closing .button:focus-visible {
  outline-color: var(--band-ink);
}

/* The footer follows the band, so it drops the border it would otherwise draw
   against a body-coloured section above it. */
:is(.home, .landing) .site-footer {
  border-top: 0;
}

/* ======================================================================
   The audience pages
   ======================================================================

   Three documents, one for each way of arriving: /job-seekers.html,
   /employers.html and /agents.html. They are built from the front page's
   components and add only what a page addressed to one reader needs and the
   front page does not. */

/* The how-it-works slider ------------------------------------------------
   On the front page the segmented control and the pitch it changes are drawn
   as one surface, because a floating pill above an unrelated card reads as two
   objects. An audience page asks a different question with the same control,
   how much detail the reader wants, so it gets the same treatment under a name
   of its own rather than by borrowing the front page's.

   The card sets its text left. The page around it is centred, and a numbered
   list of steps is the one thing on it that cannot be: a centred line under a
   hanging marker belongs to neither the marker nor the column. */

.slider-card {
  max-width: 48rem;
  margin-inline: auto;
  padding: clamp(1.35rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  text-align: left;
}

/* The track is the width of the card it sits in, so the three positions divide
   the whole unit rather than floating in one corner of it. */
.slider-card .slider-control {
  max-width: none;
}

.slider-card .steps {
  max-width: none;
}

/* Steps with an icon -----------------------------------------------------
   The same four steps at three depths, so the four icons are the same in all
   three panels: sliding between levels changes the words and nothing else,
   which is what makes the levels feel like one explanation rather than three.

   The badge takes the place of the number circle `.steps` draws, and the
   number moves into a small line above the step's own title, the way the
   front page labels its step cards. */

.steps-icons li {
  padding-left: 3.75rem;
}

.steps-icons li::before {
  content: none;
}

.steps-icons li strong::before {
  content: "Step " counter(step);
  display: block;
  margin-bottom: 0.1rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

.step-badge {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
}

.step-badge .icon {
  width: 1.35rem;
  height: 1.35rem;
}

/* Blocks that keep their own alignment -----------------------------------
   An audience page centres its prose, but three things on it are read rather
   than scanned and stay left aligned inside a centred column: the questions,
   the note addressed to a machine, and any list with a marker hanging off it. */

.landing .faq,
.landing .callout {
  margin-inline: auto;
  text-align: left;
}

.landing .callout {
  max-width: var(--measure);
}

.landing .faq details p {
  margin-inline: 0;
}

/* The proof band's fourth claim is often the one that needs two lines, so the
   strip is allowed to sit on the page rather than lift into the hero when
   there is no room for the overlap. */
.landing .proof-item strong {
  text-wrap: balance;
}

/* A pair of headline numbers under a hero, for the pages whose proof is a
   quantity rather than a claim. */
.stat-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 2.5rem;
  margin-top: 1.5rem;
}

.stat {
  min-width: 8rem;
}

.stat b {
  display: block;
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--accent);
  line-height: 1.1;
}

.stat span {
  font-size: var(--text-sm);
  color: var(--muted);
}

/* Two details the front page never needed ---------------------------------
   It has no trail of crumbs, because it is the front door, and its closing
   band carries no link inside a paragraph. An audience page has both. */

:is(.home, .landing) .hero .crumbs {
  font-size: var(--text-sm);
}

/* On the coloured band the accent is the ground, so a link in the band's own
   prose is drawn in the band's ink instead of disappearing into it. */
:is(.home, .landing) .closing p a {
  color: var(--band-ink);
  text-decoration-color: var(--band-line);
}

:is(.home, .landing) .closing p a:hover {
  color: var(--band-ink);
  text-decoration-color: currentColor;
}

/* The eight cell picker that used to open the front page is gone with the page
   it opened. The front door is the application's own document now, and the two
   questions it asks are asked by the running product in `web::demo::audience`,
   over the live sample rather than over eight paragraphs. What is left here is
   the one rule the audience pages borrowed from it.

   A line under a control saying what happens if the reader does not touch
   it, so the default position is not mistaken for the only one. */
.picker-note {
  margin: 1.25rem auto 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* ======================================================================
   Bands the rebuilt pages add
   ====================================================================== */

/* A block inside the centred page that keeps its own left alignment, because
   it is a paragraph somebody reads rather than a claim they scan. The centred
   page pushes prose to the middle of its measure, so the override has to undo
   the automatic margins as well as the alignment. */
:is(.home, .landing) main .aligned {
  text-align: left;
}

:is(.home, .landing) main .aligned p,
:is(.home, .landing) main .aligned .section-head,
:is(.home, .landing) main .aligned .cta-row {
  margin-inline: 0;
  justify-content: flex-start;
}

/* The case for one audience: the argument on one side, a drawing or a list of
   outcomes on the other. Alternating sides down the page keeps three of these
   in a row from reading as one long column. */
.audience {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: center;
  text-align: left;
}

@media (min-width: 62rem) {
  .audience {
    grid-template-columns: 1.05fr 0.95fr;
  }

  .audience-flip > :first-child {
    order: 2;
  }
}

.audience h2 {
  margin-bottom: 0.9rem;
}

.audience-aside {
  padding: clamp(1.35rem, 3vw, 1.85rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, var(--accent-soft), transparent 65%), var(--surface);
  box-shadow: var(--shadow);
}

.audience-aside h3 {
  margin-bottom: 1rem;
}

.audience-aside .checklist {
  margin-top: 0;
}

.audience-aside :last-child {
  margin-bottom: 0;
}

/* The one sentence the whole site rests on, set once at full size on a band of
   its own. It is a sentence rather than a slogan, and it is allowed to take up
   room, because everything above and below it is an elaboration of it. */
.creed {
  text-align: center;
}

.creed-line {
  max-width: 44rem;
  margin: 0 auto;
  font-size: clamp(1.3rem, 3.2vw, 2rem);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.022em;
  color: var(--text);
  text-wrap: balance;
}

.creed-line em {
  font-style: normal;
  color: var(--accent);
}

.creed-note {
  max-width: 40rem;
  margin: 1.5rem auto 0;
  font-size: var(--text-lede);
  color: var(--muted);
}

/* A row of the things a person applies for, drawn as one strip so the point of
   the strip, that it is the same record every time, is made by the shape
   before it is made by the words. */
.vert-strip {
  display: grid;
  gap: 1px;
  grid-template-columns: 1fr;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}

@media (min-width: 40rem) {
  .vert-strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 66rem) {
  .vert-strip {
    grid-template-columns: repeat(5, 1fr);
  }
}

.vert-item {
  padding: clamp(1.35rem, 3vw, 1.75rem) 1.1rem;
  background: linear-gradient(180deg, var(--surface), var(--bg-soft));
}

.vert-item h3 {
  font-size: 1.0625rem;
  margin-bottom: 0.35rem;
}

.vert-item p {
  margin: 0;
  max-width: none;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* The comparison of what a search engine and a reader both want near the top:
   a plain question and a plain answer, stacked, with no disclosure to open.
   The FAQ further down the page is the same content in a control the reader
   can collapse; this is the version that is read in one pass. */
.qa {
  display: grid;
  gap: 1rem;
  text-align: left;
}

@media (min-width: 58rem) {
  .qa {
    grid-template-columns: repeat(2, 1fr);
  }
}

.qa h3 {
  margin-bottom: 0.4rem;
}

.qa p {
  margin: 0;
  max-width: none;
  color: var(--muted);
  font-size: var(--text-sm);
}
