/*
 * Email Health — "Editorial" skin (production).
 *
 * Modelled on sumobaby's ACTUAL single-tool pages (e.g. Filename Cleaner):
 * breadcrumb, a large clean heading, one plain-English subhead, then the tool.
 * Minimal and editorial: no boxed card grids, no pill chips, no mono labels on
 * everything. Helvetica Neue does the work; sumobaby's brand blue (#004aad) is
 * used sparingly with a pale-yellow pop, and the report's result block is the
 * one bold moment of brand colour.
 *
 * Type:  Helvetica Neue (Switzer = free self-hosted stand-in) for everything.
 *        Lekton only as a tiny kicker/overline/breadcrumb accent. Monospace only
 *        for genuine machine values (DNS records) in the report evidence. All
 *        faces are self-hosted under assets/fonts/ (see the @font-face block at
 *        the foot of this file) — no CDN, so CSP default-src 'self' is honoured.
 * Copy:  UK English, no em dashes.
 *
 * The Renderer owns the markup; this file owns the look. No inline styles or
 * scripts anywhere (strict CSP): the report gauge's arc + count-up are driven by
 * app.js via the CSSOM, reading the --circ/--target custom properties set there.
 * The arc's CSS keeps var(..., 471) fallbacks so the pre-script / no-JS frame
 * draws an EMPTY arc (never a false full ring); grade + score carry the meaning.
 */

:root {
    /* "Site Audit" skin: the accent is indigo (#4b45e6), matching the sister tool
       the boss pointed at. Used on the logo tile, numbers, links and the report
       cover. Pale yellow stays the sparing secondary pop (text selection). */
    --brand: #4b45e6;
    --brand-deep: #3a34d4;
    --brand-ink: #3b37c9;   /* link / accent-on-text; holds contrast on the warm bg */
    --brand-soft: #ecebfb;
    --accent-yellow: #feffb9;

    /* Warm off-white page, near-black ink — a flat, monochrome instrument look. */
    --bg: #f3f2ef;
    --ink: #141414;
    --ink-soft: #3d3f45;
    --muted: #6f6f6c;
    --faint: #9a9a95;
    --line: #ddddd7;    /* warm hairline */
    --line-2: #c7c7c0;  /* stronger warm rule (tag borders, print footer) */
    --rule: #26262a;    /* the near-black editorial rule under the search + strip */

    /* Status — a small coloured word + dot, never a box */
    --pass: #1c7c46;
    --warn: #8a6300;  --warn-dot: #cf9a1a;
    --fail: #bd2c2c;
    --note: #5a6270;

    --maxw: 1120px;

    /* spacing rhythm */
    --gap-section: 76px;

    /* Type: everything rides a monospace stack (the "instrument" voice); the ONE
       exception is the giant hero headline, which uses a condensed heavy face
       (--display-cond) for the Site-Audit-style display line. --display stays a
       clean sans for the report's section headings so long-form stays readable. */
    --mono-stack: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --display:      "Helvetica Neue", "Switzer", Helvetica, Arial, sans-serif;
    --display-cond: "Arial Narrow", "Helvetica Neue Condensed", "Roboto Condensed", "Helvetica Neue", Arial, sans-serif;
    --text:  var(--mono-stack);
    --label: "Lekton", ui-monospace, SFMono-Regular, Menlo, monospace;
    --mono:  ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ── Landing tokens ──────────────────────────────────────────────────────
   The landing (and its error state) wears the Sumobaby scanner front page:
   white ground, sumobaby's own blue, a wide frame and Archivo as the display
   face. Ported verbatim from mockup-homepage.html's :root, which lifted them
   from homepage-exact.html. Scoped to body.page-landing so the report page
   keeps its warm paper, its indigo accent and its 1120px column (see
   docs/HOMEPAGE_PARITY_PLAN.md, D1 to D3).

   Values only: the rules that spend them are the "Landing chrome" section
   below and, from Phase 3 on, the hero and the rail. Names match the ones the
   rules above already use, so applying the skin is a token swap and not a
   rewrite.

   The report mounts INSIDE the landing when a scan finishes, so .la-report
   re-declares the report's own ground and accent as a token island
   (live-audit.css; Phase 6 verifies it by eye). */
body.page-landing {
    --brand:      #004AAD;   /* sumobaby's own blue. Off the landing: #4b45e6 indigo */
    --brand-rgb:  0, 74, 173;
    --brand-ink:  #004AAD;   /* links ride the one accent here. Off the landing: #3b37c9 */
    --ink:        #191919;
    --muted:      #717171;
    --faint:      #8A8A8A;   /* the dimmed last word of the headline. 3.45:1 on white, so it
                                clears the 3:1 large-text minimum */
    --line:       #AAAAAA;   /* the ONE hairline: header, hero rule, footer */
    --line-soft:  #d7d7d7;   /* the lighter rule on the meter's segment tracks */
    --rule:       #191919;   /* the near-black editorial rule above the rail */
    --paper:      #FFFFFF;   /* page ground, in place of the warm --bg */
    --bg:         var(--paper);   /* the base body + header rules paint from --bg, so
                                     pointing it at --paper whitens the ground with no
                                     landing-scoped background rule of its own. The
                                     mockup, being landing-only, painted --paper direct */
    --sunken:     #F6F6F6;   /* recessed fill, the empty segment track */
    --accent-yellow: #FEFFB9;

    /* Severity, for the rail's locked segments: the reference's muted
       editorial set, close cousins of the values in :root. */
    --pass: #2E6B3E;
    --warn: #7A5B00;
    --fail: #9C3211;

    /* Type. Lekton is the body and UI voice (the brand signal); Archivo is the
       display face and appears ONLY on the headline, the brand wordmark and the
       small caps labels, exactly as the reference uses it. */
    --display: "Archivo", "Switzer", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --mono:    "Lekton", ui-monospace, "Cascadia Mono", Consolas, monospace;
    --text:    var(--mono);
    --label:   var(--mono);
    --head:    "Helvetica Neue", "Switzer", Helvetica, Arial, sans-serif;  /* the "Run check" button */

    --fw-bold: 700;
    --fw-black: 900;

    --fs-base: 18px;                          /* Lekton reads small. Off the landing: 15.5px */
    --fs-sm: 15px;
    --fs-xs: 13px;
    --fs-lg: 22px;                            /* the brand wordmark */
    --fs-input: clamp(24px, 2.6vw, 34px);     /* the frameless hero field */
    --fs-display: clamp(42px, 5.9vw, 88px);   /* the four-line headline */
    --lh-display: 0.9;
    --ls-display: -2px;
    --ls-caps: 2px;                           /* uppercase tracking */
    --lh-body: 1.6;

    --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
    --space-5: 24px; --space-6: 32px; --space-7: 40px; --space-8: 64px;

    --maxw-wide: 1900px;                  /* the reference frame. Off the landing: 1120px */
    --page-pad: clamp(20px, 4vw, 48px);   /* off the landing: a flat 40px */
}

/* ── Landing chrome ──────────────────────────────────────────────────────
   The rules the tokens above pay for: the frame, the header and the footer.
   Ported from mockup-homepage.html; the hero, the field and the rail follow in
   later phases, and those live with their own base rules further down because
   neither exists on the report.

   Everything here IS scoped, because the report shares this chrome and must keep
   its own look: same header markup, same footer markup, two skins. The shell
   emits `page-landing` for the landing and error states only. */

/* The reference sits the footer on the viewport floor with the page half empty
   beneath the rail, so the landing body is a flex column and <main> grows.
   `flex: 1 0 auto` GROWS on a tall screen and never SHRINKS: without the 0, a
   short viewport lets the flex algorithm squeeze <main> under the 100vh line and
   the footer's hairline is drawn straight through the last row of the page. */
body.page-landing {
    font-size: var(--fs-base);
    line-height: var(--lh-body);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}
.page-landing main { flex: 1 0 auto; padding-top: var(--space-8); padding-bottom: var(--space-8); }

/* The wide frame. HORIZONTAL LONGHANDS, deliberately: `.wrap` is worn by <main>,
   the header row and the footer row, all of which carry their own vertical
   padding. The base `.wrap { padding: 0 40px }` shorthand already zeroes that
   vertical padding, and setting the landing's side padding with the shorthand
   too would zero it a second time from a HIGHER-specificity selector, which the
   rows below could no longer answer. The symptom is a 35px header row and a hero
   that starts 64px too high. */
.page-landing .wrap {
    max-width: var(--maxw-wide);
    padding-left: var(--page-pad);
    padding-right: var(--page-pad);
}

/* The header: 82px of padding-driven row over the one hairline (24 + the 34px
   disc + 24), with the brand block centred (D4). `height: auto` is what hands
   the row back to the padding, since the base rule pins it to 82px. */
.page-landing .site-header__inner {
    height: auto;
    justify-content: center;
    gap: var(--space-5);
    flex-wrap: wrap;
    padding-top: var(--space-5);
    padding-bottom: var(--space-5);
}
.page-landing .brand { gap: var(--space-3); text-transform: lowercase; }
/* The round disc mark: accent fill, the smiley stroked in currentColor = paper. */
.page-landing .brand__tile {
    width: 34px; height: 34px; border-radius: 50%;
    background: var(--brand); color: var(--paper);
}
.page-landing .brand__tile svg { display: block; width: 20px; height: 20px; }
/* Lowercase accent-blue wordmark. The accessible name stays "Sumobaby": the case
   is CSS only, and `text-transform` inherits from .brand. */
.page-landing .brand__name {
    font-family: var(--display); font-weight: 800; font-size: var(--fs-lg);
    letter-spacing: normal; color: var(--brand);
}
.page-landing .brand__tool { font-size: var(--fs-sm); white-space: nowrap; }

/* The footer sits on the viewport floor, and its hairline runs FULL BLEED with
   the content in the inner wrap. The base footer hangs the same rule on the
   content column itself, which is what the report keeps. */
.page-landing .site-footer {
    margin-top: auto;
    border-top: 1px solid var(--line);
}
.page-landing .site-footer__inner {
    border-top: 0;
    padding-top: var(--space-6);
    padding-bottom: var(--space-6);
    align-items: center;
    gap: var(--space-2) var(--space-5);
    font-size: var(--fs-sm);
}

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

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--text);
    font-size: 15.5px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Two widths: the report reads in a comfortable column (--maxw scoped down on
   .wrap); the landing + chrome open up to the wide Site-Audit grid via --wide. */
