/* The site's own chrome.

   The report body brings its own stylesheet (templates/vendor/_report_css.html,
   vendored from axoba_worker) and injects it into the middle of the page, so on
   /r/<slug> its `:root` block is what the whole document reads its variables
   from. That is the design system: the report is the instrument readout, this
   file is the case around it, and the two share a palette because they share the
   variable names rather than because somebody kept two lists in step.

   Every token below is copied from that file, values and names both. Anything
   this file needs that the report has no opinion on (--display, --wrap, --r) is
   named differently and survives the override. Class names are still this file's
   own: nothing here targets one of the report's, so a change on that side is a
   change to the report and not to the page around it.

   The report gained a dark mode; this follows it, off the same tokens. */

:root {
  color-scheme: light dark;

  --paper:#F6F8F8; --surface:#FFFFFF; --sunk:#EDF1F1;
  --ink:#14191A; --ink-2:#566163; --ink-3:#7C8789;
  --line:#DFE6E6; --line-2:#C9D4D4;
  --accent:#0E6B75; --accent-ink:#0A5159; --accent-wash:#E2F0F1;
  --dead:#B03024; --unknown:#96690A; --live:#15715A; --live-wash:#E3F2ED;
  --verdict-bg:#101617; --verdict-fg:#F2F6F6;
  --verdict-dim:#8B9A9C; --verdict-line:#2A3436; --on-fill:#FFFFFF;

  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI Variable Text","Segoe UI",system-ui,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,"Cascadia Mono","SF Mono","JetBrains Mono",Menlo,Consolas,"Liberation Mono",monospace;

  --step--2:0.6875rem; --step--1:0.8125rem; --step-0:1.0625rem; --step-1:1.1875rem;
  --step-2:clamp(1.15rem,1.8vw,1.3rem);
  --step-3:clamp(1.7rem,3.4vw,2.25rem);
  --step-4:clamp(2.2rem,6.2vw,3.8rem);

  /* This file's own, and deliberately not one of the report's step names: the
     landing headline is bigger than anything in a report and must not become a
     third opinion about --step-4. */
  --display:clamp(2rem,3.6vw,2.7rem);

  --gutter:clamp(1.25rem,5vw,3.5rem); --stack:clamp(3rem,7vw,5rem);
  --wrap:66.25rem;   /* 1060px — the report's .wrap, so the chrome lines up with it */
  --narrow:44rem;
  --r:3px; --r-2:2px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:#0D1112; --surface:#151B1C; --sunk:#1B2223;
    --ink:#E7ECEC; --ink-2:#9DAAAB; --ink-3:#778384;
    --line:#242D2E; --line-2:#33403F;
    --accent:#3FC3CE; --accent-ink:#7FDDE4; --accent-wash:#12292C;
    --dead:#FF7062; --unknown:#E3AC46; --live:#48CC9F; --live-wash:#10261F;
    --verdict-bg:#060909; --verdict-fg:#EDF3F3;
    --verdict-dim:#7E8D8F; --verdict-line:#222C2D; --on-fill:#0B1516;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: var(--step-0)/1.62 var(--sans);
  -webkit-font-smoothing: antialiased;
  /* The one string on these pages this file did not write is the channel
     somebody pasted, and it is printed on /scan/<id> and on the account list.
     A 90-character URL with nothing in it to break on is a phone scrolling
     sideways; `break-word` breaks one only when it would otherwise overflow,
     so no line anybody wrote is affected. */
  overflow-wrap: break-word;
}

/* Layout */

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.narrow, .wrap.narrow { max-width: var(--narrow); }

/* Wide monitors. 1060px is the report's width and the reason this file has one
   at all; away from /r/<slug> there is no report to line up with, and a 27"
   monitor showing a 1060px column in the middle of 2560px of paper is a measure
   nobody chose. Steps rather than a vw expression because every paragraph on
   the site is capped in `ch` already: what the extra width buys is the hero,
   the card grid and the footer columns, and each of those wants a container
   that stops somewhere known. `.narrow` is deliberately untouched — a page that
   is only prose is 44rem at every width there is. */
