/* ── Type: Schibsted Grotesk, self-hosted (apps/landing/fonts) ─────────────────────────
   ⛔ NOT Google Fonts, and the design handoff's instruction to use it would have shipped
   INERT. `_headers` sends `style-src 'self'; font-src 'self'` to this host, so a
   fonts.googleapis.com stylesheet and a fonts.gstatic.com woff2 are both blocked outright:
   the page would render in the fallback stack, silently, with the only evidence in a console
   nobody reads. Loosening the CSP to admit a third party is the wrong trade for a typeface,
   and the repo already removed the Turnstile script for being "a third-party request per
   pageview for nothing".
   These are the SAME BYTES the app serves from apps/web/public/fonts, copied rather than
   re-cut, so the marketing site and the product render identically. That was the point of
   the change: a visitor used to read the site in Helvetica and land in the app in Schibsted.
   ⚠️ If the app ever re-cuts its fonts, copy them here in the same PR or the two drift. ── */
@font-face {
  font-family: "Schibsted Grotesk"; font-style: normal; font-weight: 400 900; font-display: swap;
  src: url("/fonts/SchibstedGrotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Schibsted Grotesk"; font-style: normal; font-weight: 400 900; font-display: swap;
  src: url("/fonts/SchibstedGrotesk-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Schibsted Grotesk"; font-style: italic; font-weight: 400 900; font-display: swap;
  src: url("/fonts/SchibstedGrotesk-latin-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================================
   page.css — shared stylesheet for the jobshifu.com CONTENT SUB-PAGES
   (/calibration, /autofill, and the rest of the Tier-A set).

   Why this file exists instead of a shared extraction from index.html:
   the landing page carries ~640 lines of INLINE css, most of it driving the
   hero tailoring loop, the showcase rows and the autofill animation. Pulling a
   common base out of it would mean rewriting index.html's <style> block and
   re-verifying every animation on the highest-value page we own. The sub-pages
   need maybe 15% of that css, so they get their own lean sheet and index.html
   stays byte-stable apart from its nav/footer links.

   ⚠️ The :root block below is COPIED from index.html, which is itself a copy of
   apps/web/src/app/style.css (seed #f4630f). Three copies now. On a theme change
   update all three. Tokens only, no new hexes: DESIGN.md is law.

   Voice constraints that apply to every page using this sheet:
     · "resume" is UNACCENTED, always.
     · No em dashes in prose.
     · No "copilot", no "local-first", no "BYO key", no privacy-moat claims.
     · The differentiator is the Calibration Engine (non-fabrication).
   ========================================================================== */

:root {
  /* Clear Signal tokens (mirror apps/web/src/app/style.css — retheme 2026-08-17) */
  --neutral-1: #fafbfc; --neutral-2: #f5f6f8; --neutral-3: #f0f1f4; --neutral-4: #e9ebee;
  --neutral-5: #e3e6eb; --neutral-6: #d5d9de; --neutral-7: #c9ced6; --neutral-11: #636b78; --neutral-12: #16181d;
  --accent-2: #fff5ee; --accent-3: #feede1; --accent-4: #fde0cb; --accent-7: #f4a26b; --accent-9: #f4630f; --accent-11: #b8470a; --accent-12: #5a2303;
  --accent-on-solid: #16181d;
  --sand: #e3e6eb; --sand-soft: #f8f9fa; --sand-ink: #4b5563;
  --amber-3: #fef1d6; --amber-9: #f59e0b; --amber-11: #96470a;
  --success-3: #e7f6ec; --success-9: #22c55e; --success-11: #137a37;
  --error-3: #fee2e2; --error-11: #b91c1c;
  --info-3: #e0f2fe; --info-11: #0369a1;
  --grad-brand: linear-gradient(120deg, #ffb27a 0%, #f4630f 55%, #d95608 100%);
  --grad-cta: linear-gradient(135deg, #b8470a 0%, #ad4405 100%);
  --sand-mid: #eef0f3;
  --font-display: "Schibsted Grotesk", "Helvetica Neue", Helvetica, "Segoe UI", Arial, sans-serif;
  --font-body: "Schibsted Grotesk", "Helvetica Neue", Helvetica, "Segoe UI", Arial, sans-serif;
  --radius-sm: 8px; --radius: 12px; --radius-lg: 16px; --radius-badge: 10px; --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(22, 24, 29,.07); --shadow: 0 4px 16px rgba(22, 24, 29,.10); --shadow-lg: 0 12px 40px rgba(22, 24, 29,.18);
  --ease-out: cubic-bezier(0.16,1,0.3,1); --ease-spring: cubic-bezier(0.34,1.56,0.64,1);
  --background: var(--neutral-1); --surface: var(--neutral-2); --text: var(--neutral-12); --text-secondary: var(--neutral-11);
  --maxw: 1120px;
  --readw: 720px;   /* measure for long-form prose: ~72ch at 17px */
  --wrappad: 24px;  /* .wrap's side padding; the reading-column clamp below is derived from it */
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; font-family: var(--font-body); color: var(--text); background: var(--background);
  font-size: 16px; line-height: 1.6; font-weight: 450; -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.12; letter-spacing: -0.01em; margin: 0; }
p { margin: 0; }
a { color: var(--accent-11); text-decoration: none; }
a:hover { text-decoration: underline; }
img, svg { max-width: 100%; }
.num { font-variant-numeric: tabular-nums; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--wrappad); }

/* ── The reading column is CENTERED, not flush-left ──────────────────────────
   `.wrap` is --maxw (1120px) and centered, but every block inside .page-head and
   .article is clamped to --readw (720px). A block with a max-width and no auto
   side margins sits FLUSH LEFT, so the whole 400px surplus collected on the right
   and nothing ever occupied it: measured 2026-08-05 at a 1249px viewport, the text
   ran 88 -> 808 with 441px of dead space beside it, and at 1920px the column's
   centre sits 176px left of the page's. That was never a decision — no rule set it,
   and DESIGN.md's own wording for this case is "the centered max-width clamp".
   Every other long-form surface we own is balanced: a blog post pairs a 652px
   prose column with a 300px sticky TOC and centres the PAIR (gutters 269/268).

   So the clamp moves off the children and onto the wrap itself, which centres the
   column and leaves every left edge inside it aligned. ⛔ Do NOT instead put
   `margin-inline: auto` on the children: .page-head's children carry DIFFERENT
   caps (h1 19ch, .sub 56ch, .answer --readw), so centring each one independently
   ragged-edges the hero against the body copy.

   ⚠️ Scope is deliberate. Only .page-head/.article carry a reading measure, and
   they appear on exactly the 15 Tier-A/sub-pages. index.html (its own inline
   sheet), blog.html and blog/*.html (generated, own sheet + sidebar), and the bare
   legal pages are untouched, and the header, footer and .cta-band stay at --maxw
   on every page — a nav that narrowed with the prose would look broken beside a
   full-width hero. */
.page-head .wrap,
.article .wrap { max-width: calc(var(--readw) + var(--wrappad) * 2); }

/* Visible-on-focus skip link (the sub-pages are long-form; keyboard users
   should not have to tab the whole nav on every one). */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: #fff; color: var(--accent-11); font-weight: 600;
  padding: 12px 18px; border-radius: 0 0 var(--radius) 0; box-shadow: var(--shadow);
}
.skip:focus { left: 0; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600;
  letter-spacing: .02em; color: var(--accent-11); background: var(--accent-3);
  padding: 6px 12px; border-radius: 6px;
}
/* Freshness stamp — sits beside the .eyebrow pill on every indexed content page.
   The DATE IS NOT HAND-MAINTAINED: apps/landing/deploy.sh §1a rewrites every
   `data-lastmod` element (and the matching JSON-LD "dateModified") from the file's git
   commit date, the same source the sitemap <lastmod> already uses. So it moves when the
   page actually changes and never on a no-op redeploy. Reason it exists: <lastmod> is a
   crawler signal, but an answer engine reads the PAGE, and an undated page reads as stale
   to a retrieval layer that prefers recent sources. See docs/aeo-program.md. */
.stamp {
  display: inline-block; margin-left: 10px; font-size: 12px; color: var(--text-secondary);
  font-variant-numeric: tabular-nums; vertical-align: middle;
}

.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent-9); box-shadow: 0 0 0 4px rgba(252,112,0,.18); }

/* ============ Buttons (copied from index.html) ============ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer;
  font-family: var(--font-body); font-weight: 600; font-size: 15px; border: none; border-radius: var(--radius);
  padding: 12px 20px; transition: transform 200ms var(--ease-spring), box-shadow 200ms, background 200ms;
  white-space: nowrap;
}
.btn:active { transform: scale(.97); }
/* --grad-cta is the ONLY gradient allowed to carry white text (strict AA across
   every stop). --grad-brand is signal-only and takes dark text. See DESIGN.md. */
.btn-cta { background: var(--grad-cta); color: #fff; box-shadow: var(--shadow); }
.btn-cta:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); text-decoration: none; }
.btn-ghost { background: transparent; color: var(--text); border: 1px solid var(--neutral-6); }
.btn-ghost:hover { background: var(--surface); text-decoration: none; }
.btn-lg { padding: 15px 26px; font-size: 16px; }

/* ============ Header / footer (must match index.html exactly) ============ */
header.site {
  position: sticky; top: 0; z-index: 30; backdrop-filter: saturate(1.4) blur(10px);
  background: rgba(252,253,253,.82); border-bottom: 1px solid var(--neutral-4);
}
.navbar { display: flex; align-items: center; justify-content: space-between; height: 74px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 700; font-size: 19px; color: var(--text); }
.navbar .brand { font-size: 24px; gap: 12px; letter-spacing: -0.01em; }
.navbar .brand .mark { width: 40px; height: 40px; border-radius: 10px; }
.brand:hover { text-decoration: none; }
.brand .mark {
  width: 28px; height: 28px; border-radius: 8px;
  background: url("/brand-mark.png") center / cover no-repeat;
  box-shadow: var(--shadow-sm);
}
.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links a { color: var(--text-secondary); font-weight: 500; font-size: 15px; }
.nav-links a:hover { color: var(--text); text-decoration: none; }
.nav-links a[aria-current="page"] { color: var(--accent-11); font-weight: 600; }
.nav-links .btn { color: #fff; padding: 9px 16px; font-size: 14px; }
.nav-links .btn-ghost { color: var(--text); }
.nav-links .btn-ghost:hover { color: var(--text); }
@media (max-width: 860px) { .nav-links a:not(.btn) { display: none; } }
@media (max-width: 400px) { .nav-links { gap: 10px; } .nav-links .btn { padding: 8px 12px; } }

footer.site { border-top: 1px solid var(--neutral-4); background: var(--surface); padding: 34px 0; margin-top: 72px; }
.foot { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; font-size: 14px; color: var(--text-secondary); }
.foot-links { display: flex; gap: 20px; flex-wrap: wrap; }
.foot-links a { color: var(--text-secondary); }
.foot-links a:hover { color: var(--text); }
.foot-col-set { display: flex; gap: 56px; flex-wrap: wrap; }
.foot-col { display: flex; flex-direction: column; gap: 9px; }
.foot-col h4 { font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text); margin-bottom: 3px; }
.foot-col a { color: var(--text-secondary); font-size: 14px; }
.foot-col a:hover { color: var(--text); }

/* ============ Page head ============ */
.page-head { position: relative; overflow: hidden; padding: 56px 0 8px; }
/* ⛔ THE ORANGE BLUR BLOB IS GONE (design "5a Clean sheet", 2026-08-26). It used to sit at
   `inset: -46% -18% auto auto` behind the page head. Its whole job was to stop the empty
   right-hand gutter from reading as blank, and the redesign removes the cause instead: split
   heroes and full-bleed bands now occupy that space with something a reader wants. A wash
   behind body copy was decoration standing in for content, and the restraint rule in
   DESIGN.md is that orange marks the one thing that matters, never a surface.
   ⛔ Deleted, not overridden. An `::before { content: none }` somewhere else would leave the
   next person reading two rules to learn there is no blob. */
.page-head .wrap { position: relative; z-index: 1; }
/* ⚠️ No per-child max-width on these two any more. The 19ch/56ch caps predate the wrap
   clamp added above (.page-head .wrap = --readw): with both in force a long headline wrapped
   to five short lines with ~90px of dead space beside every one, and the .sub stopped ~120px
   short of the .answer block directly under it — measured on /tailoring and /ats-truth,
   2026-08-08. The wrap is now the only cap, which is what keeps h1, .sub, .answer and the
   article body sharing one left edge AND one right edge. 720px is ~25ch at the h1's clamp
   ceiling and ~67ch at the .sub's, both inside the comfortable measure, so nothing needs a
   second cap. ⛔ Do not reintroduce a `ch` cap here without re-measuring the longest hero
   on the 15 sub-pages. */
.page-head h1 { font-size: clamp(2.1rem, 4.4vw, 3.05rem); font-weight: 700; margin: 16px 0 0; }
.page-head .sub { font-size: clamp(1.04rem, 1.5vw, 1.2rem); color: var(--text-secondary); margin-top: 16px; }

.crumbs { font-size: 13px; color: var(--text-secondary); margin-bottom: 4px; }
.crumbs a { color: var(--text-secondary); }
.crumbs a:hover { color: var(--accent-11); }
.crumbs .sep { padding: 0 7px; color: var(--neutral-6); }

/* ---- The answer block.
   "Answer near the top" is the single highest-weight content factor in the AI
   citation data (8.8/10), and self-contained passages score 8.0: this block has
   to make sense quoted with zero surrounding context, so it never opens with
   "it" or "this" and always names JobShifu explicitly.
   Tinted region, NOT a left edge bar: one-sided colored strips are banned
   repo-wide (see the no-thin-accent-bars rule). ---- */
.answer {
  background: var(--accent-2); border: 1px solid var(--accent-4);
  border-radius: var(--radius-lg); padding: 24px 28px; margin: 34px 0 0; max-width: var(--readw);
}
.answer p { font-size: 1.09rem; line-height: 1.62; color: var(--accent-12); }
.answer p + p { margin-top: 12px; }
.answer strong { font-weight: 700; }

/* ============ Long-form article body ============ */
.article { padding: 8px 0 0; }
.article .wrap > * { max-width: var(--readw); }

/* ── Ads-LP breakout (opt-in via body.ads-lp; currently /tailoring and /ats-check) ──
   The paid LPs need their product blocks wider than the reading measure — that width
   is most of what separates "product page" from "article" feel (index.html runs its
   showcase blocks at 900-1120px). So on these pages only, .article's wrap returns to
   --maxw and every child self-clamps to --readw instead; a block marked .breakout
   runs to 900px. Every child carries margin-inline auto (the #300 flush-left trap);
   inside .article the non-breakout caps are uniform (--readw), so prose left edges
   stay aligned with each other — unlike .page-head, whose children carry DIFFERING
   caps (h1 19ch, .sub 56ch) and where per-child centring would ragged-edge the hero;
   .page-head therefore keeps the wrap-level clamp above, deliberately.
   ⛔ Do not widen --readw itself: the ~72ch prose measure is design law (DESIGN.md).
   ⛔ Rolling breakout out to a Tier-A page = adding body.ads-lp there, which is a
   deliberate per-page change with its own visual check, not a default.
   ⚠️ The clamp sits one level DOWN from the wrap: .wrap's direct children are the
   <section>s (and nav.related), so those span --maxw and it is THEIR children that
   self-clamp to --readw. A .breakout can sit at any depth under .article. */
body.ads-lp .article .wrap { max-width: var(--maxw); }
body.ads-lp .article .wrap > * { max-width: none; }
body.ads-lp .article section > *,
body.ads-lp .article .related > * { max-width: var(--readw); margin-inline: auto; }
/* (0,3,1) beats the section>* clamp's (0,2,2) by specificity, not by order. */
body.ads-lp .article .breakout { max-width: 900px; margin-inline: auto; }
.article section { margin-top: 56px; }
.article h2 {
  font-size: clamp(1.5rem, 2.5vw, 1.95rem); font-weight: 700; margin: 0 0 16px;
  scroll-margin-top: 92px;   /* sticky header clearance for #anchor deep links */
}
.article h3 { font-size: 1.16rem; font-weight: 700; margin: 30px 0 10px; }
.article p { font-size: 1.045rem; line-height: 1.72; }
.article p + p { margin-top: 15px; }
/* ⚠️ `p { margin: 0 }` is global and the rule above only fires BETWEEN paragraphs, so a
   paragraph following any OTHER block — a figure, a card grid, a table wrapper, a list —
   had a 0px top margin and sat glued to it. Measured 2026-08-08 on 12 of the 19 pages
   that load this sheet (figcaption → next p on /tailoring, /ats-check, /ats-truth;
   .cards/.table-scroll/ul → p on nine more).
   Scope is deliberate: only UNCLASSED paragraphs, so .claim (26px), .lead, .mid-cta and
   .crumbs keep their own margins, and headings are excluded because h2/h3 already carry
   a margin-bottom. Blocks with their own margin-bottom (e.g. .shot) collapse against
   this and keep the larger value. */
.article :is(section, .wrap) > :not(h1, h2, h3, h4) + p:not([class]) { margin-top: 15px; }
/* ⚠️ `.muted` is the one CLASSED paragraph the scope above excludes that has no margin of
   its own to keep, so it fell through the crack the rule was written to close: measured
   2026-08-27 sitting flush on the table above it on /research/relisting. */
.article :is(section, .wrap) > :not(h1, h2, h3, h4) + p.muted { margin-top: 15px; }
.article ul, .article ol { margin: 15px 0 0; padding-left: 22px; }
.article li { font-size: 1.045rem; line-height: 1.68; margin-top: 9px; }
.article li strong { font-weight: 700; }
.article .lead { font-size: 1.1rem; color: var(--text-secondary); }

/* Pull-quote style statement line. Used sparingly: one per page at most. */
.claim {
  font-family: var(--font-display); font-size: clamp(1.22rem, 2.1vw, 1.5rem); font-weight: 700;
  line-height: 1.32; letter-spacing: -0.015em; color: var(--accent-12);
  margin: 26px 0; padding: 20px 24px; background: var(--sand-soft); border-radius: var(--radius-lg);
}

/* Step list */
.steps { counter-reset: step; margin: 22px 0 0; padding: 0; list-style: none; }
.steps li { position: relative; padding-left: 46px; margin-top: 20px; }
.steps li::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 1px; width: 30px; height: 30px; border-radius: 9px;
  background: var(--accent-3); color: var(--accent-11); font-family: var(--font-display);
  font-weight: 700; font-size: 14px; display: flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.steps li h3 { margin: 0 0 5px; font-size: 1.08rem; }

/* Card grid */
.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin: 24px 0 0; max-width: var(--readw); }
.card { background: #fff; border: 1px solid var(--neutral-4); border-radius: var(--radius-lg); padding: 20px 22px; box-shadow: var(--shadow-sm); }
.card h3 { margin: 0 0 8px; font-size: 1.05rem; }
.card p { font-size: .975rem; color: var(--text-secondary); line-height: 1.6; }
@media (max-width: 700px) { .cards { grid-template-columns: 1fr; } }

/* Comparison table. Wide content scrolls in its own container so the page body
   never scrolls horizontally on a phone. */
.table-scroll { overflow-x: auto; margin: 24px 0 0; max-width: var(--readw); -webkit-overflow-scrolling: touch; }
table.cmp { border-collapse: collapse; width: 100%; min-width: 520px; font-size: .975rem; }
table.cmp th, table.cmp td { text-align: left; padding: 13px 16px; border-bottom: 1px solid var(--neutral-4); vertical-align: top; }
table.cmp thead th { font-family: var(--font-display); font-weight: 700; font-size: .85rem; letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); background: var(--neutral-3); }
table.cmp thead th:first-child { border-radius: var(--radius-sm) 0 0 0; }
table.cmp thead th:last-child { border-radius: 0 var(--radius-sm) 0 0; }
table.cmp tbody tr:last-child td { border-bottom: none; }
table.cmp td:first-child { font-weight: 600; }

/* Inline "no source, no line" style code/label chip */
.chip {
  display: inline-block; font-size: .82rem; font-weight: 600; padding: 3px 9px; border-radius: 6px;
  background: var(--neutral-3); color: var(--text-secondary); white-space: nowrap;
}
.chip.ok { background: var(--success-3); color: var(--success-11); }
.chip.no { background: var(--error-3); color: var(--error-11); }
.chip.warn { background: var(--amber-3); color: var(--amber-11); }

/* ============ FAQ ============
   Rendered as <details> so every answer is in the DOM at load. An extractor
   that never fires a click still reads the full text, which is the entire point
   of shipping FAQ content at all. Do not convert these to JS-toggled panels. */
.faq { max-width: var(--readw); margin-top: 22px; }
.faq-item { border: 1px solid var(--neutral-4); border-radius: var(--radius); background: #fff; margin-top: 10px; overflow: hidden; }
.faq-item > summary {
  cursor: pointer; list-style: none; padding: 16px 46px 16px 20px; position: relative;
  font-family: var(--font-display); font-weight: 600; font-size: 1.03rem; color: var(--text);
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: ""; position: absolute; right: 20px; top: 50%; width: 9px; height: 9px;
  border-right: 2px solid var(--text-secondary); border-bottom: 2px solid var(--text-secondary);
  transform: translateY(-70%) rotate(45deg); transition: transform 200ms var(--ease-out);
}
.faq-item[open] > summary::after { transform: translateY(-30%) rotate(225deg); }
.faq-item > summary:hover { background: var(--neutral-2); }
.faq-item > summary:focus-visible { outline: 2px solid var(--accent-9); outline-offset: -2px; }
.faq-item .a { padding: 0 20px 18px; }
.faq-item .a p { font-size: 1.0rem; line-height: 1.68; color: var(--text-secondary); }
.faq-item .a p + p { margin-top: 11px; }

/* ============ Related links (internal linking is how the new pages get
   discovered at all: index.html linked nothing but /privacy and /terms) ====== */
.related { margin-top: 56px; max-width: var(--readw); }
.related h2 { font-size: 1.25rem; margin-bottom: 14px; }
.rel-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.rel-grid a {
  display: block; padding: 15px 18px; border: 1px solid var(--neutral-4); border-radius: var(--radius);
  background: #fff; color: var(--text); font-weight: 600; font-size: .98rem;
  transition: border-color 180ms, transform 180ms var(--ease-out);
}
.rel-grid a:hover { text-decoration: none; border-color: var(--accent-7); transform: translateY(-1px); }
.rel-grid a span { display: block; font-weight: 450; font-size: .9rem; color: var(--text-secondary); margin-top: 4px; line-height: 1.5; }
@media (max-width: 700px) { .rel-grid { grid-template-columns: 1fr; } }

/* ============ Product UI, REPRODUCED in markup (not screenshotted) ============
   Used by /tailoring and /ats-truth to show real app surfaces: the tailor's change
   cards, the keyword read-out, the requirements panel, the vault-growth bar.

   WHY MARKUP AND NOT A PNG. The product captures we have are 1x (the widest is
   1426px). A crop of one lands in a 720px column, which needs 1440 device pixels on
   a 2x display and has ~830 — so it rendered at roughly 0.58x and read as visibly
   soft, which on a page arguing for precision is the wrong impression. Re-shooting at
   2x was not available (it needs that exact demo vault state back), and upscaling a
   1x PNG invents detail. Markup is resolution-independent by construction, it reflows
   on a phone instead of shrinking to illegibility, and the numbers become real text a
   screen reader can read rather than alt-text approximating them.

   ⚠️ THE COST, AND IT IS REAL: this is now a DRIFT SURFACE. A screenshot rots
   visibly; a reproduction rots silently and keeps looking authoritative. The strings
   and numbers below are copied from real captures of the app
   (assets/screenshots/ui-*.png, which stay in the repo as the reference). If a
   surface changes materially, update these or drop them. ⛔ Never invent a number or
   a state the product cannot produce: the whole argument of both pages is that the
   product shows you the real read, and a flattering mock would be the exact failure
   they are written against.

   ⛔ These are NOT captioned as screenshots anywhere, and must not be. */
.article .ui :where(p, ul, ol, li) { font: inherit; margin: 0; padding: 0; }
.article .ui :where(ul, ol) { list-style: none; }
.ui {
  margin: 26px 0 0; padding: 16px;
  background: var(--neutral-3); border: 1px solid var(--neutral-5); border-radius: var(--radius-lg);
  font-size: 14px; line-height: 1.45; color: var(--text);
}
.ui--rail { max-width: 372px; margin-inline: auto; }
.ui .ui-panel { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius); padding: 14px 16px; }
.ui .ui-panel + .ui-panel { margin-top: 10px; }
.ui .ui-label { font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-secondary); }