.wrap { width: 100%; max-width: 900px; margin: 0 auto; padding: 0 40px; }
.wrap--wide { max-width: var(--maxw); }

h1, h2, h3 { margin: 0; font-family: var(--display); line-height: 1.1; }
a { color: var(--brand-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 3px; }
::selection { background: var(--accent-yellow); color: var(--ink); }

/* sumobaby wayfinding links grow a hairline underline on hover rather than the
   default browser underline (matches the theme's .nav-link::before effect). */
.crumbs a, .hdr__cta, .site-footer a { position: relative; }
.crumbs a::after,
.hdr__cta::after,
.site-footer a::after {
    content: ""; position: absolute; left: 0; bottom: -2px;
    width: 0; height: 1px; background: currentColor;
    transition: width 0.2s ease-in-out;
}
.crumbs a:hover::after,
.hdr__cta:hover::after,
.site-footer a:hover::after { width: 100%; }

/* Accessibility helpers (production-only; the mockup omits these) ──────── */

.skip-link {
    position: absolute;
    left: -999px; top: 0;
    background: var(--brand); color: #fff;
    padding: 10px 16px;
    border-radius: 0 0 9px 0;
    z-index: 10;
    font-family: var(--label); font-size: 12.5px; letter-spacing: 0.06em;
    text-transform: uppercase; text-decoration: none;
}
.skip-link:focus { left: 0; }

/* tiny Lekton accent — kicker / wayfinding. `.overline` lived here too; its one
   user was the "What we check" title, which the rail replaced (Phase 4). */
.kicker {
    font-family: var(--label); font-size: 12.5px; font-weight: 700;
    letter-spacing: 0.16em; text-transform: uppercase; color: var(--brand);
    margin: 0 0 18px;
}

/* ── Header ──────────────────────────────────────────────────────────── */
/* Site-Audit chrome: a square "S" app-tile + wordmark on the left, a diagonal-
   arrow text link on the right, a hairline under the row. The breadcrumb is no
   longer in this bar — it rides its own row in the page body (see .crumbs). */
.site-header { border-bottom: 1px solid var(--line); background: var(--bg); }
.site-header__inner { display: flex; align-items: center; gap: 14px; height: 82px; }
.brand { display: inline-flex; align-items: center; gap: 12px; }
.brand:hover { text-decoration: none; }
.brand__tile {
    flex: none; width: 42px; height: 42px; border-radius: 11px;
    background: var(--brand); color: #fff;
    display: grid; place-items: center;
    font-family: var(--display); font-weight: 700; font-size: 23px;
}
.brand__name { font-family: var(--display); font-weight: 700; font-size: 21px; letter-spacing: -0.01em; color: var(--ink); }
.brand__tool { font-size: 13.5px; color: var(--muted); }

.site-header__spacer { flex: 1 1 auto; }
.hdr__cta {
    font-size: 12.5px; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--brand-ink); white-space: nowrap;
    display: inline-flex; align-items: center; gap: 7px;
}
.hdr__cta:hover { color: var(--brand); text-decoration: none; }
.hdr__cta .arr { transition: transform 0.14s ease; }
.hdr__cta:hover .arr { transform: translate(2px, -2px); }

/* Breadcrumb — its own row in the body, above the hero / report. */
.crumbs {
    display: flex; align-items: center; gap: 9px;
    padding: 26px 0 0; font-size: 13px; color: var(--muted);
}
.crumbs__sep { color: var(--line); }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--ink); text-decoration: none; }
.crumbs__here { color: var(--ink); font-weight: 600; }

/* ── Buttons ─────────────────────────────────────────────────────────── */

.btn {
    font-family: var(--display); font-size: 16px; font-weight: 600;
    cursor: pointer; border: 1px solid transparent; border-radius: 9px;
    padding: 15px 26px; white-space: nowrap;
    display: inline-flex; align-items: center; gap: 9px;
    transition: background-color 0.14s ease, transform 0.06s ease;
}
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-deep); }
.btn--primary:active { transform: translateY(1px); }
/* app.js sets aria-busy + disabled on submit — give it a calm progress cue */
.btn[aria-busy="true"] { opacity: 0.8; cursor: progress; }
.btn .arr { transition: transform 0.14s ease; }
.btn:hover .arr { transform: translateX(3px); }

/* ── Landing — the statement hero ─────────────────────────────────────────
   The split hero, re-weighted to the mockup (parity plan, Phase 3): LEFT the
   display statement, RIGHT the description, the one hairline and the field, and
   the RIGHT track is now the WIDER one (1fr / 1.15fr) so the frameless field
   reads as the page's centre of gravity. Both columns share align-items:start,
   so the description aligns to the headline's top, and the copy column still
   precedes the search column in document order.

   These rules are NOT .page-landing scoped, unlike the chrome above: the hero
   and the field render on the landing and error states only, both of which wear
   the class, and RendererTest guards the report page against ever growing one.
   So they spend the landing tokens directly.
   Class names are pinned by the RendererTest hero contract; only the look moves. */
.hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 56px;
    align-items: start;
    padding: var(--space-5) 0 var(--space-6);
}

/* One heavy display statement over four forced lines, uppercase and tight. A
   .dim span greys the last word and .dot resolves it on an ink full stop. The
   accessible text stays mixed-case: text-transform paints the capitals. */
.lede__title {
    font-family: var(--display); font-weight: var(--fw-black);
    font-size: var(--fs-display); line-height: var(--lh-display);
    letter-spacing: var(--ls-display); text-transform: uppercase; color: var(--ink);
}
.lede__title .dim { color: var(--faint); }
.lede__title .dot { color: var(--ink); }

/* Right column: the description sits atop the search. A small top nudge lands
   its first line on the headline's cap-height; then the hairline, a mono
   "Domain" label, and the field as one row — input growing, "Run check" as a
   diagonal-arrow text link (no button chrome). */
.hero__search { min-width: 0; padding-top: var(--space-1); }
/* The description recedes: lighter, smaller, ~52ch of quiet context above the
   rule, not a second headline. */
.lede__sub {
    margin: 0 0 var(--space-6);
    font-family: var(--mono); font-size: var(--fs-sm); line-height: 1.5;
    color: var(--muted); max-width: 52ch;
}
.check-form { margin: 0; }
/* The hero's ONE structural hairline, and it is the page hairline now, not the
   near-black rule. 24px + the 4px the reference's own urlbar carries as its top
   padding: there is no wrapper between the rule and the label, so the rule owns
   both halves of that gap. */
.check-form__rule {
    height: 0; border: 0; border-top: 1px solid var(--line);
    margin: 0 0 calc(var(--space-5) + var(--space-1));
}
.check-form__label {
    display: block; font-family: var(--label); font-size: var(--fs-xs);
    letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--muted);
    margin-bottom: var(--space-3);
}
/* Input and action on one row over a 2px accent rule that is always on, so the
   field reads as the page's active control rather than a quiet input. */
.field {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-4);
    border-bottom: 2px solid var(--brand);
    padding-bottom: var(--space-5);
}
.field__input {
    flex: 1 1 auto; min-width: 0;
    font-family: var(--mono); font-size: var(--fs-input);
    padding: var(--space-2) 0 0; border: 0; background: transparent; color: var(--ink);
}
/* The rule under the field is accent at rest now, so it can no longer double as
   the focus cue, and a blanket `:focus { outline: none }` would outrank the
   global :focus-visible ring and leave the keyboard with nothing. Only the
   pointer ring is dropped; the keyboard ring stays. */
.field__input:focus:not(:focus-visible) { outline: none; }
.field__input::placeholder { color: var(--muted); }
.run {
    flex: 0 0 auto; cursor: pointer; background: none; border: 0; padding: 0;
    font-family: var(--head); font-size: var(--fs-base); font-weight: var(--fw-bold);
    letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--brand);
    white-space: nowrap; display: inline-flex; align-items: center; gap: var(--space-2);
    transition: color 0.6s ease-in-out;
}
.run:hover { color: var(--ink); }
.run:focus:not(:focus-visible) { outline: none; }
.run[aria-busy="true"] { opacity: 0.6; cursor: progress; }
.run .arr { font-weight: 400; transition: transform 0.14s ease; }
.run:hover .arr { transform: translate(2px, -2px); }

/* Error notice (production-only; calm left-rule callout, not a heavy box) */
.notice {
    margin: 28px 0 0; max-width: 560px;
    padding: 2px 0 2px 18px;
    border-left: 2px solid var(--line-2);
}
.notice--error { border-left-color: var(--fail); }
.notice__label {
    display: block; font-family: var(--label); font-size: 12px; font-weight: 700;
    letter-spacing: 0.12em; text-transform: uppercase; color: var(--fail);
    margin: 0 0 5px;
}
.notice__text { margin: 0; color: var(--ink-soft); font-size: 16px; }

