/* ===========================================================================
   ARL Scanner — the one stylesheet.
   No framework, no build step, no client-side JavaScript anywhere on the site.

   Palette discipline: paper and ink are neutral warm greys. Exactly one accent
   hue (oxide red) is used, and only for two things — links, and severity.
   Everything else is type, hairlines and whitespace.
   =========================================================================== */

:root {
  /* =========================================================================
     THE ONLY PLACE COLOUR AND SPACING ARE DECIDED.

     Two families, and they do not mix:

       NEUTRALS AND THE ACCENT are cool. The accent is a desaturated cyan and it
       is used for exactly two things — links, and the one primary action on a
       page. Nothing else.

       SEVERITY IS WARM, AND WARM IS ONLY SEVERITY. Red for high, amber for
       medium, a muted grey-blue for informational, a distinct neutral for
       could-not-determine. No warm value appears anywhere in this stylesheet
       outside a `--sev-*` token, and a test parses this file and fails the build
       if one does.

     Why that rule exists: the accent used to be an oxide red, one hue away from
     the colour marking a high-severity finding. On a tool whose whole job is
     signalling how serious something is, a brand colour that resembles the
     danger colour makes the most important signal in a report read as
     decoration. The accent moved rather than the severity colours, because the
     severity colours are the ones a reader has to be able to trust.
     ========================================================================= */

  /* ------------------------------------------------------------- neutrals */
  --paper:      #fbfbfc;
  --surface:    #ffffff;
  --ink:        #14171a;
  --ink-2:      #474d55;
  /* Small grey type is where a palette usually fails contrast, and most of this
     design depends on it. 6.0:1 on --paper at 12.5px. */
  --ink-3:      #61686f;
  --rule:       #e3e5e9;
  --rule-2:     #c7ccd3;
  --wash:       #f2f4f6;

  /* --------------------------------------------------- the accent, cool only */
  --accent:     #0d6a7c;
  --accent-mid: #4f97a5;
  --accent-pale:#e6f1f4;

  /* ------------------------------------------------------------- severity */
  /* High: solid red fill. Also the darkest of the four in greyscale, which is
     how severity survives being printed or read by somebody colourblind. */
  --sev-high:      #a2231b;
  --sev-high-bg:   #a2231b;
  --sev-high-ink:  #ffffff;
  /* Medium: amber. Text is darkened well past the fill it sits on — an amber
     light enough to read as amber is never dark enough to read as text. */
  --sev-medium:     #7c5200;
  --sev-medium-bg:  #fdf1da;
  --sev-medium-ink: #6a4600;
  /* Informational: muted grey-blue, deliberately quiet. */
  --sev-low:      #4c5c6b;
  --sev-low-bg:   #eef1f4;
  --sev-low-ink:  #37444f;
  /* Could-not-determine: a neutral of its own, never a shade of low. It is not
     a mild finding, it is an unanswered question, and the two must not look
     related. Rendered with a dashed border everywhere it appears. */
  --sev-undet:      #5c6166;
  --sev-undet-bg:   #ffffff;
  --sev-undet-ink:  #43484d;

  /* ------------------------------------------------------------- type */
  --serif: Georgia, "Iowan Old Style", "Source Serif Pro", "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* ------------------------------------------------------------- spacing */
  /* One scale, used strictly. Nothing sets a margin that is not one of these. */
  --s1: 4px;
  --s2: 8px;
  --s3: 14px;
  --s4: 22px;
  --s5: 34px;
  --s6: 56px;
  --s7: 88px;
  --s8: 128px;
}

/* The dark scheme. Global now: every page carries the same chrome, so a reader
   who has asked their machine for dark does not get it on the pricing page and
   a white sheet on the report.

   Print is forced back to light further down this file. A report is evidence
   that gets printed and sent, and dark ink on dark paper is not a document. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #0f1114;
    --surface:    #15181c;
    --ink:        #eceef1;
    --ink-2:      #b2b9c1;
    --ink-3:      #939aa2;
    --rule:       #23262b;
    --rule-2:     #373c43;
    --wash:       #1a1d22;

    --accent:     #5cc2d6;
    --accent-mid: #3d8394;
    --accent-pale:#132a30;

    /* Severity, lifted for a dark ground. The same four relationships: high is
       a solid fill, medium is amber, low is grey-blue, undetermined is its own
       neutral behind a dashed border.

       HIGH INVERTS HERE, and that is deliberate. In light mode it is the only
       dark fill among pale ones; on a dark ground a dark red fill sits within
       0.03 of the amber one in greyscale, which means a monochrome printout or a
       reader who cannot separate red from amber loses the distinction that
       matters most. So on dark it becomes the only BRIGHT fill among dark ones.
       Both schemes say the same thing — high is the chip furthest from its
       surroundings — and a test measures it rather than trusting the eye. */
    --sev-high:      #ff7a6a;
    --sev-high-bg:   #ff8271;
    --sev-high-ink:  #3a0b06;
    --sev-medium:     #e6b350;
    --sev-medium-bg:  #33270e;
    --sev-medium-ink: #f2d79a;
    --sev-low:      #93a6b6;
    --sev-low-bg:   #1c2228;
    --sev-low-ink:  #c4d0da;
    --sev-undet:      #9aa1a8;
    --sev-undet-bg:   #15181c;
    --sev-undet-ink:  #c9ced4;
  }
}

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.65 var(--sans);
  font-feature-settings: "kern" 1;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a { color: var(--accent); text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

/* --------------------------------------------------------------- typography */

h1, h2, h3, h4 { font-family: var(--mono); font-weight: 500; letter-spacing: -0.01em; }
h1 { font-size: 31px; line-height: 1.2; margin: 0 0 10px; }
h2 { font-size: 21px; line-height: 1.3; margin: 44px 0 12px; }
h3 { font-size: 17px; line-height: 1.35; margin: 26px 0 8px; }
h4 { font-size: 15px; margin: 20px 0 6px; }
p  { margin: 0 0 14px; }
ul, ol { margin: 0 0 14px; padding-left: 22px; }
li { margin: 0 0 7px; }
strong { font-weight: 650; }

.eyebrow {
  font: 600 11.5px/1.4 var(--sans);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 10px;
}
.lede { font-size: 18px; line-height: 1.6; color: var(--ink-2); margin: 0 0 26px; max-width: 62ch; }
.muted { color: var(--ink-3); }
.small { font-size: 13.5px; line-height: 1.6; }
.hint { color: var(--ink-3); font-size: 13.5px; line-height: 1.6; margin: 6px 0 0; }
code, kbd { font-family: var(--mono); font-size: 0.86em; background: var(--wash);
  padding: 1px 5px; border-radius: 3px; border: 1px solid var(--rule); }

/* Long-form pages hold a generous measure. The BODY FACE is the technical sans
   everywhere except inside a rendered report — see `.look-report .prose` at the
   foot of this file, which is the one typeface difference on the site and the
   only place a serif appears. */
.prose { max-width: 68ch; }
.prose p, .prose li { font-size: 16.5px; line-height: 1.72; }
.prose .hint, .prose .small { font-family: var(--sans); }
.prose code { font-family: var(--mono); }
.prose h2 { margin-top: var(--s5); }
.prose h2::before {
  content: ""; display: block; width: 46px; height: 2px;
  background: var(--rule-2); margin: 0 0 var(--s3);
}

/* ------------------------------------------------------------------- shell */

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--ink); color: #fff;
  padding: 10px 16px; z-index: 10;
}
.skip:focus { left: 0; }