@media (min-width: 90rem)  { :root { --wrap: 76rem; } }   /* ≥1440px viewport */
@media (min-width: 120rem) { :root { --wrap: 84rem; } }   /* ≥1920px viewport */

/* Except on the findings page. The report's own stylesheet pins every `.wrap`
   in that document to 1060px from further down the document than this file can
   reach, and `.site-nav` sizes off the variable rather than the class — so
   without this the nav would be the one element on the page wider than the
   report under it. Widening both is a change to the worker's _report_css.html,
   which is vendored here and not ours to edit (CONTEXT.md, "The report template
   is vendored, not owned"). */
body.report-page { --wrap: 66.25rem; }

/* Every band on the page is separated by a hairline rather than by a colour
   change, which is how the report separates its own sections. */
.band { padding-block: var(--stack); border-top: 1px solid var(--line); }
.band.sunk { background: var(--sunk); }

/* Type */

h1, h2, h3 { text-wrap: balance; }
/* --display and not --step-4: the report body's own headline is the biggest
   type on the site and every headline this file sets sits under it. */
h1 { font-size: var(--display); line-height: 1.06; letter-spacing: -0.032em; font-weight: 800; margin: 0 0 1rem; }
h2 { font-size: var(--step-3); line-height: 1.14; letter-spacing: -0.024em; font-weight: 700; margin: 2.75rem 0 0.75rem; }
h3 { font-size: var(--step-2); line-height: 1.3; letter-spacing: -0.015em; font-weight: 650; margin: 2rem 0 0.4rem; }
p { margin: 0 0 1rem; }

.lede { font-size: var(--step-1); color: var(--ink-2); max-width: 46ch; line-height: 1.55; }
.lede b, .lede strong { color: var(--ink); font-weight: 650; }

/* The mono uppercase label is the report's data voice. It names a section; it
   never carries a fact the sentence under it does not repeat. */
.eyebrow {
  font-family: var(--mono); font-size: var(--step--2); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.15em; color: var(--ink-3);
  margin: 0 0 0.75rem;
}
.fineprint { color: var(--ink-2); font-size: var(--step--1); }
.aside { color: var(--ink-2); font-size: 0.95rem; }
.quote { border-left: 2px solid var(--line-2); padding-left: 1rem; color: var(--ink-2); }
.num { font-variant-numeric: tabular-nums; }

code {
  font-family: var(--mono); font-size: 0.88em;
  background: var(--sunk); border: 1px solid var(--line);
  padding: 0.08em 0.35em; border-radius: var(--r-2);
}

a { color: var(--accent-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration: none; }
:is(a, button, input, textarea, summary):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--r-2);
}

.sec-title { display: flex; flex-direction: column; margin-bottom: 2rem; }
/* On the heading and not on the block around it: `ch` resolves against the
   element's own font-size, and a measure set on the wrapper is a measure in
   body-copy characters applied to display type. */
.sec-title h2 { margin: 0; max-width: 22ch; }
.sec-title p { margin: 0.6rem 0 0; color: var(--ink-2); max-width: 58ch; }
.sec-note { margin-top: 1.5rem; }
.prose { max-width: 66ch; }

/* Every page that is only text. Its own class rather than `main`, because on
   /r/<slug> the report body brings a <main> of its own and it is not this. */
.page { padding-block: clamp(2.25rem, 5vw, 3.25rem) 0; }

/* The line above a headline that says which channel, and when. Mono because it
   is data, and not `.eyebrow` because a channel's name is not ours to shout. */
.meta {
  display: flex; flex-wrap: wrap; gap: 0.45rem 1.1rem; align-items: baseline;
  font-family: var(--mono); font-size: var(--step--1); color: var(--ink-3);
  margin: 0 0 1.15rem;
}
.meta b { color: var(--ink); font-weight: 600; letter-spacing: 0.02em; }