/* Loading banner + spinner (production-only; injected by app.js after submit) */
.banner {
    display: flex; gap: 16px; align-items: center;
    margin-top: 32px; padding: 18px 20px;
    background: var(--brand-soft); border-radius: 8px;
}
.banner--loading { /* marker class app.js applies; styling lives on .banner */ }
.banner__title { margin: 0; font-family: var(--display); font-size: 18px; font-weight: 600; color: var(--ink); }
.banner__message { margin: 4px 0 0; color: var(--ink-soft); font-size: 15px; }
.spinner {
    flex: none; width: 24px; height: 24px; border-radius: 50%;
    border: 3px solid rgba(0, 74, 173, 0.2);
    border-top-color: var(--brand);
    animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* "What we check" was a three-cell divider strip here (`.about` / `.bucket`).
   Homepage parity, Phase 4 folded it into the scan rail, which names the six
   checks at rest and becomes the progress meter while a scan runs, so the strip
   and its layout rules are gone. The rail lives in `live-audit.css`. */

/* ── Footer ──────────────────────────────────────────────────────────── */

/* One quiet mono line: brand + no-login on the left, wayfinding on the right.
   The rule, the padding and the row itself sit on the INNER wrap rather than on
   the <footer>, so the landing can run its hairline full bleed while this one
   still stops at the content column. Both pages render the same box. */
.site-footer { margin-top: var(--gap-section); }
.site-footer__inner {
    padding: 26px 0 56px;
    border-top: 1px solid var(--line);
    display: flex; justify-content: space-between; align-items: baseline;
    flex-wrap: wrap; gap: 14px;
    font-size: 13px; color: var(--muted);
}
.site-footer__line b { color: var(--ink); font-weight: 700; }
.site-footer__meta { color: var(--muted); }
.site-footer__meta a { color: var(--brand-ink); }
.site-footer__meta a:hover { color: var(--brand); text-decoration: none; }
.site-footer__sep { color: var(--line-2); margin: 0 4px; }

/* ── Report tools: the "Export as PDF" affordance ────────────────────────── */
/* A quiet right-aligned bar above the cover. The button triggers the browser's
   print path (app.js: [data-print] → window.print()); the print stylesheet
   hides .report-tools, so it never shows in the exported PDF. */
.report-tools { display: flex; justify-content: flex-end; margin: 48px 0 -32px; }
.btn--ghost {
    background: transparent; color: var(--brand-ink); border-radius: 6px;
    border-color: var(--line-2); font-size: 14px; padding: 10px 16px;
}
.btn--ghost:hover { background: var(--brand-soft); border-color: var(--brand); }
.report-tools__export .arr { transition: transform 0.14s ease; }
.report-tools__export:hover .arr { transform: translateY(2px); }

/* The repeating print footer is print-only — invisible on screen. */
.print-footer { display: none; }

.check__evidence { margin: 16px 0 0; }
.check__evidence summary {
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--label); font-size: 13px; letter-spacing: 0.04em;
    text-transform: uppercase; color: var(--brand-ink);
}
.check__evidence summary::-webkit-details-marker { display: none; }
.check__evidence summary::after { content: "+"; color: var(--faint); }
.check__evidence[open] summary::after { content: "\2013"; }
.ev { margin: 14px 0 0; display: grid; gap: 8px; }
.ev__row { display: grid; grid-template-columns: minmax(120px, 26%) 1fr; gap: 16px; }
.ev__key { font-family: var(--label); font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.ev__val { font-family: var(--mono); font-size: 13.5px; color: var(--ink); overflow-wrap: anywhere; }

/* Curated evidence (Option B): a Plain view by default with a Plain / Raw
   toggle that reveals the full machine dump one click deeper. The disclosure
   emits the toggle + two `.ev-view`s only when a check is curated; an uncurated
   check keeps the single `.ev` grid above and none of this applies. */
.ev__foot { margin: 16px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); max-width: 70ch; }
.ev__mode { margin: 16px 0 4px; display: inline-flex; border: 1px solid var(--line-2); background: #fff; }
.ev__mode button {
    appearance: none; border: 0; background: transparent; cursor: pointer;
    font-family: var(--label); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); padding: 7px 14px;
}
.ev__mode button + button { border-left: 1px solid var(--line-2); }
.ev__mode button[aria-pressed="true"] { background: var(--brand); color: #fff; }
.ev-view[hidden] { display: none; }
.raw-hint {
    font-family: var(--label); font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--faint); margin: 0 0 10px;
}

/* ── Responsive ──────────────────────────────────────────────────────── */

/* The hero stacks, copy over search. 860px is the mockup's own and only
   breakpoint, and it is where it folds the six-cell directory too, so the whole
   resting landing changes shape at one width (homepage parity, Phase 6). It was
   780px, inherited from the A1 hero, which left an 80px band where the directory
   had already folded to two columns under a hero still in two. The scan chrome
   keeps its own 780px collapse in live-audit.css: that number is its grid's, not
   the hero's, and the comment there says so. */
@media (max-width: 860px) {
    .hero { grid-template-columns: 1fr; gap: var(--space-6); }
}

@media (max-width: 640px) {
    body { font-size: 15px; }
    .wrap { padding: 0 22px; }
    .lede__sub { font-size: 14.5px; }
    .field { gap: 14px; }
    .ev__row { grid-template-columns: 1fr; gap: 2px; }
    .site-footer__inner { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 0.001ms !important; transition: none !important; }
}

/* ===================================================================== */
/* Print / PDF export (WooRank-style report plan, Phase 3)               */
/*                                                                       */
/* The PDF is a first-class deliverable (D3): ONE renderer, one          */
/* stylesheet — screen and print never diverge. window.print() (the      */
/* "Export as PDF" button, wired in app.js) turns the SAME report HTML    */
/* into an agency-grade, paginated document, with no server-side engine   */
/* and no new dependency.                                                 */
/*                                                                       */
/* Page numbers: the @page margin-box counter below is honoured by paged- */
/* media engines (a future Browsershot / Gotenberg / Prince path against  */
/* this same HTML). Today's BROWSER Print-to-PDF ignores @page margin     */
/* boxes, so the per-page number comes from the browser's own header/     */
/* footer (on by default). The repeating brand FOOTER (.print-footer)     */
/* uses position:fixed, which every browser DOES repeat on each page, and */
/* the @page bottom margin reserves the band so body text never overlaps. */
/* ===================================================================== */

@page {
    size: A4;
    margin: 16mm 14mm 22mm;
    /* Honoured by paged-media engines; browsers ignore margin boxes (see note). */
    @bottom-right { content: "Page " counter(page) " of " counter(pages); }
}