/* Visible to a screen reader, not to the eye. Used where a control's purpose is
   obvious from its placeholder and a printed label would be noise — the scan
   input on the home page — and nowhere else. An input with no label at all is
   an input a screen reader announces as "edit text". */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

.site-header { border-bottom: 1px solid var(--rule-2); background: var(--surface); }
.site-header .bar {
  max-width: 1060px; margin: 0 auto; padding: 14px 26px;
  display: flex; align-items: baseline; gap: 28px; flex-wrap: wrap;
}
.mark { text-decoration: none; color: var(--ink); display: block; }

/* The masthead. Letterforms only — no icon, no image, no gradient. `ARL` in the
   heavy serif, a hairline, then `Scanner` in the regular weight, the way a
   paper sets its own name. scripts/make-icons.ts renders the same letterforms
   to the favicon, so the tab and the header cannot drift apart. */
.wordmark { display: block; font-family: var(--serif); font-size: 25px; line-height: 1.05; }
.wordmark-a { font-weight: 700; letter-spacing: 0.045em; }
.wordmark-b {
  font-weight: 400; margin-left: 9px; padding-left: 11px;
  border-left: 1px solid var(--rule-2); letter-spacing: -0.005em;
}
.mark-sub { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 5px; letter-spacing: 0.01em; }
.site-header nav { margin-left: auto; display: flex; gap: 22px; flex-wrap: wrap; }
.site-header nav a {
  font-size: 14px; color: var(--ink-2); text-decoration: none;
  padding-bottom: 3px; border-bottom: 2px solid transparent;
}
.site-header nav a:hover { color: var(--ink); border-bottom-color: var(--rule-2); }
.site-header nav a.on { color: var(--ink); border-bottom-color: var(--accent); font-weight: 600; }

/* `width: 100%` is load-bearing, not decoration. <body> is a column flex
   container (that is what pins the footer to the bottom), and a stretched flex
   item is sized to at least its own min-content width — so one evidence crop
   carrying a fixed pixel width would drag <main> wider than the viewport and
   the whole document would scroll sideways on a phone. An explicit width takes
   the item out of content-based cross sizing; `min-width: 0` lets it shrink. */
main { flex: 1 0 auto; width: 100%; min-width: 0; }
.wrap { max-width: 1010px; margin: 0 auto; padding: 34px 26px 80px; }
.wrap.narrow { max-width: 860px; }

/* Body copy holds a readable measure even where the page itself is wide for
   the sake of tables and evidence crops. Panels, notes and tables are exempt:
   they are visually contained already, and so are the lists that are really
   layout grids rather than prose. */
main > p, main > ul, main > ol, main > dl { max-width: 84ch; }
main > .steps, main > .stack, main > .faq { max-width: none; }

.site-footer {
  flex-shrink: 0; border-top: 1px solid var(--rule-2); background: var(--surface);
  margin-top: 40px;
}
.site-footer .wrap { padding-top: 26px; padding-bottom: 34px; }
.site-footer .seed {
  font-size: 12.5px; line-height: 1.6; color: var(--ink-3); margin: 0; max-width: 78ch;
}

/* Who maintains this is a different question from what the terms say, so the
   footer separates them rather than running everything into one row. */
.footer-cols {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 24px 34px; margin: 0 0 24px;
}
.footer-heading {
  font: 600 11px/1.4 var(--sans); letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 9px;
}
.footer-group ul { list-style: none; margin: 0; padding: 0; }
.footer-group li { margin: 0 0 6px; }
.footer-group a { font-size: 14px; }
.footer-group p { margin: 0; }

/* ---------------------------------------------------------------- disclaimer */

.banner {
  border: 1px solid var(--rule-2); border-left: 4px solid var(--ink);
  background: var(--surface); padding: 15px 18px; margin: 0 0 30px;
  font-size: 13.5px; line-height: 1.6; color: var(--ink-2);
}
.banner b { display: block; color: var(--ink); font-size: 12px; letter-spacing: 0.11em;
  text-transform: uppercase; margin-bottom: 5px; font-weight: 600; }
.banner a { color: var(--accent); }

/* --------------------------------------------------------------- containers */

.panel {
  background: var(--surface); border: 1px solid var(--rule); padding: 24px 26px; margin: 0 0 22px;
}
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }

.note {
  border: 1px solid var(--rule-2); border-left: 4px solid var(--accent-mid);
  background: var(--surface); padding: 14px 18px; margin: 0 0 20px; font-size: 14px; line-height: 1.6;
}
.note b { display: block; margin-bottom: 4px; }
.note ul { margin: 8px 0 0; }

.rule-line { border: 0; border-top: 1px solid var(--rule); margin: 34px 0; }

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

label { display: block; font: 600 13.5px/1.5 var(--sans); margin: 0 0 6px; }
/*
 * FORM CONTROLS. No native chrome anywhere.
 *
 * `appearance: none` on everything that takes it. A control left to the platform
 * is drawn in the operating system's own idiom — a beveled select on Windows, a
 * rounded pill on macOS, a different one again on Android — which means the page
 * cannot look like one design system on any two machines. Checkboxes and radios
 * are the deliberate exception: a custom checkbox has to reimplement the
 * indeterminate state, the focus ring and the hit target, and every
 * reimplementation that stops short of all three is worse than the native
 * control it replaced.
 */
input, textarea, select, button {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  font: inherit; color: inherit;
}
input[type=checkbox], input[type=radio] {
  appearance: auto; -webkit-appearance: auto; -moz-appearance: auto;
  accent-color: var(--accent);
}
input[type=url], input[type=text], input[type=number], input[type=email], textarea, select {
  width: 100%; padding: 11px 13px; border: 1px solid var(--rule-2); background: var(--surface);
  color: var(--ink); font: 15px/1.5 var(--mono); border-radius: 2px;
}
/* Chromium and Firefox draw their own increment arrows on a number input. They
   are the beveled system chrome this rule exists to remove, and the preset
   buttons beside the field do the same job better. */
input[type=number] { -moz-appearance: textfield; }
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
select {
  /* No native arrow, so one is drawn as a background chevron. */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 36px;
}
textarea { font-family: var(--mono); font-size: 13px; resize: vertical; }
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
input[type=file] { font-size: 13.5px; border: 0; padding: 0; width: auto; }