/* A verdict, in one word. Dead unless it says otherwise. */
.tag {
  display: inline-flex; align-items: center;
  font-family: var(--mono); font-size: var(--step--2); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.11em;
  padding: 0.28rem 0.55rem; border-radius: var(--r-2);
  background: var(--dead); color: var(--on-fill);
}
.tag.ok { background: var(--live); }
.tag.q { background: var(--unknown); }

ul.plain { list-style: none; padding: 0; margin: 1rem 0; }
ul.plain li { padding: 0.85rem 0; border-bottom: 1px solid var(--line); }
ul.plain li:last-child { border-bottom: 0; }
.reasons { padding-left: 1.15rem; }
.reasons li { margin-bottom: 0.7rem; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: fixed; left: 0.75rem; top: -3rem; z-index: 10;
  background: var(--ink); color: var(--paper); border-radius: var(--r);
  padding: 0.6rem 0.9rem; font-size: var(--step--1); text-decoration: none;
  transition: top 0.15s ease;
}
.skip:focus { top: 0.75rem; }

/* Nav and footer */

.site-head { border-bottom: 1px solid var(--line); background: var(--paper); }
.site-nav {
  display: flex; align-items: center; gap: 0.5rem 1.35rem; flex-wrap: wrap;
  max-width: var(--wrap); margin-inline: auto;
  padding: 0.9rem var(--gutter);
}
.site-nav .spacer { flex: 1; }
.site-nav .brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--mono); font-weight: 700; font-size: 0.95rem;
  letter-spacing: 0.16em; color: var(--ink); text-decoration: none;
}
.brand-mark {
  width: 0.85rem; height: 0.85rem; border-radius: var(--r-2); flex: none;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.site-nav .nav-link {
  color: var(--ink-2); text-decoration: none; font-size: 0.95rem;
}
.site-nav .nav-link:hover { color: var(--ink); }
/* Where the row would otherwise wrap and put the one action on a line of its
   own. The link is in the footer of every page as well. */
@media (max-width: 34rem) { .site-nav .nav-aside { display: none; } }
/* A 360px phone fits the brand, the one link and the button on a single row
   only just, and the gap is what it comes up short by. Narrower than that it
   wraps, which is the layout at that width rather than a failure of it. */
@media (max-width: 30rem) { .site-nav { gap: 0.5rem 0.9rem; } }

.site-foot {
  border-top: 1px solid var(--line);
  margin-top: var(--stack); padding: 2.75rem 0 3.5rem;
  color: var(--ink-2); font-size: var(--step--1);
}
/* A page that ends on the dark band has already drawn its closing edge; the
   footer's own rule and the gap above it would be a second one. Browsers
   without :has() get the gap, which is the layout this replaces. */
#main:has(.close-band) + .site-foot { margin-top: 0; border-top: 0; padding-top: 3.25rem; }
.site-foot a { color: var(--ink-2); text-decoration: none; }
.site-foot a:hover { color: var(--ink); text-decoration: underline; }
.site-foot p { margin: 0 0 0.6rem; }
.foot-cols {
  display: grid; gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.foot-cols h2 {
  font-family: var(--mono); font-size: var(--step--2); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.15em; color: var(--ink-3);
  margin: 0 0 0.9rem;
}
.foot-cols ul { list-style: none; padding: 0; margin: 0; }
.foot-cols li { margin-bottom: 0.5rem; }
.foot-say { max-width: 30ch; }
.foot-say b { color: var(--ink); font-family: var(--mono); letter-spacing: 0.16em; }
.foot-rule {
  margin-top: 2.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--step--2); color: var(--ink-3);
  letter-spacing: 0.04em;
}

/* Buttons and forms */

.cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.8rem 1.35rem;
  background: var(--accent); color: var(--on-fill);
  border: 1px solid var(--accent); border-radius: var(--r);
  font: inherit; font-weight: 650; font-size: 1rem; line-height: 1.2;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.cta:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--on-fill); }