@media print {
    /* Paint colours rather than dropping to ink-saving white — the cover and the
       status/impact badges carry meaning, so they must survive the export. */
    html, body { background: #fff; }
    body {
        font-size: 11pt; line-height: 1.5; color: #000;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    /* print-color-adjust is inherited, so body's `exact` above carries the
       report-kit badges, status dots, impact tags and radar into the PDF in
       their meaningful colours rather than dropping them to ink-saving white. */

    /* Site chrome and on-screen-only affordances never belong in the PDF. */
    .site-header,
    .site-footer,
    .crumbs,
    .skip-link,
    .check-form,
    .banner,
    .report-tools,
    /* Report-kit actions bar (New scan / Export as PDF) — on-screen only; an
       "Export as PDF" button in the PDF itself makes no sense. */
    .rk-actions,
    /* The Plain/Raw toggle is an on-screen affordance; the PDF carries the Plain
       view only (Raw stays hidden via its own `hidden` attribute). */
    .ev__mode { display: none !important; }

    /* The landing's own `.page-landing .wrap` outranks the bare `.wrap` here, so
       it is named too or its side padding would survive into the export. */
    .wrap, .page-landing .wrap { max-width: none; padding: 0; }
    main#main { padding: 0; }

    /* The report can be reached two ways (homepage parity, D3): at `?domain=` on
       its own page, or mounted under a finished scan on the landing. Export as
       PDF is offered on both, and the PDF has to be the same document either way.
       Off the landing it already is. Inline it was not:

         · everything above the mount is live scan chrome. The status bar, the
           gauge, the findings feed and the progress rail were all still printing,
           so the PDF opened on a frozen progress meter before it reached the
           report.
         · `.la-report` carries the report's own warm ground as a real background
           (the token island in live-audit.css), and print only whitens html and
           body, so the inline report printed as a warm panel where the standalone
           one printed on white. `print-color-adjust: exact` above means that
           ground is deliberately honoured, not dropped, which is right on screen
           and wrong here.

       Both are scoped to report-mode, which is set only once a report has
       actually mounted, so printing the resting landing is untouched. The seam
       (the rule and the 40px either side of it) goes with the chrome it was
       parting the report from.

       !important is load bearing here, not decoration: live-audit.css declares
       the same `main.report-mode .la-report` selector, and it is linked AFTER
       this file, so at equal specificity it would otherwise win. */
    main.report-mode .la-stage { display: none !important; }
    main.report-mode .la-report {
        background: #fff !important;
        margin-top: 0 !important; padding-top: 0 !important; border-top: 0 !important;
    }

    /* Pagination: keep the report-kit cover, verdict, score balance, each card,
       the CTA and a glossary row whole, and keep a category heading (and a card
       title) with the content it introduces. */
    .rk-cover, .rk-verdict, .rk-balance, .rk-check, .rk-cta, .rk-gloss__row {
        break-inside: avoid;
    }
    .rk-block__head, .rk-check__title, .rk-cover__title { break-after: avoid; }

    /* Open evidence reads as a quiet labelled block in the PDF. app.js opens
       every <details> on beforeprint; this drops the interactive marker so what
       remains is a plain "Technical details" caption above the records. Covers
       both the client appendix's `.check__evidence` and the report-kit `.rk-ev`. */
    .check__evidence summary,
    details.rk-ev summary { color: var(--muted); cursor: default; }
    .check__evidence summary::after,
    .check__evidence[open] summary::after,
    details.rk-ev summary::before,
    details.rk-ev[open] summary::before { content: ""; }

    /* Links print as plain ink — no blue, no underline, no dangling URLs. */
    a { color: #000; text-decoration: none; }

    /* The repeating brand footer — our "Brought to you by …". position:fixed is
       what makes browsers repeat it on every page; the @page bottom margin holds
       the band clear of the body text. */
    .print-footer {
        display: flex !important; justify-content: space-between; align-items: baseline;
        gap: 16px;
        position: fixed; left: 0; right: 0; bottom: 0;
        padding: 6px 14mm; background: #fff;
        border-top: 1px solid var(--line-2);
        font-family: var(--label); font-size: 8.5pt; letter-spacing: 0.04em;
        color: var(--muted);
    }
    .print-footer b { color: var(--ink); font-weight: 700; }
    .print-footer__meta { white-space: nowrap; }
}

/* ===================================================================== */
/* CLIENT REPORT  (?view=client)                                         */
/*                                                                       */
/*   The urgency-first, fix-free client report (docs/CLIENT_REPORT_PORT_ */
/*   PLAN.md). Ported from the approved mockup report-client-full.html:  */
/*   every rule that lived in that file's inline <style> block, and every */
/*   inline style="…" attribute, moved here as a class. Everything is     */
/*   namespaced under `.creport` / `.creport-*` so it can NEVER collide   */
/*   with the enriched report's classes — the two reports share the page  */
/*   shell but nothing else.                                             */
/*                                                                       */
/*   Font decision (Plan D6, option a): the mockup's JetBrains Mono is a  */
/*   Google-Fonts request the CSP forbids, so body/mono copy rides the    */
/*   self-hosted Lekton (--label) and the display headlines ride Switzer  */
/*   (--display) — both already self-hosted + preloaded, no new request.  */
/*   To adopt the exact JetBrains face later: self-host it as woff2, add   */
/*   one @font-face below, and repoint --cr-mono. Nothing else changes.   */
/*                                                                       */
/*   INERT as of Phase 0.1: no markup uses these rules yet. Phase 2 wires  */
/*   the narrative to them; Phase 3 hangs the (unchanged) evidence panels  */
/*   inside .creport-tech. Colours are the mockup's own palette, kept as   */
/*   local --cr-* tokens so they cannot leak into or out of the enriched   */
/*   report's :root variables.                                           */
/* ===================================================================== */

.creport {
    /* Mockup palette, scoped locally (never touches production :root). */
    --cr-ink:       #161615;
    --cr-body:      #3a3936;   /* paragraph ink */
    --cr-gray:      #8b8985;
    --cr-gray-soft: #9b9a96;
    --cr-indigo:    #4f46e5;
    --cr-link:      #4338ca;
    --cr-hair:      #e2e0da;
    --cr-red:       #c73a2e;
    --cr-amber:     #b5811a;
    --cr-green:     #2f9e5b;

    /* D6 option (a): self-hosted faces, no external request. */
    --cr-mono:      var(--label);    /* Lekton — brutalist mono body */
    --cr-display:   var(--display);  /* Switzer / Helvetica Neue-alike headlines */
}

/* Colour helpers (mockup .red/.amber/.green, namespaced). */
.creport-red   { color: var(--cr-red); }
.creport-amber { color: var(--cr-amber); }
.creport-green { color: var(--cr-green); }

/* -------- Checked-domain header (mockup .crumb + .tested) -------------- */
.creport-crumb {
    font-family: var(--cr-mono);
    font-size: 13px; color: var(--cr-gray); letter-spacing: 0.5px; padding: 26px 0 0;
}
.creport-crumb .creport-here { color: var(--cr-ink); font-weight: 700; }

.creport-tested {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 24px; padding: 30px 0 6px;
}
.creport-tested__label {
    font-family: var(--cr-mono); font-size: 11px; letter-spacing: 2.4px;
    color: var(--cr-gray); text-transform: uppercase; margin-bottom: 14px;
}
.creport-tested__site {
    font-family: var(--cr-mono); font-size: 26px; color: var(--cr-ink);
    letter-spacing: 0.3px; word-break: break-all;
}
.creport-tested__meta {
    font-family: var(--cr-mono); font-size: 13px; color: var(--cr-gray);
    text-align: right; line-height: 1.7; white-space: nowrap;
}

/* Shared section label (mockup .section-label). */
.creport-section-label {
    font-family: var(--cr-mono); font-size: 11px; letter-spacing: 2.4px;
    color: var(--cr-gray); text-transform: uppercase; padding: 0 0 22px;
}
.creport-section-label--ruled {
    border-top: 1px solid var(--cr-hair); padding-top: 52px;
}

/* -------- Section 1: the verdict (mockup .verdict) --------------------- */
.creport-verdict {
    display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 90px;
    align-items: start; padding: 44px 0 76px;
}
.creport-verdict h1 {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: clamp(40px, 5.8vw, 84px); line-height: 0.92; letter-spacing: -2px;
    color: var(--cr-ink); margin: 0;
}
.creport-verdict h1 .creport-muted { color: var(--cr-gray-soft); }
.creport-verdict h1 .creport-dot {
    display: inline-block; width: 0.13em; height: 0.13em; border-radius: 50%;
    background: var(--cr-red); vertical-align: baseline; margin-left: 0.04em;
}
/* Tone the hero dot per theme (the mockup only shipped the red case; the calm    */
/* and unfinished themes carry a green / amber hero). Mirrors .creport-p-dot--*.  */
.creport-verdict h1 .creport-dot--red   { background: var(--cr-red); }
.creport-verdict h1 .creport-dot--amber { background: var(--cr-amber); }
.creport-verdict h1 .creport-dot--green { background: var(--cr-green); }
.creport-lede {
    font-family: var(--cr-mono); font-size: 15px; line-height: 1.75;
    color: var(--cr-body); max-width: 440px;
}
.creport-rule { height: 1px; background: var(--cr-ink); margin: 34px 0 0; }

.creport-scores { display: flex; gap: 56px; margin: 26px 0 30px; }
.creport-score__label {
    font-family: var(--cr-mono); font-size: 11px; letter-spacing: 2.4px;
    color: var(--cr-gray); text-transform: uppercase; margin-bottom: 12px;
}
.creport-score__num {
    font-family: var(--cr-display); font-weight: 800; font-size: 62px;
    line-height: 0.9; letter-spacing: -2px;
}
.creport-score__num span {
    font-family: var(--cr-mono); font-size: 20px; color: var(--cr-gray);
    font-weight: 500; letter-spacing: 0;
}
.creport-badge {
    display: inline-block; margin-top: 12px; font-family: var(--cr-mono);
    font-size: 11px; letter-spacing: 1.6px; text-transform: uppercase; font-weight: 700;
}
.creport-cta-inline {
    font-family: var(--cr-mono); font-size: 13px; letter-spacing: 1.6px;
    color: var(--cr-link); font-weight: 500; text-transform: uppercase; text-decoration: none;
}
.creport-cta-inline:hover { text-decoration: underline; }

/* -------- Section 1b: why unnoticed (mockup .why) --------------------- */
.creport-why {
    border-top: 1px solid var(--cr-hair); padding: 46px 0 50px;
    display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 90px; align-items: start;
}
.creport-why h2 {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: clamp(24px, 3vw, 38px); line-height: 1; letter-spacing: -1.2px;
    color: var(--cr-ink); margin: 0;
}
.creport-why h2 .creport-muted { color: var(--cr-gray-soft); }
.creport-why p {
    font-family: var(--cr-mono); font-size: 15px; line-height: 1.75;
    color: var(--cr-body); max-width: 440px;
}

/* -------- Section 2: the cost (mockup .costs) ------------------------- */
.creport-costs {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 64px;
    border-top: 1px solid var(--cr-hair); padding: 52px 0 60px;
}
.creport-costs__big {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: 44px; letter-spacing: -1.5px; line-height: 0.95; margin-bottom: 18px;
    color: var(--cr-ink);
}
.creport-costs p {
    font-family: var(--cr-mono); font-size: 14px; line-height: 1.7;
    color: var(--cr-body); max-width: 340px;
}

/* -------- Section 3: live now, the proof (mockup .reality) ------------ */
.creport-reality {
    border-top: 1px solid var(--cr-hair); display: grid;
    grid-template-columns: 1.05fr 0.95fr; gap: 90px; align-items: center; padding: 60px 0;
}
.creport-reality__figure {
    font-family: var(--cr-display); font-weight: 800; letter-spacing: -3px;
    line-height: 0.85; font-size: clamp(64px, 9vw, 128px);
}
.creport-reality__cap {
    font-family: var(--cr-mono); font-size: 14px; color: var(--cr-gray);
    margin-top: 16px; max-width: 340px; line-height: 1.6;
}
.creport-reality__cap b { color: var(--cr-ink); font-weight: 700; }
.creport-reality h2 {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: clamp(26px, 3.4vw, 42px); line-height: 0.98; letter-spacing: -1.5px;
    margin-bottom: 22px; color: var(--cr-ink);
}
.creport-reality p {
    font-family: var(--cr-mono); font-size: 15px; line-height: 1.75;
    color: var(--cr-body); max-width: 440px;
}
.creport-reality .creport-stress { color: var(--cr-red); font-weight: 700; }

/* -------- Section 4: what we found (mockup .problems) ----------------- */
.creport-problems { border-top: 1px solid var(--cr-hair); padding: 52px 0 8px; }
.creport-problem {
    display: grid; grid-template-columns: 150px 1fr 120px; gap: 36px;
    align-items: start; padding: 26px 0; border-bottom: 1px solid var(--cr-hair);
}
.creport-problem__rank { display: flex; align-items: center; gap: 11px; }
.creport-p-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.creport-p-dot--red   { background: var(--cr-red); }
.creport-p-dot--amber { background: var(--cr-amber); }
.creport-p-dot--green { background: var(--cr-green); }
.creport-p-sev {
    font-family: var(--cr-mono); font-size: 11px; letter-spacing: 1.6px;
    text-transform: uppercase; font-weight: 700;
}
.creport-problem__title {
    font-family: var(--cr-display); font-weight: 700; font-size: 19px;
    letter-spacing: -0.2px; margin-bottom: 8px; color: var(--cr-ink);
}
.creport-problem__desc {
    font-family: var(--cr-mono); font-size: 14.5px; line-height: 1.7;
    color: var(--cr-body); max-width: 560px;
}
.creport-problem__val {
    font-family: var(--cr-mono); font-weight: 500; font-size: 22px;
    text-align: right; letter-spacing: -0.5px;
}
.creport-problem__val small {
    display: block; font-size: 11px; letter-spacing: 1.4px; text-transform: uppercase;
    color: var(--cr-gray); margin-top: 6px; font-weight: 700;
}

.creport-reveal {
    font-family: var(--cr-mono); padding: 34px 0 4px; font-size: 16px;
    line-height: 1.7; color: var(--cr-ink); max-width: 660px;
}
.creport-reveal b { font-weight: 700; }

/* -------- Section 5: but it works fine (mockup .split-note) ----------- */
.creport-split-note {
    border-top: 1px solid var(--cr-hair); display: grid;
    grid-template-columns: 1.05fr 0.95fr; gap: 90px; align-items: center; padding: 56px 0;
}
.creport-split-note h2 {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: clamp(26px, 3.4vw, 44px); line-height: 0.98; letter-spacing: -1.5px;
    color: var(--cr-ink); margin: 0;
}
.creport-split-note h2 .creport-muted { color: var(--cr-gray-soft); }
.creport-split-note p {
    font-family: var(--cr-mono); font-size: 15px; line-height: 1.75;
    color: var(--cr-body); max-width: 440px;
}

/* -------- Section 6: CTA (mockup .cta) -------------------------------- */
.creport-cta {
    border-top: 1px solid var(--cr-hair); display: grid;
    grid-template-columns: 1.05fr 0.95fr; gap: 90px; align-items: center; padding: 70px 0;
}
.creport-cta h2 {
    font-family: var(--cr-display); font-weight: 800; text-transform: uppercase;
    font-size: clamp(34px, 4.4vw, 64px); line-height: 0.94; letter-spacing: -1.5px;
    color: var(--cr-ink); margin: 0;
}
.creport-cta h2 .creport-muted { color: var(--cr-gray-soft); }
.creport-cta__right p {
    font-family: var(--cr-mono); font-size: 15px; line-height: 1.75;
    color: var(--cr-body); max-width: 440px; margin-bottom: 30px;
}
.creport-book {
    display: inline-block; font-family: var(--cr-mono); font-size: 15px;
    letter-spacing: 1.6px; text-transform: uppercase; font-weight: 700; color: #fff;
    background: var(--cr-indigo); text-decoration: none; padding: 16px 26px; border-radius: 10px;
}
.creport-book:hover { background: var(--cr-link); }
.creport-cta__note {
    font-family: var(--cr-mono); margin-top: 16px; font-size: 12px;
    color: var(--cr-gray); letter-spacing: 0.4px;
}

/* -------- Technical detail (collapsed) — mockup .tech ----------------- */
/* The OUTER "for the curious" wrapper only. The per-check evidence panels  */
/* INSIDE it are the enriched report's own .check__evidence markup, reused  */
/* verbatim (Plan D4) and styled by their existing rules — never restyled   */
/* here. That is why nothing below reaches into .check__evidence.           */
.creport-tech { border-top: 1px solid var(--cr-hair); padding: 30px 0 10px; }
.creport-tech > summary {
    list-style: none; cursor: pointer; font-family: var(--cr-mono); font-size: 12px;
    letter-spacing: 1.8px; text-transform: uppercase; color: var(--cr-gray);
    font-weight: 700; display: flex; align-items: center; gap: 10px;
}
.creport-tech > summary::-webkit-details-marker { display: none; }
.creport-tech > summary .creport-chev { transition: transform 0.2s; }
.creport-tech[open] > summary .creport-chev { transform: rotate(90deg); }
.creport-tech__in { padding: 26px 0 0; }
.creport-tech__lead {
    font-family: var(--cr-mono); font-size: 13px; color: var(--cr-gray);
    max-width: 660px; line-height: 1.7; margin-bottom: 10px;
}
.creport-trustline {
    font-family: var(--cr-mono); font-size: 12px; color: var(--cr-gray);
    line-height: 1.65; margin-top: 24px; max-width: 660px;
}

/* Per-check appendix panel HEAD only (mockup .checkev head, namespaced). The    */
/* evidence BODY under each head is the enriched .check__evidence markup, reused  */
/* verbatim (Plan D4) and styled by its own rules — never restyled here. Phase 0  */
/* deferred this head; Phase 3 adds it as the appendix is built.                  */
.creport-checkev { border-top: 1px solid var(--cr-hair); padding: 28px 0; }
.creport-checkev__head {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.creport-checkev__title {
    font-family: var(--cr-display); font-weight: 700; font-size: 16px;
    letter-spacing: -0.2px; color: var(--cr-ink);
}
.creport-checkev__status {
    font-family: var(--cr-mono); font-size: 11px; letter-spacing: 1.6px;
    text-transform: uppercase; font-weight: 700; white-space: nowrap;
    color: var(--cr-gray);
}

/* -------- Responsive (mockup @media max-width:900px) ----------------- */
@media (max-width: 900px) {
    .creport-verdict, .creport-why, .creport-reality,
    .creport-split-note, .creport-cta {
        grid-template-columns: 1fr; gap: 36px; padding: 36px 0 48px;
    }
    .creport-costs { grid-template-columns: 1fr; gap: 36px; }
    .creport-problem { grid-template-columns: 1fr; gap: 12px; }
    .creport-problem__val { text-align: left; }
    .creport-tested { flex-direction: column; align-items: flex-start; }
    .creport-tested__meta { text-align: left; }
}

/* -------- Print / PDF export (Client Report Phase 5.1) --------------- */
/* The client report exports through the SAME window.print() path as the    */
/* enriched report (app.js: [data-print] -> window.print()). On beforeprint  */
/* app.js opens the outer .creport-tech disclosure AND its nested            */
/* .check__evidence panels, so the technical appendix carries into the PDF   */
/* on its Plain view (the .ev__mode toggle + Raw stay hidden — handled by     */
/* the enriched print block above). One renderer, one stylesheet: screen and */
/* PDF never diverge. The @page A4 size and the shared, per-page .print-      */
/* footer band are defined once in the enriched print block above and reused  */
/* here, so the client PDF is self-identifying with one brand strip.         */
@media print {
    /* The client report is near-monochrome editorial with a few meaning-      */
    /* carrying accents (red/amber/green verdicts + dots, the indigo CTA);     */
    /* force the whole scope to print its colours exactly so none drop out.    */
    .creport, .creport * {
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }

    /* On-screen-only navigation chrome never belongs in the PDF: the          */
    /* breadcrumb and the inline "see what this could cost you" anchor jump.    */
    /* (The export button .report-tools and the .ev__mode toggle are already    */
    /* hidden by the enriched print block above.)                              */
    .creport-crumb, .creport-cta-inline { display: none !important; }

    /* Flatten the two-column editorial grids to one readable column (mirrors   */
    /* the 900px screen breakpoint) and tighten the generous screen padding so  */
    /* the PDF paginates cleanly instead of one section per page.              */
    .creport-verdict, .creport-why, .creport-reality,
    .creport-split-note, .creport-cta { grid-template-columns: 1fr; gap: 22px; }
    .creport-costs { grid-template-columns: 1fr; gap: 20px; }
    .creport-problem { grid-template-columns: 1fr; gap: 10px; }
    .creport-problem__val { text-align: left; }
    .creport-verdict, .creport-why, .creport-costs, .creport-reality,
    .creport-problems, .creport-split-note, .creport-cta,
    .creport-tech { padding: 22px 0; }

    /* Never split a self-contained block across a page. */
    .creport-verdict, .creport-why, .creport-reality, .creport-reveal,
    .creport-split-note, .creport-cta, .creport-problem,
    .creport-costs > div, .creport-checkev { break-inside: avoid; }
    .creport-verdict h1, .creport-why h2, .creport-reality h2,
    .creport-split-note h2, .creport-cta h2,
    .creport-costs__big, .creport-checkev__head { break-after: avoid; }
    /* The long appendix may flow across pages; only its panels stay whole. */
    .creport-tech { break-inside: auto; }

    /* The appendix is force-opened for print; render its summary as a plain    */
    /* caption — drop the interactive chevron and the pointer cursor.          */
    .creport-tech > summary { cursor: default; color: var(--cr-gray); }
    .creport-chev { display: none !important; }

    /* The booking CTA is the payload of this report, so it keeps its brand     */
    /* colour in the PDF (the global print rule flattens links to plain ink).   */
    .creport-book {
        color: #fff !important; background: var(--cr-indigo) !important;
    }
}

/* ===================================================================== */
/* Report-kit skin (report-kit port, Phase 2)                            */
/*                                                                       */
/*   The graded report's new look, ported from mockup-needs-work.html /  */
/*   mockup-strong.html. EVERYTHING here is scoped under .rk-report so it */
/*   only styles the graded report body — it never leaks into the        */
/*   landing/error pages, and the report-kit palette (accent #004AAD,    */
/*   Lekton mono) is self-contained, independent of the app's indigo     */
/*   landing tokens (decision D10). The mockups' webfont @import is       */
/*   dropped: --font-mono/--font-head repoint to the self-hosted Lekton   */
/*   (--label) and Helvetica-Neue/Switzer (--display) faces at the foot   */
/*   of this file (invariant 2 — no CDN). Every inline style the mockups  */
/*   use (grade-badge backgrounds, the whole radar SVG, figcaption/label  */
/*   text) has a class or SVG presentation-attribute equivalent here, so  */
/*   the Renderer emits no inline style="" (hard CSP boundary).           */
/*                                                                       */
/*   Phase 2 only LANDS these rules; no markup carries .rk-* until later  */
/*   phases, so the existing pages are visually unchanged.               */
/* ===================================================================== */

.rk-report {
    /* base report-kit palette, ported as-is from the mockups (D10) */
    --accent: #004AAD; --accent-contrast: #FFFFFF;
    --ink: #191919; --paper: #FFFFFF;
    --ground: #FFFFFF; --sunken: #F6F6F6;
    --text-muted: #717171;
    --hairline: #AAAAAA; --hairline-soft: #d7d7d7;
    --highlight: #FEFFB9;

    --sev-critical: #8B1A10; --sev-critical-bg: #F7E7E4;
    --sev-high: #9C3211;     --sev-high-bg: #F8EAE2;
    --sev-medium: #7A5B00;   --sev-medium-bg: #F6F0DA;
    --sev-low: #3D5A73;      --sev-low-bg: #E9EEF3;
    --sev-info: #5C5C5C;     --sev-info-bg: #ECECEC;
    --sev-ok: #2E6B3E;       --sev-ok-bg: #E6F0E9;

    --grade-a: #059669; --grade-b: #2563EB; --grade-c: #F59E0B; --grade-d: #EA580C; --grade-f: #B91C1C;

    /* fonts repointed to the self-hosted faces (no webfont @import) */
    --font-mono: var(--label);   /* Lekton */
    --font-head: var(--display); /* Helvetica Neue / Switzer */

    /* the --rk-* layer, resolving off the palette above */
    --rk-accent: var(--accent, #004AAD); --rk-accent-soft: var(--sev-low-bg, #E9EEF3);
    --rk-ink: var(--ink, #191919); --rk-ink-soft: #3D3F45; --rk-muted: var(--text-muted, #717171);
    --rk-faint: #9A9A95; --rk-line: var(--hairline-soft, #D7D7D7); --rk-line-2: var(--hairline, #C7C7C0);
    --rk-paper: var(--paper, #FFFFFF); --rk-quiet: #FBFBFA; --rk-sunken: var(--sunken, #F6F6F3);
    --rk-pass: var(--sev-ok, #2E6B3E); --rk-warn: var(--sev-medium, #7A5B00); --rk-warn-dot: #CF9A1A;
    --rk-fail: var(--sev-critical, #8B1A10); --rk-note: var(--sev-info, #5C5C5C);
    --rk-crit: var(--sev-critical, #8B1A10); --rk-high: var(--sev-high, #9C3211);
    --rk-med: var(--sev-medium, #7A5B00); --rk-low: var(--sev-low, #3D5A73); --rk-info: var(--sev-info, #5C5C5C);
    --rk-crit-bg: var(--sev-critical-bg, #F7E7E4); --rk-high-bg: var(--sev-high-bg, #F8EAE2);
    --rk-med-bg: var(--sev-medium-bg, #F6F0DA); --rk-low-bg: var(--sev-low-bg, #E9EEF3);
    --rk-info-bg: var(--sev-info-bg, #ECECEC); --rk-pass-bg: var(--sev-ok-bg, #E6F0E9);
    --rk-grade-a: var(--grade-a, #059669); --rk-grade-b: var(--grade-b, #2563EB);
    --rk-grade-c: var(--grade-c, #F59E0B); --rk-grade-d: var(--grade-d, #EA580C); --rk-grade-f: var(--grade-f, #B91C1C);
    --rk-mono: var(--font-mono, "Lekton", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
    --rk-disp: var(--font-head, "Helvetica Neue", Helvetica, Arial, sans-serif);
    --rk-label: var(--font-mono, "Lekton", ui-monospace, SFMono-Regular, Menlo, monospace);

    max-width: 860px; margin: 0 auto; color: var(--rk-ink);
    font-family: var(--rk-mono); font-size: 15px; line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}
.rk-report a:not(.rk-btn) { color: var(--rk-accent); text-decoration: none; }
.rk-report a:not(.rk-btn):hover { text-decoration: underline; }
.rk-eyebrow { font-family: var(--rk-label); font-size: 12px; letter-spacing: .22em; text-transform: uppercase; color: var(--rk-accent); margin: 0 0 14px; }
.rk-cover__title { font-family: var(--rk-disp); font-weight: 700; font-size: 2.35rem; line-height: 1.05; letter-spacing: -.015em; margin: 0 0 12px; text-wrap: balance; }
.rk-cover__url { font-family: var(--rk-mono); font-size: 13.5px; color: var(--rk-muted); }
.rk-cover__url b { color: var(--rk-ink-soft); font-weight: 400; }
.rk-verdict { display: grid; grid-template-columns: 150px 1fr; gap: 34px; align-items: center; margin: 38px 0 10px; padding: 26px 0; border-top: 1px solid var(--rk-line); border-bottom: 1px solid var(--rk-line); }
.rk-gauge { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.rk-ring__score { font-family: var(--rk-label); font-size: 13px; color: var(--rk-muted); letter-spacing: .05em; white-space: nowrap; }
.rk-band { display: inline-flex; align-items: center; gap: 8px; font-family: var(--rk-label); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; margin: 0 0 8px; font-weight: 700; }
.rk-band__dot { width: 9px; height: 9px; border-radius: 50%; }
.rk-verdict__lead { font-family: var(--rk-disp); font-size: 1.28rem; line-height: 1.28; margin: 0 0 10px; letter-spacing: -.01em; }
.rk-verdict__meta { font-size: 13px; color: var(--rk-muted); }
.rk-verdict__meta b { color: var(--rk-pass); font-weight: 400; }
.rk-bd-a { background: var(--rk-grade-a); } .rk-bd-b { background: var(--rk-grade-b); }
.rk-bd-c { background: var(--rk-grade-c); } .rk-bd-d { background: var(--rk-grade-d); } .rk-bd-f { background: var(--rk-grade-f); }
.rk-bd-warn { background: var(--rk-warn-dot); } .rk-bd-note { background: var(--rk-note); }
.rk-badge { width: 112px; height: 112px; flex: none; border-radius: 18px; display: flex; align-items: center; justify-content: center; font-family: var(--rk-disp); font-weight: 700; font-size: 3.9rem; line-height: 1; color: #fff; }
.rk-cat__badge { width: 46px; height: 46px; flex: none; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-family: var(--rk-disp); font-weight: 700; font-size: 1.35rem; line-height: 1; color: #fff; }
.rk-cats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 26px 0 0; }
.rk-cat { border: 1px solid var(--rk-line); border-radius: 10px; padding: 18px 16px; background: var(--rk-quiet); display: flex; align-items: center; gap: 14px; }
.rk-cat__name { font-family: var(--rk-disp); font-weight: 700; font-size: .98rem; line-height: 1.15; margin: 0 0 3px; }
.rk-cat__sub { font-size: 11.5px; color: var(--rk-muted); line-height: 1.3; }
.rk-balance { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); gap: 24px; align-items: center; margin: 26px 0 0; }
.rk-balance__cards .rk-cats { grid-template-columns: 1fr; margin: 0; }
.rk-balance__radar { display: flex; justify-content: center; }
@media (max-width: 640px) { .rk-balance { grid-template-columns: 1fr; gap: 20px; } }
.rk-block { margin-top: var(--rk-gap, 64px); }
.rk-block__head { display: flex; align-items: baseline; justify-content: space-between; border-bottom: 1px solid var(--rk-line); padding-bottom: 12px; margin-bottom: 26px; }
.rk-block__head h2 { font-family: var(--rk-disp); font-weight: 700; font-size: 1.5rem; margin: 0; letter-spacing: -.01em; }
.rk-block__count { font-family: var(--rk-label); font-size: 12px; letter-spacing: .06em; color: var(--rk-muted); }
.rk-block__count b { color: var(--rk-ink); }
.rk-checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.rk-check { border: 1px solid var(--rk-line); border-radius: 12px; padding: 20px 22px; background: var(--rk-paper); }
.rk-check--quiet { background: var(--rk-quiet); }
.rk-check__top { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.rk-check__title { font-family: var(--rk-disp); font-weight: 700; font-size: 1.08rem; margin: 0; }
.rk-status { display: inline-flex; align-items: center; gap: 7px; font-family: var(--rk-label); font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; white-space: nowrap; }
.rk-status__dot { width: 9px; height: 9px; border-radius: 50%; }
.rk-status--pass { color: var(--rk-pass); } .rk-status--pass .rk-status__dot { background: var(--rk-pass); }
.rk-status--warn { color: var(--rk-warn); } .rk-status--warn .rk-status__dot { background: var(--rk-warn-dot); }
.rk-status--fail { color: var(--rk-fail); } .rk-status--fail .rk-status__dot { background: var(--rk-fail); }
.rk-status--note { color: var(--rk-note); } .rk-status--note .rk-status__dot { background: var(--rk-note); }
.rk-check__tags { display: flex; gap: 8px; margin: 13px 0 0; flex-wrap: wrap; }
.rk-tag { font-family: var(--rk-label); font-size: 11px; letter-spacing: .05em; text-transform: uppercase; padding: 4px 9px; border-radius: 6px; border: 1px solid var(--rk-line-2); color: var(--rk-ink-soft); }
.rk-tag--impact-high { color: var(--rk-fail); background: var(--rk-crit-bg); border-color: var(--rk-crit-bg); }
.rk-tag--impact-medium { color: var(--rk-med); background: var(--rk-med-bg); border-color: var(--rk-med-bg); }
.rk-tag--impact-low { color: var(--rk-low); background: var(--rk-low-bg); border-color: var(--rk-low-bg); }
.rk-check__summary { margin: 14px 0 0; font-size: 14.5px; }
.rk-check__found { margin: 10px 0 0; font-size: 14px; color: var(--rk-ink-soft); }
.rk-check__found b { color: var(--rk-ink); font-weight: 700; }
.rk-consequence { margin: 15px 0 0; padding: 13px 16px; border-left: 3px solid var(--rk-warn-dot); background: var(--rk-med-bg); border-radius: 0 8px 8px 0; }
.rk-consequence__label { font-family: var(--rk-label); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--rk-med); font-weight: 700; }
.rk-consequence p { margin: 5px 0 0; font-size: 13.5px; color: var(--rk-ink-soft); }
details.rk-ev { margin: 15px 0 0; border-top: 1px dashed var(--rk-line-2); padding-top: 12px; }
details.rk-ev summary { font-family: var(--rk-label); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--rk-muted); cursor: pointer; list-style: none; display: flex; align-items: center; gap: 7px; }
details.rk-ev summary::-webkit-details-marker { display: none; }
details.rk-ev summary::before { content: "+"; font-size: 15px; color: var(--rk-accent); width: 12px; }
details.rk-ev[open] summary::before { content: "\2212"; }
.rk-ev__body { margin: 12px 0 0; font-family: var(--rk-mono); font-size: 12.5px; color: var(--rk-ink-soft); background: var(--rk-sunken); border: 1px solid var(--rk-line); border-radius: 8px; padding: 12px 14px; line-height: 1.7; overflow-x: auto; }
.rk-ev__row { display: grid; grid-template-columns: 150px 1fr; gap: 12px; padding: 3px 0; }
.rk-ev__k { color: var(--rk-faint); }
.rk-ev__foot { margin: 10px 0 0; padding-top: 9px; border-top: 1px dashed var(--rk-line-2); color: var(--rk-muted); font-size: 12px; line-height: 1.55; }
.rk-cta { margin: 36px 0 0; padding: 24px 26px; border: 1px solid var(--rk-accent); border-radius: 12px; background: var(--rk-accent-soft); display: flex; gap: 22px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.rk-cta__head { font-family: var(--rk-disp); font-weight: 700; font-size: 1.22rem; margin: 0 0 5px; color: var(--rk-ink); }
.rk-cta__body { margin: 0; font-size: 14px; line-height: 1.5; color: var(--rk-ink-soft); max-width: 56ch; }
.rk-legend { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 30px; padding-top: 20px; border-top: 1px solid var(--rk-line); font-size: 12.5px; color: var(--rk-muted); }
.rk-legend span { display: inline-flex; align-items: center; gap: 7px; }
.rk-legend .d { width: 9px; height: 9px; border-radius: 50%; }
.rk-gloss { margin-top: 44px; padding-top: 22px; border-top: 1px solid var(--rk-line); }
.rk-gloss__title { font-family: var(--rk-disp); font-weight: 700; font-size: 1.15rem; margin: 0 0 4px; color: var(--rk-ink); }
.rk-gloss__intro { font-size: 13px; color: var(--rk-muted); margin: 0 0 18px; }
.rk-gloss__list { margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 16px 32px; }
.rk-gloss__row { margin: 0; }
.rk-gloss__term { font-family: var(--rk-disp); font-weight: 700; font-size: 0.92rem; color: var(--rk-ink); margin: 0; }
.rk-gloss__def { margin: 2px 0 0; font-size: 0.86rem; line-height: 1.5; color: var(--rk-ink-soft, #3d3f45); }
@media (max-width: 640px) { .rk-gloss__list { grid-template-columns: 1fr; } }
.rk-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin: 0 0 26px; }
.rk-actions--footer { margin: 38px 0 0; padding-top: 22px; border-top: 1px solid var(--rk-line); }
.rk-btn { display: inline-flex; align-items: center; gap: 8px; font-family: var(--rk-label); font-size: 12.5px; letter-spacing: .04em; text-transform: uppercase; font-weight: 700; padding: 11px 21px; border-radius: 4px; text-decoration: none; cursor: pointer; border: 1.5px solid var(--rk-accent); color: var(--rk-accent); background: var(--rk-paper); transition: background .12s, color .12s, border-color .12s; }
.rk-btn:hover { background: var(--rk-accent-soft); }
.rk-btn--primary { background: var(--rk-accent); color: var(--rk-paper); border-color: var(--rk-accent); }
.rk-btn--primary:hover { background: var(--rk-ink); border-color: var(--rk-ink); }
.rk-btn--ghost { border-color: var(--rk-line-2); color: var(--rk-ink-soft); }
.rk-btn--ghost:hover { background: var(--rk-sunken); }
@media (max-width: 640px) {
    .rk-verdict { grid-template-columns: 1fr; justify-items: center; text-align: center; }
    .rk-cats { grid-template-columns: 1fr; }
    .rk-actions .rk-btn { flex: 1 1 auto; justify-content: center; }
}

/* radar — server-rendered SVG, class-based (invariant 2: no inline style=). */
.rk-radar { margin: 0; text-align: center; }
.rk-radar__svg { width: 100%; max-width: 400px; height: auto; }
.rk-radar__ring { fill: none; stroke: var(--rk-line); stroke-width: 1; }
.rk-radar__axis { stroke: var(--rk-line); stroke-width: 1; }
.rk-radar__area { fill-opacity: .13; stroke-width: 2; stroke-linejoin: round; }
.rk-radar__cap { font-family: var(--rk-disp); font-weight: 700; font-size: 11px; letter-spacing: .09em; text-transform: uppercase; color: var(--rk-muted); margin-top: 8px; }

/* ===================================================================== */
/* Five areas (five-area report, Phase 5)                                */
/*                                                                       */
/*   The delta mockup-five-areas.html adds to the report-kit skin. It     */
/*   sits AFTER the .rk-* rules above on purpose: a.rk-cat below ties on  */
/*   specificity with the generic `.rk-report a:not(.rk-btn)` link rule,  */
/*   so it has to come later to win.                                     */
/* ===================================================================== */

/* -- the cards column ------------------------------------------------------
   Five cards where the shipped grid carries three, so they run tighter. Each
   card is a LINK to its own section: the whole point of one taxonomy is that a
   reader can get from the letter to the findings that produced it. */
.rk-cats--areas { grid-template-columns: 1fr; gap: 9px; margin: 0; }
.rk-cats--areas .rk-cat { padding: 12px 13px; gap: 12px; align-items: flex-start; }
.rk-cats--areas .rk-cat__badge { width: 40px; height: 40px; font-size: 1.12rem; border-radius: 8px; }
/* No underline on the card, hover included: the generic `.rk-report
   a:not(.rk-btn):hover` rule outranks a bare `a.rk-cat`, and it underlines the
   whole card — name and description both. The hover cue is the accent border
   and the lifted background instead. */
.rk-report a.rk-cat { text-decoration: none; color: inherit; transition: border-color .12s, background .12s; }
.rk-report a.rk-cat:hover { border-color: var(--rk-accent); background: var(--rk-paper); text-decoration: none; }
.rk-cats__note { margin: 14px 0 0; font-size: 12px; line-height: 1.6; color: var(--rk-muted); }

/* -- the letter, repeated on the section heading ---------------------------
   The same letter as the card badge and the dot on the web. Badge, dot and
   heading are one area, so the letter can be checked against the findings.
   Rendered by the sections (Phase 6); the class lands with the rest of the
   delta so the two phases do not split one stylesheet block. */
.rk-area-grade {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 32px; height: 26px; padding: 0 8px; border-radius: 6px;
    color: #fff; font-family: var(--rk-disp); font-weight: 700;
    font-size: .86rem; line-height: 1; margin-right: 11px; vertical-align: 2px;
}
.rk-block__intro { margin: -8px 0 20px; font-size: 13.5px; line-height: 1.65; color: var(--rk-muted); max-width: 68ch; }

/* -- the web ---------------------------------------------------------------
   The pieces that make it read the way it does, in the order they are drawn:

     - inner rings hairline grey, the OUTER RIM slightly heavier, so the
       boundary of a perfect score is the one gridline that reads as an edge
     - spokes hairline with rounded caps
     - the grade ladder up the top spoke: A+, B, D+, F reading outward to in,
       each letter carrying a paper halo so it knocks out the ring behind it
     - area names in bold display ink, set well clear of the rim
     - no numbers, no letters on the spokes themselves

   The ladder is what lets a reader price a single point ("that dent reaches
   about a D+"). It is faint grey on purpose: it is a scale, not a verdict.

   SIZE. Three things make the web read as the equal of the card stack beside
   it, in order of effect:

     1. The area names wrap to two lines. This is the real lever. Set on one
        line they push the viewBox out to 544 units wide, and since the drawing
        scales to the column width, every wasted unit of label run shrinks the
        pentagon. Wrapped, the box tightens to 428 x 286 and the same column
        renders the web about a third larger.
     2. The report opens to 920px, and the web takes the larger half of the
        split.
     3. The figure is width:100% so nothing shrink-to-fits inside the flex
        column, and the SVG has no max-width holding it back (the shipped rule
        caps it at 400px, which is what kept it small).

   The pentagon itself is untouched. Apparent size is set by the ratio of the
   circumradius to the viewBox, never by the radius, so tightening the frame is
   what enlarges the drawing. */
.rk-report { max-width: 920px; }
.rk-balance--areas { grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr); gap: 28px; }
.rk-radar--areas { width: 100%; margin: 0; }
/* The shipped narrow-screen rule stacks .rk-balance, but this block comes after
   it, so the areas variant has to restate it or the two columns survive down to
   a phone and squeeze both. The mockup is a single-width artefact and never had
   to answer this. */
@media (max-width: 640px) { .rk-balance--areas { grid-template-columns: 1fr; gap: 20px; } }
.rk-radar__svg--areas { max-width: 100%; }
.rk-radar__ring--rim { stroke: var(--rk-line-2); stroke-width: 1.4; }
.rk-radar__axis { stroke-linecap: round; }
.rk-radar__label--area { font-family: var(--rk-disp); font-size: 12.5px; font-weight: 700; fill: var(--rk-ink); }
/* An area we could not score (an Info or couldn't-check result) keeps its name
   but greys it, and plots no vertex and no dot. Never plotted at full: that is
   the fake-value trap Renderer.php:102 already warns about. Reachable through
   "Where your mail goes" on a null-MX domain and through "Your address in
   public" when the page cannot be fetched. */
.rk-radar__label--muted { fill: var(--rk-faint); }
.rk-radar__rung {
    font-family: var(--rk-disp); font-size: 10.5px; font-weight: 700; fill: var(--rk-faint);
    paint-order: stroke; stroke: var(--rk-paper); stroke-width: 3.5; stroke-linejoin: round;
}

/* ONE COLOUR FOR THE WHOLE WEB, and that colour is the overall grade's.

   The shape's fill, the shape's outline and every vertex dot all take the same
   grade colour, so the web is monochrome and the eye reads one object. It is
   also how the chart answers to the letter at the top of the page: the web is
   amber BECAUSE the grade is C+, and it would be red at F or green at A.
   Colouring each dot by its own area turns the chart into five competing
   colours and loses that entirely.

   The letters stay on the cards, where five verdicts belong. The web says one
   thing: this is your grade, and this is its shape. */
.rk-radar__area--a { fill: var(--rk-grade-a); stroke: var(--rk-grade-a); }
.rk-radar__area--b { fill: var(--rk-grade-b); stroke: var(--rk-grade-b); }
.rk-radar__area--c { fill: var(--rk-grade-c); stroke: var(--rk-grade-c); }
.rk-radar__area--d { fill: var(--rk-grade-d); stroke: var(--rk-grade-d); }
.rk-radar__area--f { fill: var(--rk-grade-f); stroke: var(--rk-grade-f); }

/* The dots ride one group carrying that same grade colour rather than a class
   per point. This supersedes the old per-point pass/warn/fail tones, which
   keyed off "is this 100, 0, or something else" and so could never describe a
   B+. */
.rk-radar__pts { stroke: var(--rk-paper); stroke-width: 1.5; }
.rk-radar__pts--a { fill: var(--rk-grade-a); }
.rk-radar__pts--b { fill: var(--rk-grade-b); }
.rk-radar__pts--c { fill: var(--rk-grade-c); }
.rk-radar__pts--d { fill: var(--rk-grade-d); }
.rk-radar__pts--f { fill: var(--rk-grade-f); }

/* Nothing else sits on the chart: rings, spokes, ladder, shape, dots, names,
   caption, and that is the whole inventory. */

/* Print only. The SVG carries role="img" and a full aria-label, so a screen
   reader already hears every area and its letter; this list exists because a
   web reproduces badly on paper. */
.rk-radar__print { display: none; }
.rk-radar__sub {
    display: block; margin-top: 6px; font-family: var(--rk-mono); font-size: 12.5px;
    font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--rk-muted);
    max-width: 46ch; margin-left: auto; margin-right: auto; line-height: 1.55;
}

/* -- appendix: background, not a grade -------------------------------------
   Hosting lives here. It is descriptive and deliberately unscored, so it gets
   a block that is visibly not one of the graded five. Rendered by Phase 6. */
.rk-appendix { margin-top: 54px; padding-top: 26px; border-top: 2px solid var(--rk-line-2); }
.rk-appendix__eyebrow { font-family: var(--rk-label); font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: var(--rk-muted); margin: 0 0 6px; }
.rk-appendix__note { font-size: 13px; color: var(--rk-muted); margin: 0; max-width: 68ch; }
.rk-info { border: 1px solid var(--rk-line); border-radius: 12px; overflow: hidden; }
.rk-info__head { display: flex; align-items: center; justify-content: space-between; padding: 13px 18px; background: var(--rk-sunken); border-bottom: 1px solid var(--rk-line); font-family: var(--rk-disp); font-size: .95rem; }
.rk-info__tag { font-family: var(--rk-label); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--rk-muted); font-weight: 400; }
.rk-irow { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; padding: 15px 18px; border-bottom: 1px solid var(--rk-line); }
.rk-irow:last-child { border-bottom: 0; }
.rk-irow b { font-family: var(--rk-disp); font-size: .95rem; }
.rk-irow p { margin: 4px 0 0; font-size: 13.5px; color: var(--rk-ink-soft); line-height: 1.55; }
.rk-irow__flag { font-family: var(--rk-label); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--rk-note); background: var(--rk-info-bg); border-radius: 6px; padding: 4px 9px; white-space: nowrap; }

/* The new coloured surfaces need the colour-adjust the shipped badges get, or
   the letters print white on white. */
@media print {
    .rk-area-grade, .rk-radar__area, .rk-radar__pts, .rk-irow__flag {
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    .rk-radar__print {
        display: grid; grid-template-columns: 1fr auto; gap: 4px 16px;
        margin-top: 12px; font-size: 12px;
    }
    .rk-radar__print li { display: contents; }
    .rk-radar__k { color: var(--rk-muted); }
    .rk-radar__v { font-family: var(--rk-disp); font-weight: 700; }
    .rk-report a.rk-cat { border-color: var(--rk-line); }
}

/* ===================================================================== */
/* Self-hosted fonts                                                     */
/*                                                                       */
/*   Switzer  — free Helvetica-Neue-alike, the display + body face. Used  */
/*              via the stack "Helvetica Neue", "Switzer", … so machines  */
/*              with real Helvetica Neue use HN and everyone else gets    */
/*              Switzer. To ship sumobaby's licensed Helvetica Neue, add  */
/*              HN @font-face rules here — the stack already prefers it.   */
/*              The editorial skin paints weights 400/500/600/700 + the    */
/*              italic 400 tagline. (switzer-300 is unused by this skin    */
/*              but retained below; it is harmless and costs nothing until */
/*              referenced.)                                              */
/*   Lekton   — OFL technical-label accent (kicker / overline / crumbs /  */
/*              evidence keys / domain).                                  */
/*   Archivo  — OFL grotesque, the landing's display face (headline,      */
/*              brand wordmark, rail labels). Weights 800 + 900 only, and  */
/*              only under body.page-landing; the report never asks for it. */
/*              Latin-subset static instances from Google Fonts v25.       */
/*                                                                       */
/* All same-origin under assets/fonts/ (satisfies CSP default-src 'self');*/
/* font-display: swap so text paints immediately on the fallback stack.   */
/* ===================================================================== */

@font-face {
    font-family: "Switzer";
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url("fonts/switzer-300.woff2") format("woff2");
}
@font-face {
    font-family: "Switzer";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/switzer-400.woff2") format("woff2");
}
@font-face {
    font-family: "Switzer";
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/switzer-italic-400.woff2") format("woff2");
}
@font-face {
    font-family: "Switzer";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("fonts/switzer-500.woff2") format("woff2");
}
@font-face {
    font-family: "Switzer";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("fonts/switzer-600.woff2") format("woff2");
}
@font-face {
    font-family: "Switzer";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/switzer-700.woff2") format("woff2");
}

@font-face {
    font-family: "Lekton";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/lekton-400.woff2") format("woff2");
}
@font-face {
    font-family: "Lekton";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/lekton-700.woff2") format("woff2");
}

@font-face {
    font-family: "Archivo";
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url("fonts/archivo-800.woff2") format("woff2");
}
@font-face {
    font-family: "Archivo";
    font-style: normal;
    font-weight: 900;
    font-display: swap;
    src: url("fonts/archivo-900.woff2") format("woff2");
}