button {
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink); border-radius: 2px;
  padding: 11px 22px; font: 500 15px/1.2 var(--mono); cursor: pointer;
}
button:hover { filter: brightness(1.25); }
button.secondary { background: var(--surface); color: var(--ink); border-color: var(--rule-2); }
button.secondary:hover { background: var(--wash); filter: none; }
button[disabled] { opacity: 0.6; cursor: default; filter: none; }

.row { display: flex; gap: 10px; align-items: stretch; }
.row input { flex: 1; }
.checkline { display: flex; gap: 9px; align-items: flex-start; font-weight: 400; font-size: 14px; margin: 12px 0 0; }
.checkline input { width: auto; margin-top: 3px; flex: none; }

fieldset { border: 1px solid var(--rule); padding: 18px 20px; margin: 0 0 18px; }
legend { font: 600 13.5px/1.4 var(--sans); padding: 0 8px; }

.state-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
  gap: 2px 18px; margin: 12px 0 0;
}
.state-grid label { font-weight: 400; font-size: 14px; display: flex; gap: 8px; align-items: baseline; margin: 0; padding: 4px 0; }
.state-grid input { width: auto; }
.scope-all {
  display: flex; gap: 9px; align-items: baseline; font-weight: 600; font-size: 14.5px;
  padding: 0 0 12px; border-bottom: 1px solid var(--rule); margin: 0;
}
.scope-all input { width: auto; }

/* ------------------------------------------------------------------- chips */

.chip {
  display: inline-block; font: 600 10.5px/1.5 var(--sans); letter-spacing: 0.1em;
  text-transform: uppercase; padding: 2px 8px; border-radius: 2px; vertical-align: middle;
  white-space: nowrap;
}
/*
 * Severity, and nothing else on this site, uses a warm colour.
 *
 * Every chip also carries its own word (the markup renders the severity as text)
 * and a leading glyph, and the four differ in fill lightness as well as hue. A
 * reader who cannot distinguish red from amber, or who is holding a monochrome
 * printout, still has three independent ways to tell them apart. Colour is the
 * fastest carrier here and never the only one.
 */
.chip.high    { background: var(--sev-high-bg); color: var(--sev-high-ink); border: 1px solid var(--sev-high); }
.chip.medium  { background: var(--sev-medium-bg); color: var(--sev-medium-ink); border: 1px solid var(--sev-medium); }
.chip.low     { background: var(--sev-low-bg); color: var(--sev-low-ink); border: 1px solid var(--sev-low); }
.chip.manual  { background: var(--sev-undet-bg); color: var(--sev-undet-ink); border: 1px dashed var(--sev-undet); }
.chip.none    { background: var(--wash); color: var(--ink-2); border: 1px solid var(--rule-2); }
.chip::before { font-weight: 700; margin-right: 5px; }
.chip.high::before   { content: "\25B2"; }  /* filled triangle */
.chip.medium::before { content: "\25CF"; }  /* filled circle */
.chip.low::before    { content: "\25CB"; }  /* hollow circle */
.chip.manual::before { content: "?"; }
.chip.pending::before, .chip.none::before, .chip.overdue::before,
.chip.health-issue::before, .chip.health-clear::before,
.chip.health-undetermined::before { content: none; margin-right: 0; }
/* --ink-2 rather than --ink-3: chip text is 10.5px, and small type needs the
   darker value to clear 4.5:1 against the surface behind it. */
.chip.pending { background: var(--surface); color: var(--ink-2); border: 1px dashed var(--rule-2); }
/* A stale rule summary. Marked, never hidden — being visibly overdue is more
   use to a reader than looking current. */
.chip.overdue {
  background: var(--sev-medium-bg); color: var(--sev-medium-ink); border: 1px solid var(--sev-medium);
}

/* Checkout-health status chips. A separate vocabulary from the statute-related
   severity chips on purpose: these describe the checkout as a mechanism, and
   sharing the high/medium/low look would invite reading one as the other. */