.cta:active { transform: translateY(1px); }
.cta.sm { padding: 0.5rem 0.9rem; font-size: 0.9rem; }

.scanform {
  display: flex; flex-wrap: wrap; gap: 0.6rem;
  margin: 1.75rem 0 0.75rem; max-width: 34rem;
}
.scanform input {
  flex: 1 1 15rem; min-width: 0;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--line-2); border-radius: var(--r);
  font-family: var(--mono); font-size: 0.95rem;
  background: var(--surface); color: var(--ink);
}
.scanform input::placeholder { color: var(--ink-3); }
.scanform input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-color: transparent; }
/* Wrapped onto its own line the button keeps its own width and reads as
   something left over rather than as the action. Same button, filling the line
   it has already taken. */
@media (max-width: 30rem) { .scanform .cta { width: 100%; } }

.formerror { color: var(--dead); font-size: 0.95rem; font-weight: 600; }

main form { max-width: 26rem; margin: 1.5rem 0; }
main form label { display: block; margin: 1.1rem 0 0.35rem; font-size: 0.95rem; color: var(--ink-2); }
main form :is(input[type=email], input[type=password], input[type=text], textarea) {
  width: 100%; padding: 0.7rem 0.9rem;
  border: 1px solid var(--line-2); border-radius: var(--r);
  font: inherit; background: var(--surface); color: var(--ink);
}
main form button { margin-top: 1.25rem; }
form.inline { display: inline; margin: 0; max-width: none; }
form.inline button { margin: 0; }
.linkish {
  background: none; border: 0; padding: 0; color: var(--ink-2);
  font: inherit; font-size: 0.95rem; cursor: pointer;
}
.linkish:hover { color: var(--ink); }

/* Sign in with Google / Facebook, above the email form on /login and /signup.
   Sized to the same 26rem as `main form` so the two stack as one column. */

.oauth-list { display: grid; gap: 0.6rem; max-width: 26rem; margin: 1.5rem 0 0; }
.oauth-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.65rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--surface); color: var(--ink); text-decoration: none;
  font: inherit; font-weight: 600; font-size: 0.98rem;
}
.oauth-btn:hover { border-color: var(--ink-3); background: var(--sunk); }
.oauth-mark { width: 1.15rem; height: 1.15rem; flex: none; }

/* "or", with a rule either side of it. */
.oauth-or {
  display: flex; align-items: center; gap: 0.75rem;
  max-width: 26rem; margin: 1.5rem 0 0;
  color: var(--ink-3); font-family: var(--mono); font-size: var(--step--2);
  text-transform: uppercase; letter-spacing: 0.15em;
}
.oauth-or::before, .oauth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* Landing: the hero */

.hero { padding-block: clamp(2.5rem, 6vw, 4rem) clamp(2.5rem, 6vw, 4rem); }
.hero-grid { display: grid; gap: clamp(2.25rem, 5vw, 3.5rem); align-items: center; }
@media (min-width: 62rem) {
  .hero-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}
.hero h1 { max-width: 22ch; }
/* A hero already spends the space above the first heading of the page under it. */
.hero + main.page { padding-top: 0; }
main.page section:first-of-type > h2:first-child { margin-top: 0; }
.hero .lede { max-width: 44ch; }
#scan { scroll-margin-top: 5rem; }

/* The scan-readout panel: the one dark surface on the page, and a faithful
   miniature of what the report's own verdict band looks like. It is the product
   rather than a picture of it, which is why it is markup and not a screenshot -
   it reflows, it is selectable, and it cannot go stale against the real one. */