/* — the tailor's proposed-change card — */
.ui .ui-card { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius); padding: 13px 14px; }
.ui .ui-card + .ui-card { margin-top: 12px; }
.ui .ui-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 9px; }
.ui .ui-badge {
  display: inline-block; padding: 2px 11px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600; color: #fff; background: var(--neutral-11);
}
.ui .ui-badge--add { background: var(--success-11); }
.ui .ui-chk { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); }
.ui .ui-chk::before {
  content: "\2713"; display: grid; place-items: center; width: 15px; height: 15px;
  border-radius: 3px; background: #b8470a; color: #fff; font-size: 11px; line-height: 1;
}
.ui .ui-headline { font-weight: 600; margin: 0 0 9px; }
.ui .ui-match { color: #b8470a; font-weight: 700; font-size: 13px; margin: 0 0 3px; }
.ui .ui-match-list { margin: 0 0 4px; padding-left: 16px; list-style: disc; color: #b8470a; }
.ui .ui-match-list li { font-size: 13px; line-height: 1.45; margin: 2px 0; color: var(--accent-11); }
.ui .ui-more { font-size: 12.5px; color: var(--accent-11); text-decoration: underline; }
.ui .ui-field {
  margin: 5px 0 10px; padding: 9px 10px; border: 1px solid var(--neutral-6); border-radius: var(--radius-sm);
  background: #fff; font-size: 13px; line-height: 1.5;
}
.ui .ui-grounded { display: flex; align-items: center; gap: 9px; font-size: 12.5px; }
.ui .ui-grounded b { color: var(--success-11); font-weight: 700; }
.ui .ui-grounded a, .ui .ui-grounded span.lnk { color: var(--accent-11); text-decoration: underline; }

/* — the submit-verdict stat row — */
.ui .ui-stats { display: grid; grid-template-columns: repeat(3, 1fr); }
.ui .ui-stat { padding: 2px 16px; border-left: 1px solid var(--neutral-4); }
.ui .ui-stat:first-child { border-left: 0; padding-left: 2px; }
.ui .ui-stat b { display: block; margin-top: 4px; font-size: 15px; font-weight: 700; }
.ui .ui-stat .sub { margin-top: 3px; font-size: 11.5px; color: var(--text-secondary); }
.ui .ui-stat .warn { color: var(--amber-11); }
@media (max-width: 560px) {
.ui .ui-stats { grid-template-columns: 1fr; gap: 12px; }
.ui .ui-stat { border-left: 0; border-top: 1px solid var(--neutral-4); padding: 10px 2px 0; }
.ui .ui-stat:first-child { border-top: 0; padding-top: 2px; }
}

/* — the vault-growth bar — */
.ui .ui-lvl-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ui .ui-lvl-top b { color: #b8470a; font-size: 15px; }
.ui .ui-pill { font-size: 11.5px; padding: 2px 9px; border-radius: var(--radius-pill); background: var(--success-3); color: var(--success-11); font-weight: 600; }
.ui .ui-lvl-sub { color: var(--text-secondary); font-size: 13px; margin-top: 2px; }
.ui .ui-meter-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 4px; }
.ui .ui-meter-row .val { white-space: nowrap; font-size: 13px; color: var(--text-secondary); }
.ui .ui-meter-row .val b { color: #b8470a; }
.ui .ui-meter-row .val .dn { color: var(--error-11); }
.ui .ui-meter { height: 7px; border-radius: 4px; background: var(--neutral-4); margin-top: 7px; overflow: hidden; }
.ui .ui-meter i { display: block; height: 100%; background: var(--success-11); }

/* — the requirements / domain read-out — */
.ui .ui-row { display: grid; grid-template-columns: 172px 1fr; gap: 10px; align-items: start; }
.ui .ui-row + .ui-row { margin-top: 8px; }
.ui .ui-row > .k { color: var(--text); font-weight: 600; font-size: 13px; padding-top: 2px; }
.ui .ui-row > .k .mini { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 700; color: var(--amber-11); background: var(--amber-3); border-radius: var(--radius-pill); padding: 1px 7px; }
.ui .ui-two { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ui .ui-box { border: 1px solid var(--neutral-5); border-radius: var(--radius-sm); padding: 7px 10px; font-size: 13px; background: #fff; }
.ui .ui-verdict { font-weight: 700; margin-bottom: 5px; }
.ui .ui-notes { margin: 0; padding-left: 16px; list-style: disc; color: var(--text-secondary); font-size: 12.5px; }
.ui .ui-notes li { margin: 3px 0; line-height: 1.45; }
.ui .ui-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 5px; }
.ui .ui-chip { font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: var(--radius-pill); background: var(--success-11); color: #fff; }
.ui .ui-chip span { font-weight: 450; opacity: .85; }
.ui .ui-chip--miss { background: #fff; color: var(--text-secondary); border: 1px solid var(--neutral-6); font-weight: 450; }
@media (max-width: 620px) {
.ui .ui-row { grid-template-columns: 1fr; gap: 4px; }
.ui .ui-two { grid-template-columns: 1fr; }
}

/* ============ CTA button rows ============
   `.launch-cta` was used by ten pages that load this sheet but was only ever DEFINED
   in index.html's and 404.html's own inline sheets — so everywhere else the div fell
   back to plain inline-block flow: the buttons sat flush against the block above them
   with only a whitespace gap between each other. The base rule below matches the
   values index.html already used; .cta-band's variant still overrides it (centred). */
.launch-cta { display: flex; gap: 12px; margin-top: 28px; flex-wrap: wrap; }

/* ============ Closing CTA band ============ */
.cta-band { margin-top: 68px; padding: 52px 0; background: var(--sand-soft); text-align: center; }
.cta-band h2 { font-size: clamp(1.6rem, 3vw, 2.15rem); font-weight: 700; }
.cta-band p { margin: 14px auto 0; max-width: 52ch; color: var(--sand-ink); font-size: 1.05rem; }
.cta-band .launch-cta { display: flex; gap: 12px; margin-top: 26px; justify-content: center; flex-wrap: wrap; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ⚠️ QUIET LINKS INSIDE THE ANSWER BLOCK (2026-08-26). The BLUF card is the passage answer
   engines lift and the highest-weight editorial link position on the page, so it carries one
   link. Styled as the site's standard orange, that link put a spot of colour in the middle of
   the bolded lead sentence and changed how the card reads: measured before/after, it was the
   only visible difference the whole internal-linking pass produced.
   So links here inherit the ink and carry a tinted underline instead. Still a real <a>, still
   crawled, still keyboard-reachable, still obviously a link on hover. ⛔ Do not "fix" this by
   removing the underline: a link with no affordance at all is a different problem. */
.answer a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--accent-7);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.answer a:hover, .answer a:focus-visible { color: var(--accent-11); text-decoration-color: currentColor; }


/* ============ Motion ==========================================================
   ⭐ PORTED VERBATIM FROM index.html (2026-08-26). Before this, `.reveal` appeared 14 times
   on the homepage and ZERO times on any other page: the signature scroll-in of this brand
   existed on exactly one surface. The keyframes, the `html.anim` gate, the reduced-motion
   kill and the noscript override are the homepage's, unchanged, so the two can never drift
   into two dialects of the same motion.

   ⛔ THE THREE SAFETY NETS ARE NOT OPTIONAL and all three already exist upstream:
     1. `html.anim` — the class is set by JS. No-JS and no-IntersectionObserver visitors
        never enter an animated state at all.
     2. `prefers-reduced-motion` — kills every transition and animation outright.
     3. `<noscript>` — each page carries an inline override painting `.reveal` opaque.
   `.reveal` animates OPACITY and TRANSFORM only, never `display`, so all copy is in the
   initial HTML and crawlers and assistive tech see the whole page regardless.

   ⚠️ Scope: every `h2`-led section and every `.band` gets `.reveal`. Nothing else
   scroll-animates. A page where everything moves reads as a page where nothing matters. */
@keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes pop  { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }

.reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s var(--ease-out), transform .6s var(--ease-out); }
.reveal.in { opacity: 1; transform: none; }
/* ⛔ Until JS adds `.anim` to <html>, nothing is hidden. This is the gate that makes a failed
   or blocked script a non-event rather than a blank page. */
html:not(.anim) .reveal { opacity: 1; transform: none; transition: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .band [data-demo], .band [data-demo] * { animation: none !important; transition: none !important; }
}

/* ============ Bands ===========================================================
   The unit of the "1b Banded" redesign. A band is a full-bleed <section> BETWEEN prose
   sections: it carries the demo, the data figure or the comparison that used to be described
   in a paragraph.

   ⛔ TWO RULES THAT KEEP THE READING SURFACE INTACT, and they are the reason this direction
   was chosen over widening the prose:
     1. Prose never leaves the 720px column. `.article .wrap` is untouched by everything here.
     2. A band never sits INSIDE a section. It is a sibling of `.article`, full-bleed, so it
        cannot inherit the reading clamp and cannot push the measure around.
   Bands alternate ground so the page gains the rhythm the audit measured as missing: the
   homepage has three band changes down its length, the sub-pages had one (the CTA). */
.band { padding: 64px 0; background: var(--surface); border-top: 1px solid var(--neutral-4); border-bottom: 1px solid var(--neutral-4); }
.band--white { background: #fff; }
.band > .wrap { max-width: var(--maxw); }
.band-head { max-width: 62ch; margin: 0 0 28px; }
.band-head h2 { font-size: clamp(1.45rem, 2.3vw, 1.8rem); font-weight: 700; margin: 0 0 8px; }
.band-head p { color: var(--text-secondary); margin: 0; }
/* ⚠️ The same `p { margin: 0 }` defect the .article block above documents, one container
   over. `.band > .wrap` carries prose on the Tier-A pages and nothing ever gave it rhythm,
   so consecutive paragraphs rendered at a 0px gap and an <h3> sat flush on the paragraph
   above it. Measured 2026-08-27 in Mobile Safari on /autofill (4), /resume-tailoring (3),
   /visa-sponsorship (2) and /cover-letters (1). Not a phone-only bug, it is wrong at every
   width, but a phone is where two merged paragraphs actually stop being readable.
   `.band-head` is deliberately untouched: it is a child container with its own margins and
   its eyebrow-over-heading pair is meant to be tight. Same scoping rule as .article,
   unclassed paragraphs only, so .lead / .muted / .band-note keep their own spacing. */
.band > .wrap > :not(h1, h2, h3, h4) + p:not([class]) { margin-top: 15px; }
.band > .wrap > * + :is(h3, h4) { margin-top: 30px; }
.band > .wrap > :is(h3, h4) + p:not([class]) { margin-top: 10px; }
/* The homepage `.ptf` proportions, so a band beside a media plate reads as the same object
   the reader already met on the hero page. */
.band-rail { display: grid; grid-template-columns: minmax(280px, .74fr) 1.26fr; gap: 52px; align-items: center; }
.band-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
.band-note { margin: 22px 0 0; font-size: .86rem; color: var(--text-secondary); }
@media (max-width: 900px) { .band-rail { grid-template-columns: 1fr; gap: 28px; } .band { padding: 48px 0; } }

/* ============ Split hero ======================================================
   Opt-in per page (`.page-head--split`), for pages whose subject is an object worth drawing:
   a score ring, a live counter, a board. It widens ONLY the head's wrap; the article below
   keeps its 720px measure, so the page opens wide and then settles into reading width.
   ⚠️ `--plate` is set per page in that page's inline sheet (400–560px in the artboards). */
.page-head--split .wrap { max-width: var(--maxw); }
.page-head--split .head-split { display: grid; grid-template-columns: minmax(0, 1fr) var(--plate, 440px); gap: 52px; align-items: center; }
.page-head--split .head-copy > .answer { margin-right: 0; }
.plate { position: relative; background: var(--neutral-2); border: 1px solid var(--neutral-4); border-radius: 20px; padding: 26px; display: grid; place-items: center; }
@media (max-width: 900px) {
  .page-head--split .head-split { grid-template-columns: 1fr; gap: 28px; }
  .page-head--split .wrap { max-width: calc(var(--readw) + var(--wrappad) * 2); }
}

/* Replay control for a demo that has played once. */
.replay { margin: 16px 0 0; }

/* ── Band cards: a card whose subject is a NUMBER ───────────────────────────────
   The prose version of these was four unlabelled description cards, which made the page
   assert that its sub-scores are commensurable without ever showing them side by side.
   ⚠️ `.sub-num--off` is the load-bearing one: a dropped input has to read as *deliberately
   absent*, not as a zero and not as a blank. The dashed border and the word "dropped" are
   the page's own argument ("a missing input is excluded, never guessed") made visible. */
.sub-card { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius-lg); padding: 18px 20px; }
.sub-card p { margin: 8px 0 0; font-size: .92rem; line-height: 1.55; color: var(--text-secondary); }
.sub-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.sub-top h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.sub-num { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; color: var(--accent-11); line-height: 1; }
.sub-num small { font-size: .72em; font-weight: 700; margin-left: 1px; }
.sub-card--dropped { border-style: dashed; border-color: var(--neutral-6); background: var(--neutral-2); }
.sub-num--off { font-size: .95rem; font-weight: 700; color: var(--text-secondary); letter-spacing: 0; }

/* A rail whose two halves are closer to equal than the .74/1.26 copy-rail split: used when
   both sides are figures (a table beside a chart) rather than copy beside a plate. */
.band-rail--wide { grid-template-columns: 1.15fr .85fr; align-items: start; }
@media (max-width: 900px) { .band-rail--wide { grid-template-columns: 1fr; } }

/* ── Hero ring plate (fit-score) ────────────────────────────────────────────────
   Drawn AT REST, no animation. The animated pair lives in the band further down the page;
   two moving dials on one page is noise, and the hero's job is to show what the number looks
   like, not to perform. Authored finished, so no-JS and crawlers see the same thing. */
.hero-ring { aspect-ratio: 4 / 5; gap: 0; align-content: center; }
.hr-dial { position: relative; width: 132px; height: 132px; }
.hr-dial svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.hr-track { fill: none; stroke: var(--neutral-4); stroke-width: 8; }
.hr-arc { fill: none; stroke: url(#heroFitGrad); stroke-width: 8; stroke-linecap: round; }
.hr-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 2rem; font-weight: 800; letter-spacing: -.02em; }
.hr-num small { font-size: .5em; font-weight: 700; }
.hr-label { margin-top: 14px; font-size: .78rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.hr-cap { margin-top: 4px; font-size: .84rem; color: var(--text-secondary); }
.hr-chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 18px; }
.hr-foot { margin: 16px 0 0; font-size: .8rem; line-height: 1.5; color: var(--text-secondary); text-align: center; max-width: 30ch; }

/* ── Check cards (calibration) ──────────────────────────────────────────────────
   ⛔ The visual inequality IS the content. One blocking check gets an error border and a
   solid chip; the six warns are uniform and quiet; the advisory is quieter still. If a future
   check graduates from warn to block, it moves to .chk--block here in the same PR that
   changes calibration.ts, or the page lies by omission. */
.chk { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius); padding: 16px 18px; }
.chk p { margin: 8px 0 0; font-size: .88rem; line-height: 1.5; color: var(--text-secondary); }
.chk-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.chk-top h3 { margin: 0; font-size: .98rem; font-weight: 700; }
.chk--block { border: 2px solid var(--error-11); background: var(--error-3); grid-column: span 2; }
.chk--block p { color: var(--text); }
.chk--info { background: var(--neutral-2); }
@media (max-width: 700px) { .chk--block { grid-column: span 1; } }

/* ── Plan grid (pricing) ────────────────────────────────────────────────────────
   ⛔ The FREE tile spans two columns and carries the accent tint. That is a positioning
   decision, not decoration: this product's free tier is unusually complete (unlimited
   autofill/matching/tracking, 2 tailored resumes a DAY) and burying it under the paid
   cadences would misrepresent the offer.
   ⛔ NEVER add a countdown, a struck-through anchor price or an "ends tonight" ribbon here.
   The copy in this band promises their absence; a design that reintroduced them would make
   the page call itself a liar, and it is a standing brand rule besides. */
.plan-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; align-items: start; }
.plan { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius-lg); padding: 20px; }
.plan-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.plan-top h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.plan-price { font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em; }
.plan-price small { display: block; font-size: .62em; font-weight: 500; color: var(--text-secondary); letter-spacing: 0; }
.plan-sub { margin: 10px 0 0; font-size: .88rem; line-height: 1.5; color: var(--text-secondary); }
.plan-list { margin: 14px 0 0; padding-left: 18px; font-size: .9rem; line-height: 1.7; color: var(--text); }
.plan--free { grid-column: span 2; background: var(--accent-2); border-color: var(--accent-4); }
.plan--best { border-color: var(--accent-9); box-shadow: var(--shadow-sm); }
.plan--pass { border-style: dashed; background: var(--sand-soft); }
.no-timers { font-weight: 600; color: var(--text); }
@media (max-width: 900px) { .plan-grid { grid-template-columns: repeat(2, 1fr); } .plan--free { grid-column: span 2; } }
@media (max-width: 560px) { .plan-grid { grid-template-columns: 1fr; } .plan--free { grid-column: span 1; } }

/* ── Outcome cards (job-tracker) ────────────────────────────────────────────────
   Ghosted and Accepted carry their own colour because the page's whole argument is that they
   are NOT interchangeable with the other two. Uniform styling here would undo the point. */
.oc { background: #fff; border: 1px solid var(--neutral-5); border-radius: var(--radius); padding: 16px 18px; }
.oc h3 { margin: 0 0 6px; font-size: 1rem; font-weight: 700; }
.oc p { margin: 0; font-size: .89rem; line-height: 1.55; color: var(--text-secondary); }
.oc--ghost { border-color: var(--amber-9); background: var(--amber-3); }
.oc--ghost p, .oc--win p { color: var(--text); }
.oc--win { border-color: var(--success-9); background: var(--success-3); }

/* ── Tag definitions (fresh) ────────────────────────────────────────────────────*/
.tagdef { background: var(--neutral-2); border: 1px solid var(--neutral-4); border-radius: var(--radius); padding: 16px 18px; }
.tagdef p { margin: 10px 0 0; font-size: .88rem; line-height: 1.55; color: var(--text-secondary); }

/* ── Timeline (ats-truth) ───────────────────────────────────────────────────────
   A claim -> source -> date chain is this page's actual product, so it is drawn rather than
   described. ⚠️ Tone: this is a correction, not a campaign. No alarm colours; the "now" step
   is marked with the accent because it is the surprising one (the figure outlived the company
   by 13 years), not because it is a threat. */
.tl { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 0; max-width: 760px; }
.tl-i { position: relative; padding: 0 0 24px 34px; border-left: 2px solid var(--neutral-5); }
.tl-i:last-child { padding-bottom: 0; border-left-color: transparent; }
.tl-i::before { content: ""; position: absolute; left: -7px; top: 4px; width: 12px; height: 12px; border-radius: 50%; background: var(--neutral-6); }
.tl-i--now::before { background: var(--accent-9); box-shadow: 0 0 0 4px var(--accent-3); }
.tl-y { display: block; font-size: .78rem; font-weight: 800; letter-spacing: .08em; color: var(--text-secondary); }
.tl-i--now .tl-y { color: var(--accent-11); }
.tl-i p { margin: 5px 0 0; font-size: .95rem; line-height: 1.6; }

/* ── Sponsorship bars (visa-sponsorship hero plate) ─────────────────────────────
   ⛔ THE BARS ARE NOT TO SCALE WITH EACH OTHER, deliberately, and the aria-label carries the
   real figures so the honest version is what assistive tech and any crawler receive. At true
   scale (97% / 2.3% / 0.3%) the two non-silent bars are invisible, which would hide the
   comparison the panel exists to make. The NUMBERS beside each bar are exact and are the
   claim; the bars are a legend, not a measurement.
   ⚠️ Figures come from the committed snapshot research/data/visa-sponsorship.json. If that is
   regenerated, these change in the same PR or the page cites a number the dataset denies. */
.sp-plate { display: block; text-align: left; }
.sp-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-secondary); margin: 0 0 14px; }
.sp-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.sp-bars li { display: grid; grid-template-columns: 1fr; gap: 4px; }
.sp-k { font-size: .84rem; color: var(--text-secondary); }
.sp-bars b { font-size: 1.05rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.sp-bar { display: block; height: 8px; border-radius: 999px; background: var(--neutral-4); overflow: hidden; }
.sp-bar i { display: block; height: 100%; border-radius: 999px; background: var(--neutral-7); }
.sp-bar--no i { background: var(--error-11); }
.sp-bar--yes i { background: var(--success-9); }
.sp-note { margin: 16px 0 0; font-size: .9rem; line-height: 1.55; }
.sp-foot { margin: 12px 0 0; font-size: .78rem; line-height: 1.5; color: var(--text-secondary); }