.chip.health-issue        { background: var(--ink); color: var(--paper, #fff); border: 1px solid var(--ink); }
.chip.health-clear        { background: var(--wash); color: var(--ink-2); border: 1px solid var(--rule-2); }
.chip.health-undetermined { background: var(--surface); color: var(--ink-2); border: 1px dashed var(--rule-2); }

/* ----------------------------------------------------------------- pricing */

.plans-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.plans-row .panel { margin: 0; }
.price-line { font-size: 26px; margin: 0 0 14px; }
.btn-link {
  display: inline-block; background: var(--ink); color: var(--paper, #fff); font-weight: 600;
  padding: 10px 18px; border-radius: 3px; text-decoration: none;
}
.btn-link:hover { background: var(--accent); color: #fff; }
.not-yet { text-transform: uppercase; font-size: 11px; letter-spacing: 0.08em; }

/* The quantity calculator.
 *
 * A number field somebody can type into, and presets beside it for the round
 * numbers. Typing 13 has to be as easy as reaching for 10, which rules out a
 * dropdown: a select makes every quantity a scroll and 13 a scroll to the
 * thirteenth item. Both controls write the same query parameter, and with
 * JavaScript off both still work — the presets are links and the field has a
 * submit button. */
.calc { margin: 0 0 var(--s4); }
.calc label { display: block; margin: 0 0 var(--s2); font-family: var(--mono); font-size: 13.5px; color: var(--ink-2); }
.calc-entry { display: flex; gap: var(--s2); align-items: stretch; max-width: 340px; }
.calc-entry input[type=number] {
  flex: 1 1 auto; min-width: 0; font-size: 18px; text-align: center; letter-spacing: 0.04em;
}
/* Secondary, deliberately. There is one filled action per page and on this page
   it is Subscribe; a heavier "Price it" would compete with it for the same
   attention, and with the script running this button is never even needed. */
.calc-go {
  white-space: nowrap; background: var(--surface); color: var(--ink);
  border-color: var(--rule-2); font-size: 14px; padding: 11px var(--s3);
}
.calc-go:hover { background: var(--wash); filter: none; }
.calc-presets {
  display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; margin: var(--s3) 0 0;
}
.calc-presets-label { font: 13px/1 var(--mono); color: var(--ink-3); }
.calc-preset {
  display: inline-block; min-width: 40px; text-align: center; text-decoration: none;
  font: 14px/1 var(--mono); padding: 9px 10px; border: 1px solid var(--rule-2);
  border-radius: 2px; color: var(--ink-2); background: var(--surface);
}
.calc-preset:hover { border-color: var(--accent); color: var(--accent); }
.calc-preset.on {
  border-color: var(--accent); color: var(--accent); background: var(--accent-pale); font-weight: 600;
}
.calc .price-line { margin: var(--s4) 0 0; line-height: 1.3; display: grid; gap: var(--s1); }
.calc .price-line .small { font-size: 14px; }
/* The marginal rate. The most useful line in the block, so it is the one that is
   not muted — an average says what somebody pays, this says what a decision
   costs. Accent-coloured, which is allowed: it is the primary action's colour and
   this is a statement about buying, not about severity. */
.calc-next {
  font: 500 15px/1.4 var(--mono); color: var(--accent); margin-top: var(--s1);
}
.calc-carry { font-size: 13.5px; color: var(--ink-2); margin: var(--s2) 0 0; line-height: 1.6; }

/* ------------------------------------------------- the free/paid comparison */

/* A real table, so a screen reader reads a cell with both its row and its column.
 * The paid column is emphasised with weight and a hairline and nothing else: the
 * accent marks the one primary action on a page, warm colour belongs to severity,
 * and a comparison table is not an alarm. */
.cmp { width: 100%; margin: 0 0 var(--s3); font-size: 14.5px; }
.cmp caption {
  text-align: left; font-size: 13px; color: var(--ink-3); line-height: 1.6;
  padding: 0 0 var(--s3); max-width: 68ch;
}
.cmp caption em { font-style: normal; font-family: var(--mono); font-size: 12.5px; }
.cmp thead th {
  font: 500 12px/1.4 var(--mono); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-2); border-bottom: 1px solid var(--rule-2); padding: 0 var(--s3) var(--s2) 0;
}
.cmp .cmp-corner { border-bottom: 1px solid var(--rule-2); }
.cmp tbody th[scope="row"] {
  text-align: left; font-weight: 600; color: var(--ink); width: 30%;
  padding: var(--s3) var(--s3) var(--s3) 0; border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
.cmp tbody td {
  padding: var(--s3) var(--s3) var(--s3) 0; border-bottom: 1px solid var(--rule);
  color: var(--ink-2); vertical-align: top;
}
/* The emphasis on the paid column: a hairline down its left edge and a heavier
   ink, carried by the header cell too so the column reads as one thing. */
.cmp .cmp-paid {
  border-left: 1px solid var(--rule-2); padding-left: var(--s3);
  color: var(--ink); font-weight: 500;
}
.cmp .cmp-none { color: var(--ink-3); font-family: var(--mono); }
/* "same either way" — a statement that paying withdraws nothing, which is the
   point of printing those rows at all rather than leaving them out. */
.cmp-flag {
  display: block; font: 400 11.5px/1.5 var(--mono); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 400; margin-top: 2px;
}

/* Narrow screens: the table stacks. Each row becomes its own block and each cell
   carries its column name, so nothing scrolls sideways and no value is left
   without a label. `data-label` is written by the server, so this works with no
   JavaScript — and the markup stays a table, which is what the accessibility
   tree needs. */
@media (max-width: 620px) {
  .cmp, .cmp thead, .cmp tbody, .cmp tr, .cmp th, .cmp td { display: block; width: auto; }
  .cmp thead { display: none; }
  .cmp caption { display: block; }
  .cmp tbody tr {
    border-bottom: 1px solid var(--rule-2); padding: 0 0 var(--s3); margin: 0 0 var(--s3);
  }
  .cmp tbody tr:last-child { border-bottom: 0; }
  .cmp tbody th[scope="row"] {
    width: auto; border-bottom: 0; padding: 0 0 var(--s2);
    font-family: var(--mono); font-size: 14px;
  }
  .cmp tbody td {
    border-bottom: 0; padding: 0 0 var(--s1) var(--s3);
    border-left: 1px solid var(--rule); margin: 0 0 var(--s1);
  }
  .cmp tbody td::before {
    content: attr(data-label) " — ";
    font: 500 11.5px/1.5 var(--mono); letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); display: block;
  }
  .cmp .cmp-paid { border-left: 2px solid var(--rule-2); padding-left: var(--s3); }
  .cmp-flag { display: inline; margin: 0 0 0 var(--s2); }
}

/* The band table. Two narrow columns of numbers, so it does not want the full
 * width the generic table rule gives it. */
table.bands { font-size: 14px; margin: 0 0 16px; }
table.bands caption { text-align: left; font-size: 12.5px; color: var(--ink-3); padding: 0 0 8px; line-height: 1.55; }
table.bands td, table.bands th { padding: 7px 12px 7px 0; }

.chiprow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 0 0 14px; }

/* ---------------------------------------------------------------- findings */

.findings { counter-reset: finding; }

.finding {
  background: var(--surface); border: 1px solid var(--rule); border-left: 4px solid var(--rule-2);
  padding: 20px 24px; margin: 0 0 16px;
}
.finding.high    { border-left-color: var(--sev-high); }
.finding.medium  { border-left-color: var(--sev-medium); }
.finding.low     { border-left-color: var(--sev-low); }
.finding.manual  { border-left-style: dashed; }
.finding h3 { margin: 10px 0 10px; font-size: 18px; line-height: 1.35; }
.finding h3 a { color: var(--ink); text-decoration: none; }
.finding h3 a:hover { color: var(--accent); text-decoration: underline; }
.finding > :last-child { margin-bottom: 0; }

.finding-no {
  font: 600 11.5px/1.4 var(--sans); letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-3);
}

/* The states a finding relates to, kept visible on the collapsed card so the
 * three things a reader needs — severity, what it is, who it relates to — are
 * all readable without opening anything. */
.finding-states { margin: 0 0 10px; }

/* Evidence disclosure. No animation: the stylesheet has none anywhere, which is
 * how prefers-reduced-motion is honoured. <details> needs no JavaScript, so the
 * headline above it reads with scripting switched off. */
.finding .evidence-toggle { border-top: 1px solid var(--rule); padding: 10px 0 0; margin-top: 4px; }
.finding .evidence-toggle > summary { font-size: 13.5px; }
.finding .evidence-body > :first-child { margin-top: 14px; }
.finding .evidence-body > :last-child { margin-bottom: 0; }

/* --------------------------------------------------------- report summary */

.summary .summary-counts {
  font: 600 15px/1.5 var(--sans); margin: 0 0 14px; color: var(--ink);
}
.summary-list { margin: 0 0 4px; padding-left: 0; list-style: none; }
.summary-list li {
  display: flex; gap: 10px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid var(--rule);
}
.summary-list li:first-child { border-top: 0; }
.summary-list a { color: var(--ink); }
.summary-undetermined { margin-top: 18px; padding-top: 4px; border-top: 1px solid var(--rule); }
.summary-undetermined h3 { font-size: 15px; margin: 14px 0 6px; }

/* The audit-document metadata block: label / value pairs on hairlines. */
.meta { margin: 12px 0 0; font-size: 13.5px; }
/* Direct children only. `.meta div` would also catch the `.ref` blocks nested
   inside a `dd`, turn each citation into a flex container, and let its parts
   collapse to one character per line when a long URL sits beside them. */
.meta > div { display: flex; gap: 14px; padding: 7px 0; border-top: 1px solid var(--rule); }
.meta dt, .meta .k {
  flex: 0 0 148px; color: var(--ink-3); font-weight: 600; font-size: 12px;
  letter-spacing: 0.06em; text-transform: uppercase; padding-top: 1px;
}
.meta dd, .meta .v { margin: 0; flex: 1; min-width: 0; }
.statute { font-family: var(--serif); font-style: italic; }

/* One statute a finding relates to. A finding commonly relates to several, so
   these stack rather than running together on one line. */
.ref { padding: 0 0 8px; }
.ref + .ref { padding-top: 8px; border-top: 1px dotted var(--rule); }
.ref:last-child { padding-bottom: 0; }
.ref .capt { margin-top: 2px; }

.observed {
  font-family: var(--serif); font-size: 16px; line-height: 1.65; margin: 0 0 12px;
}
.requirement {
  border-left: 2px solid var(--rule-2); padding: 2px 0 2px 16px; margin: 16px 0;
  font-family: var(--serif); font-size: 15.5px; line-height: 1.65; color: var(--ink-2);
}
ul.det { margin: 12px 0 0; padding-left: 20px; font-size: 14.5px; }

/* ------------------------------------------------------------------- tables */

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th, td { text-align: left; padding: 9px 12px 9px 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
thead th {
  font: 600 11.5px/1.4 var(--sans); letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-3); border-bottom: 1px solid var(--rule-2);
}
table.sig th { font-weight: 600; color: var(--ink-2); width: 220px; font-family: var(--mono); font-size: 12.5px; }
table.sig td code { background: none; border: 0; padding: 0; }
.scroll { overflow-x: auto; }
.capt { font-size: 12.5px; color: var(--ink-3); margin: 6px 0 0; line-height: 1.55; }

/* --------------------------------------------------------------- evidence */

.crop { border: 1px solid var(--rule-2); overflow: hidden; margin: 14px 0 0; background: var(--wash); }
.crop .inner { transform-origin: top left; overflow: hidden; }
.crop img { display: block; max-width: none; }

.film { display: grid; grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); gap: 18px; }
.film figure { margin: 0; }
.film img {
  width: 100%; height: 200px; object-fit: cover; object-position: top;
  border: 1px solid var(--rule-2); display: block; background: var(--surface);
}
.film figcaption { font-size: 12.5px; color: var(--ink-3); margin: 7px 0 0; word-break: break-word; line-height: 1.5; }