.readout {
  position: relative; overflow: hidden;
  margin: 0;
  background: var(--verdict-bg); color: var(--verdict-fg);
  border: 1px solid var(--verdict-line); border-radius: var(--r);
  border-bottom: 3px solid var(--dead);
}
.readout-bar {
  display: flex; align-items: center; gap: 0.6rem 1rem; flex-wrap: wrap;
  padding: 0.7rem 1.1rem; border-bottom: 1px solid var(--verdict-line);
  font-family: var(--mono); font-size: var(--step--2);
  text-transform: uppercase; letter-spacing: 0.15em; color: var(--verdict-dim);
}
.readout-bar b { color: var(--verdict-fg); font-weight: 700; }
.readout-bar .spacer { flex: 1; }
.readout-body { padding: 1.4rem 1.1rem 1.5rem; }
.readout-what {
  font-family: var(--mono); font-size: var(--step--2); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--verdict-dim);
  margin: 0 0 0.7rem;
}
.readout-url {
  font-family: var(--mono); font-size: clamp(1.05rem, 2.6vw, 1.5rem); font-weight: 600;
  letter-spacing: -0.01em; word-break: break-all; margin: 0 0 0.9rem;
  text-decoration: line-through; text-decoration-color: var(--dead); text-decoration-thickness: 2px;
}
.readout-meta {
  display: flex; align-items: center; gap: 0.6rem 0.9rem; flex-wrap: wrap;
  margin: 0 0 1.4rem;
  font-family: var(--mono); font-size: var(--step--1); color: var(--verdict-dim);
}
.readout-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 1.15rem;
  margin: 0; padding-top: 1.15rem; border-top: 1px solid var(--verdict-line);
}
/* Value above label, so a label that wraps to two lines cannot knock the three
   figures off a common baseline. column-reverse rather than a reordered <dl>:
   the pairing has to stay dt-then-dd for anything reading the markup. */
.readout-stats > div {
  display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: 0.35rem;
}
.readout-stats > div:not(:last-child) { padding-right: 0.9rem; }
.readout-stats > div + div { border-left: 1px solid var(--verdict-line); padding-left: 0.9rem; }
.readout-stats dt {
  font-family: var(--mono); font-size: 0.625rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--verdict-dim);
}
.readout-stats dd {
  margin: 0; font-family: var(--mono); font-size: 1.3rem; font-weight: 700;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.readout-stats .zero { color: var(--dead); }
/* Three columns on a 375px phone is three four-word labels in about 90px each,
   which is a three-line label over every figure. Two columns is the same three
   figures with room to be read; the third drops to a second row and gives up
   the rule down its left, which on a row of one would be a divider standing at
   the start of a line rather than between two things. */
@media (max-width: 30rem) {
  .readout-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .readout-stats > div:nth-child(odd) { border-left: 0; padding-left: 0; }
}
.readout figcaption {
  padding: 0.85rem 1.1rem; border-top: 1px solid var(--verdict-line);
  font-family: var(--mono); font-size: var(--step--2);
  letter-spacing: 0.08em; color: var(--verdict-dim);
}

/* The one moving thing on the site: a single pass of the check across the
   panel, on load, and never again. */
.readout::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 42%, rgba(63, 195, 206, 0.16) 50%, transparent 58%);
  transform: translateX(-110%);
  animation: sweep 1.5s cubic-bezier(0.4, 0, 0.2, 1) 0.35s 1 both;
}
@keyframes sweep { to { transform: translateX(110%); } }

/* The claim strip under the hero. Five things we do, in the data voice, because
   each one is a fact about the scan rather than a benefit. */
.spec {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.6rem;
  list-style: none; margin: clamp(2rem, 4vw, 2.75rem) 0 0; padding: 1.1rem 0 0;
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--step--2);
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-3);
}
.spec li { display: flex; align-items: center; gap: 0.5rem; }
.spec li::before {
  content: ""; width: 0.3rem; height: 0.3rem; flex: none;
  background: var(--accent); border-radius: var(--r-2);
}

/* Three real findings, in the shape a finding actually has. */

/* Three findings are a set, and the third one on a row of its own reads as an
   afterthought rather than as the third. `auto-fit, minmax(12rem, 1fr)` was
   aimed at that and did not reach it: two columns fit from about 430px, three
   only from about 680px, so every phone in landscape and every small tablet got
   exactly the 2+1 the measure was chosen to avoid. Stated as the intent instead
   — three across, or one down, and nothing in between. */
.case-grid { display: grid; gap: 1rem; }
@media (min-width: 44rem) { .case-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.case {
  display: flex; flex-direction: column; gap: 0.45rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1.15rem 1.2rem 1.25rem;
}
.case-who {
  font-family: var(--mono); font-size: var(--step--2); text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-3); margin: 0;
}
.case-n {
  font-size: 1.9rem; font-weight: 800; letter-spacing: -0.035em; line-height: 1;
  font-variant-numeric: tabular-nums; margin: 0.15rem 0 0.1rem;
}
.case-n span { font-size: 0.95rem; font-weight: 500; letter-spacing: 0; color: var(--ink-2); margin-left: 0.4rem; }
.case-what {
  font-family: var(--mono); font-size: 0.85rem; color: var(--ink-2); margin: 0;
  text-decoration: line-through; text-decoration-color: var(--dead); text-decoration-thickness: 1px;
}
.case-tag { margin: 0.5rem 0 0; }
.case-tag .tag { background: none; color: var(--dead); border: 1px solid currentColor; }

/* Free against paid, side by side. The one place on the site that draws the
   line, and it is drawn as two boxes rather than as a sentence with a "but" in
   it: the free half is genuinely complete and genuinely not enough, and neither
   of those reads as true unless both are in view at once. Same 44rem as
   `.case-grid` - two boxes and three cards break to one column together. */
.split { display: grid; gap: 1rem; }
@media (min-width: 44rem) { .split { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.split-col {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1.3rem 1.4rem 1.4rem;
}
/* The same left rule the buy panel carries, so the paid half is marked the same
   way in both places a reader meets it. */
.split-col.paid { border-left: 3px solid var(--accent); }
.split-h {
  font-family: var(--mono); font-size: var(--step--2); text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-3); margin: 0 0 0.9rem;
}
.split-col ul { margin: 0; padding-left: 1.15rem; }
.split-col li { margin-bottom: 0.5rem; }
.split-col li:last-child { margin-bottom: 0; }
.split-note {
  margin: 1rem 0 0; padding-top: 0.9rem; border-top: 1px solid var(--line);
  color: var(--ink-2); font-size: 0.95rem;
}

/* The three steps. A real sequence, so it is numbered; the numbering is the
   report's own step marker. */

.stepline { display: grid; gap: 1.5rem; list-style: none; padding: 0; margin: 0; }
/* 50rem and not 52: a tablet held upright is 820px, and three short steps
   stacked down the middle of it is a screen of white on either side. The same
   number is on `.qa` below, for the same tablet. */
@media (min-width: 50rem) { .stepline { grid-template-columns: repeat(3, 1fr); gap: 2rem; } }
.stepline li { display: flex; flex-direction: column; gap: 0.5rem; }
.stepline .n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.7rem; height: 1.7rem; flex: none;
  border: 1px solid var(--accent); border-radius: 50%;
  font-family: var(--mono); font-size: var(--step--2); font-weight: 700;
  color: var(--accent-ink); margin-bottom: 0.35rem;
}
.stepline b { font-weight: 650; }
.stepline p { margin: 0; color: var(--ink-2); }

/* The one number the whole ranking argument rests on. */

.bigstat {
  display: grid; gap: 1.25rem 2.5rem; align-items: center;
  margin: 2rem 0 0; padding: 1.75rem 0 0; border-top: 1px solid var(--line);
}
@media (min-width: 46rem) { .bigstat { grid-template-columns: auto minmax(0, 1fr); } }
.bigstat-n {
  font-family: var(--mono); font-size: clamp(3.25rem, 11vw, 5.5rem); font-weight: 700;
  letter-spacing: -0.05em; line-height: 0.9; color: var(--dead);
  font-variant-numeric: tabular-nums; margin: 0;
}
.bigstat p { margin: 0; max-width: 42ch; color: var(--ink-2); }
.bigstat p b { color: var(--ink); }