/* -------------------------------------------------------------- disclosure */

details { border-top: 1px solid var(--rule); padding: 12px 0; }
details summary {
  cursor: pointer; font: 600 14.5px/1.5 var(--sans); list-style: none;
  display: flex; gap: 10px; align-items: baseline;
}
details summary::-webkit-details-marker { display: none; }
details summary::before { content: "+"; color: var(--accent); font-weight: 700; font-family: var(--mono); }
details[open] summary::before { content: "\2212"; }
details > :not(summary) { margin-top: 14px; }

/* ------------------------------------------------------------------- lists */

.stack { list-style: none; padding: 0; margin: 0; }
.stack > li { padding: 14px 0; border-top: 1px solid var(--rule); margin: 0; }
.stack > li:last-child { border-bottom: 1px solid var(--rule); }

.steps { list-style: none; padding: 0; margin: 0 0 14px; counter-reset: step;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 28px; }
.steps li { counter-increment: step; margin: 0; border-top: 2px solid var(--ink); padding-top: 14px; }
.steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block; font: 600 12px/1 var(--mono); color: var(--accent); margin-bottom: 8px;
  letter-spacing: 0.08em;
}
.steps h3 { margin: 0 0 6px; font-size: 16px; }
.steps p { font-size: 14px; line-height: 1.6; color: var(--ink-2); margin: 0; }

.faq dt { font-family: var(--serif); font-size: 17.5px; font-weight: 600; margin: 34px 0 8px; }
.faq dd { margin: 0; max-width: 68ch; }
.faq dd p { font-family: var(--serif); font-size: 16.5px; line-height: 1.7; }

.kv { display: grid; grid-template-columns: max-content 1fr; gap: 10px 22px; font-size: 14px; margin: 0 0 22px; }
.kv dt { color: var(--ink-3); font-weight: 600; font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; padding-top: 2px; }
.kv dd { margin: 0; }

.tag { font-family: var(--mono); font-size: 12px; color: var(--ink-3); }
/* Newly observed since last week is a severity signal, so it is allowed the
   warm colour. Fewer findings is not, and stays neutral. */
.delta-up   { color: var(--sev-medium); font-weight: 600; }
.delta-down { color: var(--ink-2); font-weight: 600; }
.delta-same { color: var(--ink-3); }

/* --------------------------------------------------- provenance and review */

/* "Rule summary last reviewed: DATE", under every check on /checks and on
   every state page. */
.prov { margin: 8px 0 0; padding: 8px 0 0; border-top: 1px dotted var(--rule); }
.prov-date { font-size: 12.5px; color: var(--ink-2); }
.prov .chip { margin-left: 8px; }
.prov-page {
  border: 1px solid var(--rule); border-left: 3px solid var(--rule-2);
  background: var(--surface); padding: 12px 16px; margin: 0 0 22px;
}
.prov-page .prov-date { font-size: 14px; }

/* An identity field nobody has filled in. Shown in the position the value
   would occupy, marked, never substituted with something plausible. */
.placeholder {
  font-family: var(--mono); font-size: 0.9em; color: var(--accent);
  background: var(--accent-pale); border: 1px dashed var(--accent-mid);
  padding: 1px 6px; border-radius: 2px; white-space: nowrap;
}

/* ------------------------------------------------------------- changelog */

.release { margin: 0 0 10px; }
.release h2 { margin-top: 40px; }
.release-versions {
  font-size: 13px; color: var(--ink-3); margin: -6px 0 14px;
  padding-bottom: 12px; border-bottom: 1px solid var(--rule);
}
.release .prose h3 { margin-top: 24px; }

/* ------------------------------------------------------------ methodology */

.signal {
  border: 1px solid var(--rule); border-left: 3px solid var(--rule-2);
  background: var(--surface); padding: 18px 22px; margin: 0 0 16px;
}
.signal h3 { margin: 0 0 6px; font-family: var(--mono); font-size: 15px; overflow-wrap: anywhere; }
.signal h3 code { background: none; border: 0; padding: 0; font-size: 1em; overflow-wrap: anywhere; }
.signal .meta div:first-child { border-top: 0; padding-top: 0; }
.group-head {
  font-size: 15px; text-transform: uppercase; letter-spacing: 0.1em;
  font-family: var(--sans); color: var(--ink-3); margin: 36px 0 14px;
  padding-bottom: 8px; border-bottom: 2px solid var(--ink);
}
ul.tight { margin: 0; padding-left: 18px; }
ul.tight li { margin: 0 0 5px; }