/* Questions, as rows rather than as an accordion: everything on this list is
   something somebody hesitates over, and hiding it behind a click is the wrong
   place to save space. */

.qa { border-top: 1px solid var(--line); margin: 0; }
.qa > div { padding: 1.4rem 0; border-bottom: 1px solid var(--line); }
@media (min-width: 50rem) {
  .qa > div { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: 1rem 2.5rem; }
}
.qa dt { font-weight: 650; letter-spacing: -0.01em; }
.qa dd { margin: 0.4rem 0 0; color: var(--ink-2); max-width: 60ch; }
@media (min-width: 50rem) { .qa dd { margin-top: 0; } }

/* The close, on the same dark surface as the hero panel, so the page opens and
   shuts on the instrument rather than on a second idea. */

/* Centred, and the only thing on the page that is: the argument has been made
   by here and what is left is the one action. */
.close-band {
  background: var(--verdict-bg); color: var(--verdict-fg);
  border-top: 1px solid var(--verdict-line);
  padding-block: var(--stack);
  text-align: center;
}
.close-band h2 { color: var(--verdict-fg); margin: 0 auto 0.75rem; max-width: 22ch; }
.close-band p { color: var(--verdict-dim); max-width: 52ch; margin-inline: auto; }
.close-band .scanform { margin-inline: auto; justify-content: center; }
.close-band .scanform input {
  background: rgba(255, 255, 255, 0.06); border-color: var(--verdict-line); color: var(--verdict-fg);
}
.close-band .scanform input::placeholder { color: var(--verdict-dim); }
.close-band .fineprint { color: var(--verdict-dim); }
.close-band .fineprint a, .close-band p a { color: var(--verdict-fg); }
.close-band .eyebrow { color: var(--verdict-dim); }
/* The teal has nowhere to go against #101617, so the button on this band is the
   paper colour instead. Same button, inverted, rather than a second style. */
.close-band .cta {
  background: var(--verdict-fg); border-color: var(--verdict-fg); color: var(--verdict-bg);
}
.close-band .cta:hover { background: #fff; border-color: #fff; color: var(--verdict-bg); }

/* The report page's own chrome, around the vendored report body.

   Everything below is styled through a class rather than an element, because on
   /r/<slug> the report's stylesheet is later in the document and its bare `p`,
   `h2` and `section` rules would otherwise win here. */

.banner-ok {
  background: var(--accent-wash); border: 1px solid var(--accent);
  border-radius: var(--r);
  padding: 1.15rem 1.3rem; margin: 1.25rem auto 0;
}
.banner-ok p { margin: 0 0 0.75rem; }
.banner-ok p:last-child { margin-bottom: 0; }

/* The neutral sibling of .banner-ok. Nothing good just happened - the reader
   asked for a scan and is being shown the one they already have - so it takes
   the sunk surface rather than the accent wash, which is reserved for a thing
   that went right. */
.banner-note {
  background: var(--sunk); border: 1px solid var(--line-2);
  border-radius: var(--r);
  padding: 1.15rem 1.3rem; margin: 1.25rem auto 0;
}
.banner-note p { margin: 0 0 0.5rem; max-width: 68ch; }
.banner-note p:last-child { margin-bottom: 0; }

/* The buy block, injected into the report body under the fix-list table.
   Sized to sit inside that template's .wrap without fighting it. */
.cta-block {
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--surface);
  padding: 1.6rem; margin: 2rem 0 0;
  border-left: 3px solid var(--accent);
}
.cta-block .cta-title {
  font-size: var(--step-1); font-weight: 700; letter-spacing: -0.015em;
  margin: 0 0 0.5rem;
}
.cta-block p { margin: 0 0 1rem; max-width: 54ch; }
.cta-block p:last-child { margin-bottom: 0; }
.cta-block .cta-fine { color: var(--ink-2); font-size: var(--step--1); margin-bottom: 0; }

.removal {
  border-top: 1px solid var(--line);
  margin-top: var(--stack); padding-block: 2rem 3.5rem;
}
.removal h2 { margin: 0 0 0.6rem; font-size: var(--step-2); }
.removal p { margin: 0 0 0.75rem; color: var(--ink-2); font-size: 0.95rem; max-width: 60ch; }
.removal p:last-child { margin-bottom: 0; }

/* Where a scan has got to, on /scan/<id>. Three steps and a marker, above the
   headline, because a scan takes hours and the page is reloaded by someone who
   wants that one fact. `.past` and `.now` never carry the state alone: the
   heading under this says the same thing in words, so a printed page, a screen
   reader and a reader who cannot tell the two greys apart all still get it. */

.track {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem;
  list-style: none; padding: 0 0 1.5rem; margin: 0 0 1.75rem;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--step--2);
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-3);
}
.track li { display: flex; align-items: center; gap: 0.5rem; }
.track li::before {
  content: ""; flex: none;
  width: 0.55rem; height: 0.55rem; border-radius: var(--r-2);
  border: 1px solid var(--line-2); background: var(--surface);
}
.track li.past { color: var(--ink-2); }
.track li.past::before { background: var(--live); border-color: var(--live); }
.track li.now { color: var(--ink); font-weight: 700; }
.track li.now::before { background: var(--accent); border-color: var(--accent); }

/* The dead-link table on the clean and gated pages. Those two carry no report
   body, so they do not get the report's own stylesheet and the one table they
   now show has to be styled here.

   The URLs are deliberately not anchors: a page whose whole subject is that
   these links are dead has no business asking anyone to click one, and several
   of them are domains that lapsed and may now belong to somebody else. Text in
   a mono face, breakable, and that is all. */

.tablewrap { overflow-x: auto; margin: 1.25rem 0; }

.deadlinks {
  width: 100%; border-collapse: collapse;
  font-size: var(--step--1);
}
.deadlinks th, .deadlinks td {
  text-align: left; padding: 0.55rem 0.75rem 0.55rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.deadlinks th {
  font-family: var(--mono); font-size: var(--step--2); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
  border-bottom-color: var(--line-2); white-space: nowrap;
}
.deadlinks td.url {
  font-family: var(--mono); color: var(--ink);
  /* A description link can be 200 characters of tracking parameters, and this
     table sits inside a `narrow` wrap. Breaking anywhere beats a row that
     pushes the page sideways. */
  overflow-wrap: anywhere; max-width: 34ch;
}
.deadlinks td.dim { color: var(--ink-2); }
.deadlinks td.num, .deadlinks th.num {
  text-align: right; padding-right: 0;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.deadlinks tr:last-child th, .deadlinks tr:last-child td { border-bottom: none; }

/* Touch. Keyed on the pointer rather than on the width, because the case is a
   1024px tablet as much as a phone: nothing here is small enough to miss with a
   mouse, and a 0.95rem link in a row of them is with a thumb. Padding rather
   than a font size, so the same page is the same page. */

@media (pointer: coarse) {
  .site-nav .nav-link, .site-nav .linkish { padding-block: 0.4rem; }
  .foot-cols li a { display: inline-block; padding-block: 0.2rem; }
}

/* Motion. One staggered entrance on the hero and the single sweep above; the
   site has no script, so there is nothing that reveals on scroll and nothing
   that can be left half-animated by a slow connection. */

@media (prefers-reduced-motion: no-preference) {
  /* Short on purpose: `backwards` holds the hero at opacity 0 until its turn
     comes, so the whole sequence has to be over before it is the thing keeping
     the largest text on the page from being painted. */
  .rise { animation: rise 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) backwards; }
  .rise-2 { animation-delay: 0.05s; }
  .rise-3 { animation-delay: 0.1s; }
  .rise-4 { animation-delay: 0.15s; }
}
@keyframes rise { from { opacity: 0; transform: translateY(0.6rem); } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