/* ------------------------------------------------------------- progress */

.stages { list-style: none; padding: 0; margin: 0 0 14px; }
.stages li {
  display: flex; gap: 12px; align-items: baseline; padding: 7px 0;
  border-bottom: 1px solid var(--rule); margin: 0; font-size: 14px;
}
.stage-mark { font-family: var(--mono); width: 14px; flex: none; text-align: center; }
.stages li.done { color: var(--ink-2); }
.stages li.done .stage-mark { color: var(--accent); }
.stages li.now { font-weight: 650; color: var(--ink); }
.stages li.now .stage-mark { color: var(--accent); }
.stages li.pending { color: var(--ink-3); }

.events { list-style: none; padding: 0; margin: 0; counter-reset: ev; }
.events li {
  display: grid; grid-template-columns: 74px 210px 1fr; gap: 14px;
  padding: 8px 0; border-top: 1px solid var(--rule); margin: 0; font-size: 13.5px;
}
.event-time { font-family: var(--mono); font-size: 12.5px; color: var(--ink-3); }
.event-phase { color: var(--ink-2); font-weight: 600; font-size: 12.5px; }
.event-msg { color: var(--ink); }

/* -------------------------------------------------------- copy-link control */

.copyline { margin: 0 0 6px; }
.copyrow { display: flex; gap: 8px; align-items: stretch; }
.copyfield {
  flex: 1; min-width: 0; padding: 9px 11px; border: 1px solid var(--rule-2);
  background: var(--wash); color: var(--ink); font: 13px/1.4 var(--mono);
  border-radius: 2px;
}
.copybtn { flex: none; padding: 9px 16px; font-size: 13.5px; }

/* -------------------------------------------------------------- utilities */

/* Real content for a screen reader, absent for everyone else. Used where a
   heading is needed for the document outline but would add visual noise. */
.visually-hidden, .sr-heading {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* URLs and ids, which have no spaces to wrap at.
   `anywhere` rather than `break-word`: only `anywhere` lowers the element's
   min-content width, and it is the min-content width of an official code URL
   that otherwise forces a metadata grid wider than a phone screen.
   `overflow-wrap` INHERITS, so this is aimed at the links and code spans that
   actually carry an unbreakable string rather than at their containers —
   putting it on a container lets every word inside break, which collapses a
   citation to one letter per line. */
.brk, code, .kv dd a, .capt a, .meta a[href], .prov a, .footer-group a {
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------- mobile */

/* The report is the page most likely to be opened on a phone — somebody sent a
   link — and it is the page with the widest content. Tables and evidence crops
   scroll or scale inside their own boxes; the page body never scrolls
   sideways. */
@media (max-width: 720px) {
  .wrap { padding: 24px 18px 60px; }
  h1 { font-size: 26px; }
  h2 { font-size: 19px; margin-top: 34px; }
  .lede { font-size: 16.5px; }
  .prose p, .prose li { font-size: 16px; }

  .site-header .bar { padding: 12px 18px; gap: 12px; }
  .site-header nav { margin-left: 0; gap: 14px 16px; width: 100%; }
  .site-header nav a { font-size: 13.5px; }
  .wordmark { font-size: 21px; }

  /* Label above value rather than beside it: a 148px label column leaves
     nothing for the value on a 360px screen. */
  .meta div { flex-direction: column; gap: 3px; }
  .meta dt, .meta .k { flex: none; }
  .kv { grid-template-columns: 1fr; gap: 3px 0; }
  .kv dt { margin-top: 12px; }
  .kv dt:first-child { margin-top: 0; }

  .row { flex-direction: column; }
  .row input { width: 100%; }
  .row button { width: 100%; }
  .copyrow { flex-direction: column; }
  .copybtn { width: 100%; }

  .findings .finding, .finding { padding: 16px 16px; }
  .panel { padding: 18px 16px; }
  .signal { padding: 14px 14px; }
  .signal h3 { font-size: 13.5px; }

  /* An evidence crop carries an inline pixel width from the server, computed
     for a desktop measure. Cap it to the column and let the box clip rather
     than letting the page scroll sideways. */
  .crop { max-width: 100%; }
  .film { grid-template-columns: 1fr 1fr; gap: 12px; }
  .film img { height: 140px; }

  .events li { grid-template-columns: 1fr; gap: 2px; padding: 10px 0; }
  .state-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 420px) {
  .film { grid-template-columns: 1fr; }
  .state-grid { grid-template-columns: 1fr; }
}

/* Anything with a fixed inline width still cannot force the document wider. */
img, table, pre { max-width: 100%; }
body { overflow-x: hidden; }

/* ------------------------------------------------------------------- print */

.only-print { display: none; }

@page { size: letter; margin: 0.7in; }

@media print {
  /*
   * Print is forced back to the light palette regardless of the reader's colour
   * scheme. A report is evidence that gets printed and sent, and dark ink on a
   * dark ground is not a document — a browser printing a dark page either wastes
   * a cartridge on the background or drops it and leaves pale grey text on white.
   * Every token is restated rather than inherited, because :root above may have
   * been rewritten by the dark media query and @media print does not undo it.
   */
  :root {
    --paper: #fff;
    --surface: #fff;
    --ink: #111;
    --ink-2: #333;
    --ink-3: #555;
    --rule: #ddd;
    --rule-2: #aaa;
    --wash: #f4f4f4;
    --accent: #0d6a7c;
    --accent-mid: #4f97a5;
    --accent-pale: #e6f1f4;
    --sev-high: #a2231b;      --sev-high-bg: #a2231b;   --sev-high-ink: #fff;
    --sev-medium: #7c5200;    --sev-medium-bg: #fdf1da; --sev-medium-ink: #6a4600;
    --sev-low: #4c5c6b;       --sev-low-bg: #eef1f4;    --sev-low-ink: #37444f;
    --sev-undet: #5c6166;     --sev-undet-bg: #fff;     --sev-undet-ink: #43484d;
  }
  body { background: #fff; color: #111; font-size: 11pt; overflow-x: visible; }
  .no-print, .site-header nav, form, button, .film, .skip { display: none !important; }
  .only-print { display: block; }

  /* The running header. `position: fixed` inside a printed document repeats on
     every page in Chromium, so the report id and the not-legal-advice line are
     carried on every sheet — a page separated from the rest of a PDF still says
     what it is and which scan it came from. */
  .print-running {
    display: block; position: fixed; top: 0; left: 0; right: 0;
    font: 7.5pt/1.3 var(--sans); letter-spacing: 0.04em; text-transform: uppercase;
    color: #444; border-bottom: 0.5pt solid #bbb; padding-bottom: 3pt;
    background: #fff;
  }
  /* Room for the running header on every page. On <body> rather than <main>,
     because the masthead precedes <main> and would otherwise sit under it. */
  body { padding-top: 18pt; }

  /* A horizontal scroll container has nothing to scroll on paper, and clipping
     an evidence crop is the one thing a printed report must not do. */
  .scroll { overflow: visible !important; }

  .wrap { max-width: none; padding: 0; }
  .site-header { border-bottom: 1px solid #000; background: none; }
  .site-header .bar { padding: 0 0 8pt; }
  .site-footer { border-top: 1px solid #999; margin-top: 18pt; }
  .site-footer .wrap { padding: 8pt 0 0; }

  /* The disclaimer must survive printing, and must land on page one. It is the
     first block inside <main>, is never allowed to break, and is never allowed
     to be pushed onto a later page. */
  .banner {
    display: block !important; visibility: visible !important;
    break-inside: avoid; page-break-inside: avoid;
    break-before: avoid; page-break-before: avoid;
    border: 1pt solid #000; border-left: 3pt solid #000; background: none;
    margin: 0 0 14pt; padding: 8pt 10pt; font-size: 9.5pt;
  }

  h1 { font-size: 19pt; }
  h2 { font-size: 13pt; margin-top: 18pt; break-after: avoid; page-break-after: avoid; }
  h3 { font-size: 11.5pt; break-after: avoid; page-break-after: avoid; }
  .finding, .panel, .note, .crop { break-inside: avoid; page-break-inside: avoid; }
  .finding { border: 1pt solid #999; border-left: 3pt solid #000; }
  .finding.medium { border-left-width: 2pt; }
  .finding.low, .finding.manual { border-left: 1pt solid #999; }
  .chip { border: 1pt solid #000 !important; background: none !important; color: #000 !important; }
  a { color: #000; text-decoration: underline; }
  /* A printed report has to stand alone, so links resolve on paper. */
  .meta a[href^="http"]::after, .prose a[href^="http"]::after {
    content: " <" attr(href) ">"; font-size: 8pt; font-family: var(--mono); word-break: break-all;
  }
  /* Everything collapsed on screen prints open. A printed report is the archival
     copy — a reader holding it cannot click, so a closed <details> would print
     as a heading with the evidence silently missing.

     `display: block` alone is not enough in current Chromium: a closed
     <details> hides its contents through the ::details-content pseudo-element,
     which ignores the child's own display. Without the rule below the evidence
     crops are absent from the PDF entirely — verified by rendering one. The
     display rule stays as the fallback for engines without
     ::details-content. */
  details { border: 0; }
  details > :not(summary) { display: block; }
  details::details-content { content-visibility: visible !important; }
  img { max-width: 100%; }
  .crop { border: 1pt solid #999; }

  /* A finding is the unit a reader cites, so it is kept whole across a page
     boundary wherever it fits on one. Its evidence crop and its metadata block
     travel with it. */
  .finding, .signal, .prov-page, .release { break-inside: avoid; page-break-inside: avoid; }
  .finding .meta, .identity, .stack > li { break-inside: avoid; page-break-inside: avoid; }
  .signal, .release { border-left-width: 2pt; }
  ol, ul { break-inside: auto; }
  li { break-inside: avoid; page-break-inside: avoid; }
  /* Never leave a heading or an opening line alone at a page boundary. */
  p, li { orphans: 3; widows: 3; }
  .stages, .events, .copyline { display: none !important; }
}

/* An operational notice that has to precede the scan form without becoming the
   page's opening statement. One line, not a boxed banner. */
.note-inline {
  font: 400 14px/1.55 var(--sans); color: var(--ink-2);
  border-left: 2px solid var(--accent-mid); padding-left: 12px; margin: 0 0 18px;
}
/* The one caveat under the scan button. A line, per the brief — not a banner. */
.hero-caveat { margin: 10px 0 0; }
/* Plain scannable list of what the scanner looks for. */
.plain-list li { padding: 6px 0; }
/* The single link out to the background reading. */
.lede-link { font-size: 16px; margin: 18px 0 26px; }

/* The no-flow notice. Accent-bordered rather than neutral: it changes how every
   number below it must be read, so it cannot look like an ordinary note. */
.note.noflow { border-left-color: var(--sev-medium); }

/* Quoted-sentence evidence, for signals whose match is in fetched text rather
   than on any page: the quotation IS the evidence. */
.evidence-quote {
  margin: 0 0 8px; padding: 12px 16px; border-left: 3px solid var(--rule-2);
  background: var(--wash); font-family: var(--serif); font-size: 15.5px; line-height: 1.6;
}

/* The fourteen-state list collapses behind its own disclosure; the default is
   the whole matrix, which is what nearly every scan uses. */
.state-details { border-top: 0; padding: 4px 0 0; }
.state-details > summary { font-size: 13.5px; }

/* ===========================================================================
   ONE VISUAL SYSTEM, EVERY PAGE

   There were two for a while: a technical look on the pages that sell and
   explain, and an older serif treatment on reports and /checks. Two visual
   languages side by side read as unfinished, so everything below applies
   site-wide — the same palette, the same spacing scale, the same header and
   footer, on the home page and inside a report alike.

   ONE EXCEPTION, in one place, for a stated reason: the long-form evidence
   prose inside a rendered report keeps a serif body face, because that is the
   text somebody reads for ten minutes rather than scans. Its headings, chrome,
   tables, chips and signal values are technical like everything else. See
   `.look-report .prose` at the end of this file.

   The effect being aimed at is subtraction. Section gaps are deliberately larger
   than looks comfortable in a stylesheet — that is the point, and shrinking them
   is how this drifts back into a dense page.
   =========================================================================== */


{
  font: 16px/1.7 var(--sans);
}


/* --------------------------------------------------------- marketing type */

/* Mono headings, tight leading, and a generous gap below. The eyebrow and the
   nav go mono too, so the register is consistent rather than applied to
   headlines alone. */
h1,
h2,
h3,
.eyebrow,
.site-header nav a {
  font-family: var(--mono);
  letter-spacing: -0.01em;
}
h1 {
  font-size: clamp(30px, 6.4vw, 52px);
  font-weight: 500;
  line-height: 1.08;
  margin: 0 0 var(--s4);
  max-width: 22ch;
}
h1 em,
h1 strong {
  font-style: normal; font-weight: 500; color: var(--accent);
}
h2 {
  font-size: clamp(19px, 2.4vw, 23px);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0;
  margin: 0 0 var(--s4);
}
h3 {
  font-size: 15px; font-weight: 500; line-height: 1.4; margin: 0 0 var(--s2);
}
.eyebrow {
  font-size: 11.5px; font-weight: 400; letter-spacing: 0.16em;
}
/* Roughly 65 characters. A full-width line of body copy is the single fastest
   way to make a wide page unreadable. */
p,
li { max-width: 65ch; }
.lede {
  font-size: clamp(16.5px, 2vw, 19px); line-height: 1.6; color: var(--ink-2);
  margin: 0 0 var(--s5); max-width: 58ch;
}

/* ------------------------------------------------------- marketing shell */

/* Hairlines, not boxes. The header and footer keep a single rule each and lose
   their fill in light mode, so the page is one continuous surface. */
.site-header { background: none; border-bottom: 1px solid var(--rule); }
.site-footer { background: none; border-top: 1px solid var(--rule); margin-top: var(--s7); }
.wrap { max-width: 940px; padding: var(--s6) 26px var(--s7); }
.site-footer .wrap { padding-top: var(--s5); padding-bottom: var(--s5); }
.site-header nav a { font-size: 13.5px; letter-spacing: 0; }

/* The disclaimer banner becomes one muted line with a hairline, not a bordered
   box. It is not being demoted: it still precedes everything, and the home page
   states the same thing again directly under the scan button. */
.banner {
  border: 0; border-bottom: 1px solid var(--rule); background: none;
  padding: 0 0 var(--s4); margin: 0 0 var(--s6); font-size: 13px; color: var(--ink-3);
}
.banner b {
  font-size: 10.5px; letter-spacing: 0.16em; color: var(--ink-3); font-family: var(--mono);
  font-weight: 400; margin-bottom: var(--s1);
}

/* Panels stop being cards. */
.panel {
  background: none; border: 0; padding: 0; margin: 0 0 var(--s4);
}
.note {
  background: none; border: 0; border-left: 2px solid var(--rule-2);
  padding: 0 0 0 var(--s3); margin: 0 0 var(--s4); font-size: 14px; color: var(--ink-2);
}
.note b { font-family: var(--mono); font-weight: 400; }

/* ------------------------------------------------------- marketing sections */

/* One hairline and an enormous gap. This is the whole grouping mechanism. */
.band { border-top: 1px solid var(--rule); padding-top: var(--s6); margin-top: var(--s7); }
.band > :last-child { margin-bottom: 0; }
.band-note { font-size: 14px; color: var(--ink-3); margin: var(--s5) 0 0; }

/* Title-plus-a-sentence items in a simple grid. No borders, no shadows, no
   icons — the gap between columns is the only separator. */
.tiles {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--s5) var(--s5);
}
.tiles li { margin: 0; max-width: 42ch; }
.tiles h3 { color: var(--ink); }
.tiles h3 .g {
  font-family: var(--mono); color: var(--ink-3); font-weight: 400;
  margin-right: var(--s2);
}
.tiles p { font-size: 14px; line-height: 1.6; color: var(--ink-2); margin: 0; max-width: none; }

/* ------------------------------------------------------------ the scan form */

/* The one primary action on the site. A single filled button, the accent used
   here and on links and nowhere else. */
.act { margin: 0 0 var(--s3); }
.act .row { display: flex; gap: var(--s2); align-items: stretch; max-width: 620px; }
.act input[type="url"] {
  flex: 1 1 auto; min-width: 0; font: 15px/1.4 var(--mono);
  padding: 14px var(--s3); background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule-2); border-radius: 2px;
}
.act button[type="submit"] {
  font: 500 15px/1.4 var(--mono); padding: 14px var(--s4);
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: 2px; cursor: pointer; white-space: nowrap;
}
@media (prefers-color-scheme: dark) {
  .act button[type="submit"] { color: #06232a; }
}
.act button[type="submit"]:hover { filter: brightness(1.08); }
.act-aside { font-size: 14px; color: var(--ink-3); margin: var(--s3) 0 0; }
.act-aside a { color: var(--accent); }
.act-fine { font-size: 13px; color: var(--ink-3); margin: var(--s2) 0 0; }

/* The self-serve gate: an address and the authorization box. Set apart from the
   URL field by a hairline rather than a box, because it is a second step in the
   same action and not a separate form. */
.act-gate { margin: var(--s4) 0 0; padding: var(--s4) 0 0; border-top: 1px solid var(--rule); max-width: 620px; }
.act-gate label[for="email"] {
  display: block; font: 13.5px/1.4 var(--mono); color: var(--ink-2); margin: 0 0 var(--s2);
}
.act-gate input[type="email"] { font-family: var(--mono); }
.act-gate .attest {
  align-items: flex-start; gap: var(--s2); margin: var(--s4) 0 0; font-size: 14px; line-height: 1.55;
}
.act-gate .attest input { margin-top: 3px; flex: none; width: auto; }
.act-gate .attest span { color: var(--ink); }
.act details { margin: var(--s4) 0 0; }
.act details > summary {
  font: 13.5px/1.4 var(--mono); color: var(--ink-3); cursor: pointer; padding: var(--s2) 0;
}
.act details[open] > summary { color: var(--ink-2); }

/* Focus must be obvious in both schemes. The default UA ring disappears against
   a near-black ground on several browsers. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------- marketing pricing bits */

.plans-row { display: block; }
.price-line { font-family: var(--mono); font-size: clamp(24px, 4vw, 34px); font-weight: 500; }
.calc select {
  font: 15px/1.4 var(--mono); background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule-2); border-radius: 2px; max-width: 320px;
}
.calc label { font-family: var(--mono); font-size: 13.5px; }
.btn-link {
  font: 500 15px/1.4 var(--mono); background: var(--accent); color: #fff;
  border-radius: 2px; padding: 13px var(--s4);
}
@media (prefers-color-scheme: dark) {
  .btn-link { color: #06232a; }
}
table.bands { max-width: 340px; }
table.bands td,
table.bands th { font-family: var(--mono); font-size: 13px; }

@media (max-width: 720px) {
  .wrap { padding: var(--s5) 18px var(--s6); }
  .band { padding-top: var(--s5); margin-top: var(--s6); }
  .tiles { gap: var(--s4); }
  .act .row { flex-direction: column; }
  .act .row button { width: 100%; }
}

/* ===========================================================================
   THE ONE TYPEFACE EXCEPTION

   Inside a rendered report, the long-form evidence prose is set in a serif.
   Nowhere else on the site is, and nothing else about a report differs: its
   headings, chrome, tables, chips and signal values are the same technical
   system as the pricing page.

   The reason is reading time, not decoration. A report's prose is the text
   somebody sits with for ten minutes deciding whether a finding is worth acting
   on, and extended reading at that length is easier in a serif. Every other body
   of text on this site is scanned rather than read.

   Scoped by a class rather than applied to `.prose` outright, because `.prose`
   also wraps the changelog, the terms and the methodology — pages that are read
   in paragraphs but are not evidence, and that belong to the site's own voice.
   =========================================================================== */
.look-report .prose p,
.look-report .prose li,
.look-report .evidence-quote {
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.72;
}
.look-report .prose .hint,
.look-report .prose .small { font-family: var(--sans); }
.look-report .prose code { font-family: var(--mono); }
