:root {
  --bg: #f7f9fc;
  --bg-alt: #ffffff;
  --panel: #ffffff;
  --panel-2: #f1f5fb;
  --text: #0a1730;
  --text-soft: #2f3f5c;
  --muted: #61708c;
  --accent: #2457e6;
  --accent-dark: #1a3fb0;
  --accent-soft: #e8eefd;
  --ink-deep: #0a1730;
  --ink-mid: #12305e;
  --sg-red: #e0301e;
  --good: #0b7a45;
  --warn: #9a5b00;
  --bad: #c0261a;
  --border: #e2e8f2;
  --border-strong: #cbd6e6;
  --radius: 16px;
  --radius-sm: 11px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  --shadow: 0 1px 2px rgba(13, 27, 46, 0.05), 0 8px 24px rgba(13, 27, 46, 0.06);
  --shadow-lg: 0 2px 6px rgba(10, 23, 48, 0.06), 0 22px 50px rgba(10, 23, 48, 0.11);
}

* { box-sizing: border-box; }
/* The header is sticky at 74px, so anchored sections need to stop clear of it instead of sliding
   under it. The offset is reduced at the small-screen breakpoint, where the header stops sticking.
   The scrollbar gutter is reserved on every page, so a short page and a long one put the header in
   the same place instead of shifting the centred content by half a scrollbar when you move between them. */
html { scroll-behavior: smooth; scroll-padding-top: 90px; scrollbar-gutter: stable; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 22px; }
/* Deprecated. Every page now shares one container width, so a section's content lines up with the
   header and with every other page instead of being inset by a different amount. */
.narrow { max-width: 1120px; }

/* Account area: a small sidebar, so the pages that belong to an account read as a workspace rather
   than as one long scroll of panels. */
.account-layout { display: grid; grid-template-columns: 216px 1fr; gap: 26px; align-items: start; }
.account-nav {
  position: sticky; top: 96px; display: flex; flex-direction: column; gap: 2px; padding: 10px;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
}
.account-nav a { padding: 9px 11px; border-radius: 8px; font-size: 14px; color: var(--text-soft); text-decoration: none; white-space: nowrap; }
.account-nav a:hover { background: var(--accent-soft); color: var(--accent); text-decoration: none; }

/* Report identity, at the top where it can be seen and copied. */
.report-meta {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between;
  padding: 12px 16px; margin-bottom: 18px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--panel); box-shadow: var(--shadow);
}
.report-meta code { font-size: 13px; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { line-height: 1.2; margin: 0 0 14px; color: var(--text); }
h1 { font-size: 48px; letter-spacing: -1.2px; line-height: 1.12; }
h2 { font-size: 30px; letter-spacing: -0.6px; }
h3 { font-size: 19px; letter-spacing: -0.2px; }
p { margin: 0 0 14px; }
strong { color: var(--text); }

/* ---------------- header ---------------- */
.site-header {
  background: rgba(255,255,255,0.92);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
  backdrop-filter: blur(10px);
  box-shadow: 0 1px 0 rgba(10, 23, 48, 0.03), 0 8px 24px rgba(10, 23, 48, 0.04);
}
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; height: 74px; gap: 24px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 700; font-size: 18.5px; letter-spacing: -0.3px; color: var(--text); text-decoration: none; white-space: nowrap; }
.brand:hover { color: var(--accent); text-decoration: none; }
.brand img { width: 34px; height: 34px; display: block; }
.nav-wrap { display: flex; align-items: center; gap: 18px; min-width: 0; }
.tag {
  font-size: 10px; font-weight: 700; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 8px; margin-left: 2px;
  text-transform: uppercase; letter-spacing: 0.7px;
}
nav.main { display: flex; align-items: center; gap: 1px; flex-wrap: nowrap; }
nav.main a { color: var(--text-soft); text-decoration: none; font-size: 14px; padding: 8px 10px; border-radius: 8px; white-space: nowrap; }
nav.main a:hover { color: var(--accent); background: var(--accent-soft); text-decoration: none; }
/* The current page is marked with colour and a soft pill. It is deliberately not made bold: a heavier
   weight is a few pixels wider, which moved the whole nav group every time a page with an active item
   was opened next to one without. */
nav.main a.active { color: var(--accent); background: var(--accent-soft); }

/* Grouped navigation. Three menus instead of seven loose links, so the header says what the product
   does rather than listing every page in it. */
.nav-group { position: relative; }
.nav-group > a { display: inline-flex; align-items: center; gap: 5px; }
.caret { font-size: 9px; opacity: 0.55; line-height: 1; }
.nav-menu {
  position: absolute; top: 100%; left: 0; min-width: 224px; z-index: 40;
  display: none; flex-direction: column; gap: 2px; padding: 10px 8px 8px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
  /* The platform menu carries seventeen entries. On a short window it used to run past the bottom of
     the screen, so it now scrolls inside itself rather than being cut off. */
  max-height: calc(100vh - 104px); overflow-y: auto; overscroll-behavior: contain;
}
.nav-group:hover .nav-menu, .nav-group:focus-within .nav-menu { display: flex; }
.nav-menu a { font-size: 13.5px; padding: 7px 10px; }
/* A grouped menu, so eleven platform capabilities read as four ideas rather than a wall of links. */
.nav-menu.wide { min-width: 286px; }
.nav-menu .group-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase;
  color: var(--muted); padding: 9px 10px 3px;
}
.nav-menu .group-label:first-child { padding-top: 2px; }

/* Entries that only exist for a signed in account. Hidden until the session is confirmed. */
.signed-in-only { display: none; }
body.authed .signed-in-only { display: block; }

/* The one action the site wants a visitor to take, visible without opening a menu. */
nav.main a.nav-cta {
  background: var(--accent); color: #fff; font-weight: 600; margin-left: 6px;
}
nav.main a.nav-cta:hover { background: var(--accent-dark); color: #fff; }

/* The menu button exists only on small screens; on a wide screen the grouped menus are always there. */
.nav-toggle {
  display: none; align-items: center; gap: 8px; background: var(--panel); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 9px 14px; font-weight: 600;
}
.nav-toggle:hover { background: var(--panel-2); box-shadow: none; }
.nav-toggle .bars { display: inline-flex; flex-direction: column; gap: 3px; }
.nav-toggle .bars i { display: block; width: 16px; height: 2px; background: var(--text); border-radius: 2px; }

.chips { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 0; }
.verdict-chip {
  display: inline-flex; align-items: center; gap: 8px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 999px; padding: 8px 14px; background: var(--panel);
}
.verdict-chip.ok { border-color: #b6e2cd; background: #f0faf4; color: #0b6b40; }
.verdict-chip.bad { border-color: #f4c3bb; background: #fdf3f1; color: #a3211a; }
.verified-strip {
  margin-top: 16px; padding: 14px; border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm); background: linear-gradient(135deg, #fbfdff 0%, #f4f8ff 100%);
}
.verified-strip code { font-size: 12px; }

/* Evidence sits on its own full width row beneath the algorithm it belongs to. */
.data tr.evidence-row > td { background: var(--panel-2); border-top: 0; padding-top: 2px; }
.data tr.evidence-row summary { cursor: pointer; font-size: 13px; color: var(--muted); }
.data tr.evidence-row summary:hover { color: var(--accent); }

/* The cryptographic map. */
.map-wrap { margin-top: 14px; background: linear-gradient(180deg, #fbfdff, #f4f8ff); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.map-wrap svg { display: block; width: 100%; height: auto; }
.map-node { cursor: pointer; }
.map-node circle { transition: fill-opacity .15s ease, stroke-width .15s ease; }
.map-node:hover circle, .map-node:focus-visible circle { fill-opacity: 0.34; }
.map-node:focus-visible { outline: none; }
.map-node text { pointer-events: none; }
.map-detail { margin-top: 14px; padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); }
.map-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.map-legend { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 14px; }
.map-legend > span { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-soft); }
.map-legend i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }

/* Progress. A scan finishes in under a second for a small repository, which reads as nothing happening.
   The bar walks the stages the engine actually performs, so the pause communicates what is going on. */
.progress { height: 6px; border-radius: 999px; background: var(--panel-2); overflow: hidden; margin: 12px 0 6px; }
.progress > i { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--accent), #6ea8ff); transition: width .35s ease, background .2s ease; }
.progress-host .progress-label { font-size: 12.5px; color: var(--muted); }
.progress-host .progress-label.done { color: var(--good); }
.progress-host .progress-label.failed { color: var(--bad); }

/* A loading state has to read as one at a glance. The text alone sat in the same weight and colour as the
   body copy, so a page that was still fetching looked like a page that had finished. */
.loading { display: flex; align-items: center; gap: 10px; color: var(--text-soft); }
.loading::before {
  content: ""; flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2.5px solid var(--border-strong); border-top-color: var(--accent);
  animation: qr-spin 0.8s linear infinite;
}
@keyframes qr-spin { to { transform: rotate(360deg); } }

/* The auth slot keeps its own width whether or not it has been filled in yet. auth.js swaps the sign in
   links for the account chip after the page loads; before that the slot is empty, so without a reserved
   width the nav group sits flush right and then jumps left by the width of the chip when the session
   lands. The width is the sign in links, the wider of the two states, and the two are spaced apart so the
   chip stays next to the divider and Sign out stays on the right edge. */
#auth-nav {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; padding-left: 16px;
  border-left: 1px solid var(--border); min-width: 216px; justify-content: space-between;
  /* Size to the slot's own content as well as to the reservation. A min-width alone is treated as the
     flex minimum, so the box stopped at 216px and the signed-in slot, which is about 242px because the
     account chip is wider than the two sign-in links it replaces, spilled past the divider and out of
     the right edge of the header. flex: none keeps it from being shrunk below that again. */
  width: max-content; flex: 0 0 auto;
}
/* The account chip carries its own pill styling, so keep the plain nav-link treatment off it. Without
   the :not(), the link rule won the id/class specificity and stretched the chip into a tall box. */
#auth-nav a:not(.account-chip) { font-size: 14px; color: var(--text-soft); text-decoration: none; padding: 8px 11px; border-radius: 8px; font-weight: 600; }
#auth-nav a:not(.account-chip):hover { color: var(--accent); background: var(--accent-soft); text-decoration: none; }
#auth-nav a.cta-link { background: var(--accent); color: #fff; }
#auth-nav a.cta-link:hover { background: var(--accent-dark); color: #fff; }
.account-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 999px; padding: 6px 13px; font-size: 13.5px; color: var(--text); text-decoration: none; }
.account-chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }

/* ---------------- layout ---------------- */
/* Inner page heroes. A soft wash plus a faint grid, so a page opening reads as designed rather than as
   a heading dropped onto a blank field. The home page keeps its skyline treatment below. */
.hero {
  position: relative;
  padding: 68px 0 40px;
  background:
    radial-gradient(900px 320px at 12% -10%, rgba(36, 87, 230, 0.10), transparent 60%),
    radial-gradient(700px 260px at 88% 0%, rgba(11, 122, 69, 0.07), transparent 55%),
    linear-gradient(180deg, #ffffff 0%, rgba(247, 249, 252, 0) 100%);
  border-bottom: 1px solid var(--border);
}
.hero.compact { padding: 44px 0 22px; }
.hero h1 { max-width: 900px; }
.lede { color: var(--muted); font-size: 18.5px; line-height: 1.6; max-width: 780px; }

/* The home hero sits on the skyline illustration. Text goes light, and a directional scrim keeps the
   left hand side readable regardless of how the image is cropped. */
.hero-photo {
  position: relative;
  padding: 82px 0 68px;
  color: #ffffff;
  background-image:
    linear-gradient(100deg, rgba(4,10,24,0.95) 0%, rgba(4,10,24,0.86) 38%, rgba(4,10,24,0.55) 68%, rgba(4,10,24,0.34) 100%),
    url("/assets/skyline.svg");
  background-size: cover, cover;
  background-position: center center, center bottom;
  background-repeat: no-repeat, no-repeat;
}
.hero-photo h1 { color: #ffffff; max-width: 900px; }
.hero-photo .lede { color: rgba(255,255,255,0.84); }
.hero-photo .eyebrow { color: #9fd6ff; }
.hero-photo .tiny { color: rgba(255,255,255,0.7); }
.hero-photo .panel { background: #ffffff; }
.hero-photo .panel h1,
.hero-photo .panel h2,
.hero-photo .panel h3 { color: var(--text); }
.hero-photo .panel .muted,
.hero-photo .panel p { color: var(--muted); }
.hero-photo .panel .note { color: var(--muted); }
.hero-photo .panel label { color: var(--text-soft); }
.hero-photo .result { color: var(--text); }
.hero-photo .result p,
.hero-photo .result .muted { color: var(--muted); }
.hero-photo .result h3,
.hero-photo .result h4 { color: var(--text); }
.hero-photo .result table.kv th { color: var(--muted); }
.hero-photo .result table.kv td,
.hero-photo .result li { color: var(--text-soft); }

/* A soft tint at the top of interior pages so they read as one family with the home page. */
.hero.compact {
  background-image: radial-gradient(1100px 320px at 12% -30%, #e6eefc 0%, rgba(230,238,252,0) 70%);
}
.section { padding: 54px 0; }
.section.alt { background: var(--bg-alt); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.section-head { margin-bottom: 24px; }
.muted { color: var(--muted); }
.small { font-size: 14px; }
.tiny { font-size: 12.5px; }
.eyebrow { text-transform: uppercase; letter-spacing: 1.2px; font-size: 12px; font-weight: 700; color: var(--accent); margin-bottom: 10px; }
/* Inline code in prose carries real tokens (a path, a command, a package name). Let a long one break so
   it cannot push the page sideways on a phone. Block code is unaffected: `pre` does not wrap, and
   `code.demo-line` sets its own white-space. */
code { overflow-wrap: anywhere; }

/* ---------------- buttons and inputs ---------------- */
button, .btn {
  font: inherit; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: 12px 20px; font-weight: 700; background: var(--accent); color: #fff;
  box-shadow: 0 1px 2px rgba(10, 23, 48, .12); transition: background .15s ease, box-shadow .15s ease, transform .15s ease;
  /* An anchor with this class is a button, so it has to behave like one. Left inline, a long label wraps
     inside its own padding and two buttons sit on top of each other, which is exactly what happened in
     the private repositories panel. */
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  text-align: center; white-space: nowrap;
}
button:hover, .btn:hover { background: var(--accent-dark); text-decoration: none; box-shadow: 0 4px 14px rgba(36, 87, 230, .22); }
button:disabled { opacity: 0.55; cursor: not-allowed; }
.btn.secondary { background: #fff; color: var(--text); border-color: var(--border-strong); }
.btn.secondary:hover { background: var(--panel-2); }
.btn.ghost { background: transparent; color: var(--accent); border-color: transparent; }
.btn.ghost:hover { background: var(--accent-soft); }
.btn.small { padding: 8px 13px; font-size: 14px; }

input[type=text], input[type=email], input[type=password], select, textarea {
  font: inherit; background: #fff; border: 1px solid var(--border-strong); color: var(--text);
  border-radius: var(--radius-sm); padding: 12px; outline: none; width: 100%;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
label { font-size: 13px; color: var(--text-soft); display: block; margin-bottom: 7px; font-weight: 600; }

.field-row { display: flex; gap: 10px; flex-wrap: wrap; }
.field-row input { flex: 1 1 300px; }
.field-row button { flex: 0 0 auto; }

/* ---------------- cards ---------------- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 18px; }
/* Cards line up at the top and their content flows naturally. Pinning the last line to the bottom was
   tried and looked worse: a card with two lines of text next to one with eight left a hole in the middle. */
.cards .card { display: flex; flex-direction: column; }
.cards .card > p:last-child { margin-bottom: 0; }
/* A fixed three column grid so six cards fill two even rows instead of leaving a ragged last row. */
.cards.even-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cards.even-3 .card { display: flex; flex-direction: column; }
.cards.even-3 .card > p:last-child { margin-bottom: 0; }
@media (max-width: 980px) {
  .cards.even-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .cards.even-3 { grid-template-columns: 1fr; }
}
.card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow); }
.card { padding: 24px; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }

/* A glyph per card, so a row of cards reads as a set of things rather than a wall of text. */
.card-icon {
  width: 40px; height: 40px; border-radius: 12px; margin-bottom: 14px;
  display: grid; place-items: center; background: var(--accent-soft); color: var(--accent);
}
.card-icon svg { width: 21px; height: 21px; }
.card.featured .card-icon { background: #e6f6ee; color: var(--good); }

/* Icons injected from data-icon. Stroke based, so they take the colour of whatever holds them. */
.has-icon { display: inline-flex; align-items: center; gap: 9px; }
.has-icon > svg { width: 18px; height: 18px; flex: none; }
/* The menu icons are prepended by icons.js once the page has parsed, which widens each link. Because the
   nav group is right aligned, that slid the whole header sideways when the icons arrived. The links that
   carry an icon are laid out here as if the glyph were already there, and the empty slot is dropped once
   it is drawn, so they have their final width from the first paint. The slot matches the size the real
   glyph is given below: 15px inside a nav group, which already spaces its links at 5px, and 18px for the
   loose Pricing link, which spaces at 9px. Only the top row of the nav needs this; the dropdowns are
   hidden until they are opened, so their icons cannot move anything. */
nav.main > a[data-icon] { display: inline-flex; align-items: center; gap: 9px; --nav-icon: 18px; }
nav.main .nav-group > a[data-icon] { --nav-icon: 15px; }
nav.main > a[data-icon]:not(.has-icon)::before,
nav.main .nav-group > a[data-icon]:not(.has-icon)::before { content: ""; width: var(--nav-icon); height: var(--nav-icon); flex: none; }
.eyebrow.has-icon > svg { width: 15px; height: 15px; }
.card > h3.has-icon > svg { color: var(--accent); }
.badge.has-icon { gap: 5px; }
.badge.has-icon > svg { width: 12px; height: 12px; }
.badge.vulnerable.has-icon > svg { color: var(--bad); }
.badge.pqc.has-icon > svg { color: var(--good); }
.badge.strong.has-icon > svg { color: var(--good); }
.badge.deprecated.has-icon > svg { color: var(--warn); }
nav.main .nav-group > a.has-icon > svg { width: 15px; height: 15px; opacity: 0.8; }
nav.main .nav-menu a.has-icon > svg { width: 15px; height: 15px; opacity: 0.7; }

/* A word the browser must not break, so a hyphenated phrase such as "quantum-safe" stays whole rather than
   being split at its hyphen when the headline balances across lines. */
.nw { white-space: nowrap; }

/* ---------------- homepage, rebuilt around the product rather than the method ---------------- */
.section.tight { padding: 22px 0; }

.hero-dark {
  background: linear-gradient(155deg, #071227 0%, #0d2350 52%, #1b46b0 100%);
  border-bottom: 0;
  padding: 76px 0 84px;
  color: #fff;
}
.hero-dark::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(760px 320px at 12% 0%, rgba(120, 170, 255, .28), transparent 60%),
    radial-gradient(620px 300px at 88% 20%, rgba(60, 220, 190, .16), transparent 62%);
}
.hero-split { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr); gap: 46px; align-items: center; }

/* The home hero: the product panel and the map are one composition rather than two floating cards. The
   readiness panel is the subject, the map sits over its lower right corner as a second surface, and the
   two share a shadow language so they read as one object with depth. No glass, no gradient panels and no
   flourish: an enterprise buyer reads those as styling rather than as product. */
.hero-wide .wrap { max-width: 1120px; }
/* The copy column used to be narrower than the picture column (1fr against 1.24fr), so the headline wrapped
   to four lines, broke "quantum-safe" across two of them, and the panels filled their column edge to edge
   only 40px from the text. Giving the copy the larger share and the picture the smaller one, and widening the
   gap, moves the whole composition to the right and leaves air between the claim and the screen. */
.hero-wide .hero-split { grid-template-columns: minmax(0, 1.24fr) minmax(0, .92fr); gap: 60px; }
.hero-visual { position: relative; display: block; padding: 0 0 30px; }
.hero-product { position: relative; z-index: 2; width: 66%; }
/* The headline held four lines with a single word on the last one. Balance lets the browser even the
   lines out, and the smaller size keeps "Get quantum-ready." whole on one line, so the copy block is a
   line shorter and more of the visual sits above the fold. */
.hero-dark h1 { color: #fff; font-size: 52px; max-width: 100%; text-wrap: balance; }
.hero-dark .lede { color: rgba(255, 255, 255, .84); font-size: 19px; max-width: 560px; }
.hero-dark .eyebrow { color: #9dc0ff; }
.hero-try { background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .18); box-shadow: none; margin-top: 22px; backdrop-filter: blur(6px); }
.hero-try label { color: rgba(255, 255, 255, .82); }
.hero-try .note { color: rgba(255, 255, 255, .7); }
.hero-trust { color: rgba(255, 255, 255, .72) !important; margin-top: 14px; }
.hero-cta { margin-top: 22px; margin-bottom: 0; }
.hero-dark .btn.secondary { background: rgba(255, 255, 255, .12); color: #fff; border-color: rgba(255, 255, 255, .38); }
.hero-dark .btn.secondary:hover { background: rgba(255, 255, 255, .2); }

/* The scan sits on its own, full width, so a result has room to be read. */
.try-panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 30px; align-items: center; }
.try-copy h2 { margin-bottom: 8px; }
.try-form label { display: block; font-size: 12px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase; color: var(--muted); margin-bottom: 7px; }
.try-form .note { margin: 10px 0 0; }

/* A heading with an illustration beside it, for the scanner capability sections. */
.split-head { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 26px; align-items: center; }
.split-head h2 { margin-bottom: 8px; }
.split-head .muted { margin-bottom: 0; }
.illo { color: var(--accent); opacity: .9; }
.illo svg { width: 100%; height: auto; max-width: 220px; display: block; margin-left: auto; }
@media (max-width: 760px) {
  .split-head { grid-template-columns: 1fr; }
  .illo { display: none; }
}

/* The product, on screen, in the first five seconds. */
.hero-product { position: relative; }
.prod {
  background: #fff; border-radius: 18px; overflow: hidden;
  /* Three layers: a contact shadow that makes the panel sit on the surface, a mid shadow for the body,
     and a wide soft one for depth. A single large blur reads as a glow rather than as an object. */
  box-shadow:
    0 1px 2px rgba(3, 10, 26, .26),
    0 10px 20px -10px rgba(3, 10, 26, .34),
    0 44px 84px -26px rgba(3, 10, 26, .46);
  color: var(--text); transform: perspective(1200px) rotateY(-6deg) rotateX(2deg);
}
.prod-bar { display: flex; align-items: center; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: #fbfcfe; }
.prod-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #e2e8f2; }
.prod-title { margin-left: 10px; font-weight: 700; font-size: 13px; }
.prod-org { margin-left: auto; font-size: 12px; color: var(--muted); }
.prod-body { padding: 20px 22px 24px; }
.prod-label { font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); }
.prod-score { display: flex; align-items: baseline; gap: 8px; margin: 6px 0 16px; }
.prod-score span { font-size: 44px; font-weight: 800; letter-spacing: -1.6px; }
.prod-score small { font-size: 15px; color: var(--muted); }
.prod-score em { margin-left: auto; font-style: normal; font-size: 12.5px; color: var(--good); font-weight: 600; }
.prod-rows { display: grid; gap: 7px; }
.prod-row { display: flex; align-items: center; justify-content: space-between; font-size: 13.5px; color: var(--text-soft); }
.prod-row b { font-size: 14px; }
.prod-inv { display: grid; gap: 6px; margin-top: 6px; }
.prod-inv > div { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; padding: 9px 11px; border: 1px solid var(--border); border-radius: 10px; font-size: 13px; }
.prod-inv span { color: var(--muted); font-size: 12.5px; }
.tag { font-style: normal; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.tag.bad { background: #fdecea; color: #a3211a; }
.tag.warn { background: #fff4e2; color: #8a5200; }
.tag.ok { background: #e6f6ee; color: #0b6b40; }

.proof-strip { display: flex; flex-wrap: wrap; gap: 10px 26px; justify-content: center; }
.proof-strip > span { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--text-soft); }
.proof-strip > span > svg { width: 16px; height: 16px; color: var(--accent); }

/* The logo strip. Not customer logos, which we do not have, but the products it connects to. */
.logo-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px; justify-content: center; margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border); }
.logo-strip #logo-row { display: flex; flex-wrap: wrap; gap: 16px 22px; align-items: center; justify-content: center; }
.logo-item { display: inline-flex; align-items: center; gap: 9px; }
.logo-item em { font-style: normal; font-size: 13.5px; font-weight: 600; color: var(--text-soft); }

/* The estate, drawn. */
.estate { display: grid; grid-template-columns: 1fr auto 1.1fr auto 1fr; gap: 14px; align-items: center; }
.estate-col { display: grid; gap: 10px; }
.estate-node { display: flex; align-items: center; gap: 10px; padding: 13px 15px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); font-size: 14px; font-weight: 600; }
.estate-node > svg { width: 17px; height: 17px; color: var(--accent); flex: none; }
.estate-arrow { font-size: 22px; color: var(--accent); opacity: .55; }
.estate-label { font-size: 11px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase; color: var(--muted); margin-bottom: 2px; }
/* The hub has to be readable first and decorative second. It was too dark, so the heading vanished into it. */
.estate-hub {
  padding: 24px 20px; border-radius: 16px; text-align: center;
  background: linear-gradient(150deg, #eef4ff 0%, #e4edff 100%);
  border: 2px solid var(--accent); box-shadow: 0 14px 34px rgba(36, 87, 230, .18);
}
.estate-hub strong { display: block; font-size: 16px; color: var(--accent-dark); }
.estate-hub span { display: block; font-size: 12.5px; color: var(--text-soft); margin-top: 6px; }
.estate-hub .hub-stat { font-weight: 600; color: var(--text); margin-top: 10px; }

/* Cards in a row put their link on the same line, for sets where the text lengths are close. */
.cards.pin .card > p:last-child { margin-top: auto; padding-top: 12px; }

/* The engine, and the two places it runs. A diagram rather than three paragraphs: the same facts read faster,
   and a reader who only looks at the picture should still come away knowing which scanner they want. */
.engine-map { display: grid; gap: 16px; }
.engine-hub {
  padding: 22px 20px; border-radius: 16px; text-align: center;
  background: linear-gradient(150deg, #eef4ff 0%, #e4edff 100%);
  border: 2px solid var(--accent); box-shadow: 0 14px 34px rgba(36, 87, 230, .16);
}
.engine-hub strong { display: block; font-size: 17px; color: var(--accent-dark); }
.engine-hub span { display: block; font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.engine-hub .hub-parts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 12px; }
.engine-hub .hub-parts em {
  font-style: normal; font-size: 12px; font-weight: 600; color: var(--text);
  background: rgba(255, 255, 255, .78); border: 1px solid rgba(36, 87, 230, .22);
  border-radius: 999px; padding: 5px 11px;
}
.engine-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(285px, 1fr)); gap: 16px; }
.engine-split .card { padding: 20px; }
.engine-split .card h3 { margin: 0 0 4px; font-size: 16px; }
.engine-split .card .where { font-size: 12.5px; color: var(--muted); margin: 0 0 12px; }
.engine-facts { display: grid; gap: 9px; margin: 0; }
.engine-facts > div { display: grid; grid-template-columns: 104px 1fr; gap: 12px; font-size: 13.5px; line-height: 1.45; }
.engine-facts dt { color: var(--muted); font-weight: 600; }
.engine-facts dd { margin: 0; }
.engine-note {
  font-size: 13px; color: var(--muted); border-left: 3px solid var(--accent);
  padding: 2px 0 2px 14px; margin: 0;
}

/* One finding, in full. */
.finding-demo { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; max-width: 880px; }
.fd-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 22px; border-bottom: 1px solid var(--border); background: #fbfcfe; }
.fd-head strong { font-size: 19px; }
.fd-head .badge { margin-left: 10px; }
.fd-score { font-size: 13px; color: var(--muted); }
.fd-rows { margin: 0; padding: 6px 22px 18px; }
.fd-rows > div { display: grid; grid-template-columns: 190px 1fr; gap: 16px; padding: 12px 0; border-bottom: 1px dashed var(--border); }
.fd-rows > div:last-child { border-bottom: 0; }
.fd-rows dt { font-size: 12px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase; color: var(--muted); padding-top: 2px; }
.fd-rows dd { margin: 0; font-size: 15px; color: var(--text-soft); }

/* Milestones. */
.milestones { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
.milestone { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); }
.ms-year { font-size: 30px; font-weight: 800; letter-spacing: -1px; color: var(--accent); }
.ms-word { font-size: 13px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: var(--text); margin: 2px 0 10px; }

@media (max-width: 1080px) {
  /* The home hero sets its own two column split, and that rule is more specific, so it has to be named
     here as well or the hero would stay in two columns on a phone. */
  .hero-split, .hero-wide .hero-split { grid-template-columns: 1fr; gap: 34px; }
  /* One column means nothing can overlap, so the composition becomes a stack again and the map takes the
     full width it needs to stay readable on a small screen. */
  .hero-visual { padding: 0; }
  .hero-product { width: 100%; }
  .prod-map { position: static; width: 100%; margin-top: 18px; }
  .hero-visual { grid-template-columns: 1fr; gap: 16px; }
  .hero-dark h1 { font-size: 42px; }
  .prod { transform: none; }
  .estate { grid-template-columns: 1fr; }
  .estate-arrow { transform: rotate(90deg); justify-self: center; }
}
@media (max-width: 760px) {
  .hero-dark { padding: 44px 0 52px; }
  .hero-dark h1 { font-size: 33px; }
  .fd-rows > div { grid-template-columns: 1fr; gap: 4px; }
}
.card.featured { border-color: var(--accent); }
.card h3 { margin-bottom: 8px; }
.card p { color: var(--muted); font-size: 15px; }
.card p:last-child { margin-bottom: 0; }
.kpi { font-size: 21px; font-weight: 700; color: var(--accent); margin-bottom: 8px; }
.price { font-size: 22px; font-weight: 700; margin: 6px 0 10px; }
.card.featured .price { color: var(--accent); }

.panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); }
.panel + .panel { margin-top: 18px; }

.tabs {
  display: flex; gap: 6px; margin-bottom: 20px; flex-wrap: wrap;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 7px;
}
.tabs button {
  background: transparent; color: var(--text-soft); border: 1px solid transparent;
  border-radius: var(--radius-sm); padding: 11px 16px; font-weight: 600; font-size: 15px;
}
.tabs button:hover { background: #fff; color: var(--text); }
.tabs button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.tabs button.active:hover { background: var(--accent-dark); }

.note { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.note.ok { color: var(--good); }
/* Two column form grid, for the pairs of fields on the account page. */
/* Two columns. align-items is start, not end: on the explainer the left column is a short table of
   contents beside a very long article, and bottom alignment pushed the contents thousands of pixels
   down the page where nobody could see it. */
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px 22px; align-items: start; }
.grid-2 h3 { grid-column: 1 / -1; margin-bottom: 0; }
#profile label, #profile-form label { display: block; margin-bottom: 6px; }
.note.err { color: var(--bad); }
.note.warn { color: var(--warn); }

/* ---------------- badges ---------------- */
.badge {
  display: inline-block; font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.4px; white-space: nowrap; border: 1px solid transparent;
}
.badge.vulnerable { background: #fdecea; color: #a3211a; border-color: #f4c3bb; }
.badge.deprecated { background: #fff4e2; color: #8a5200; border-color: #f2d6a6; }
.badge.adequate { background: #eef1f6; color: #44526b; border-color: #d9e0ea; }
.badge.strong { background: #e6f6ee; color: #0b6b40; border-color: #b6e2cd; }
.badge.pqc { background: #e7effc; color: #17459a; border-color: #bdd2f4; }
.badge.neutral { background: #eef1f6; color: #55637c; border-color: #d9e0ea; }

/* Evidence ladder. Deliberately a green ramp, because more evidence is a better finding, not a worse one. */
.badge.ev-detected { background: #eef1f6; color: #55637c; border-color: #d9e0ea; }
.badge.ev-likely-used { background: #eef4fb; color: #31527d; border-color: #d3e0f0; }
.badge.ev-build-confirmed { background: #e7effc; color: #17459a; border-color: #bdd2f4; }
.badge.ev-deployment-confirmed { background: #e6f6ee; color: #0b6b40; border-color: #b6e2cd; }
.badge.ev-runtime-confirmed { background: #dff5e8; color: #075c37; border-color: #9edcbc; }

/* ---------------- tables ---------------- */
table.data { width: 100%; border-collapse: collapse; font-size: 14px; background: #fff; }
table.data th {
  text-align: left; color: var(--muted); font-weight: 700; font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.5px; padding: 11px 12px; border-bottom: 1px solid var(--border); white-space: nowrap;
  background: var(--panel-2);
}
table.data td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
table.data tr:last-child td { border-bottom: 0; }
table.data code { font-family: var(--mono); font-size: 12.5px; color: var(--text-soft); }
.table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }

.result { margin-top: 18px; border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--radius-sm); padding: 18px; background: #fff; }
.result.good { border-left-color: var(--good); }
.result.bad { border-left-color: var(--bad); }
.result.warn { border-left-color: var(--warn); }
.result h3 { margin-bottom: 12px; }

/* The verdict of an endpoint scan, said once and with a mark. A visitor should read the answer before the
   caveats: a green tick for a hybrid key exchange (measured, or inferred from a provider that enables it by
   default), amber when the answer is genuinely unknown, red when only a classical group was negotiated. */
.scan-verdict { display: flex; gap: 14px; align-items: flex-start; }
.scan-verdict .sv-icon { flex: none; width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; }
.scan-verdict .sv-icon svg { width: 26px; height: 26px; }
.scan-verdict.good .sv-icon { background: #e6f6ee; color: #0b6b40; }
.scan-verdict.warn .sv-icon { background: #fff4e2; color: #8a5200; }
.scan-verdict.bad .sv-icon { background: #fdecea; color: #a3211a; }
.scan-verdict .sv-body { min-width: 0; }
.scan-verdict h3 { margin: 4px 0 6px; font-size: 20px; }
.scan-verdict p { margin: 0; }
table.kv { width: 100%; border-collapse: collapse; font-size: 14px; }
table.kv th { text-align: left; color: var(--muted); font-weight: 600; padding: 6px 12px 6px 0; white-space: nowrap; vertical-align: top; width: 200px; }
table.kv td { padding: 6px 0; }

.score-card { display: flex; gap: 22px; align-items: center; flex-wrap: wrap; }
.score-value { font-size: 50px; font-weight: 800; line-height: 1; letter-spacing: -1px; }
.score-value.band-strong, .score-value.band-good { color: var(--good); }
.score-value.band-fair { color: var(--warn); }
.score-value.band-poor, .score-value.band-critical { color: var(--bad); }
.score-value.band-none { color: var(--muted); font-size: 23px; }
.meter { flex: 1 1 260px; min-width: 200px; height: 10px; background: var(--panel-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.meter span { display: block; height: 100%; background: linear-gradient(90deg, var(--bad), var(--warn), var(--good)); }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.stat { background: #fff; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 15px; }
.stat .n { font-size: 26px; font-weight: 700; }
.stat .l { font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.4px; }
.stat.vulnerable .n { color: var(--bad); }
.stat.deprecated .n { color: var(--warn); }
.stat.adequate .n { color: #44526b; }
.stat.strong .n { color: var(--good); }
.stat.pqc .n { color: var(--accent); }

.callout { border: 1px solid var(--border); border-left: 4px solid var(--accent); background: var(--accent-soft); border-radius: var(--radius-sm); padding: 16px 18px; margin-bottom: 16px; }
.callout.warn { border-left-color: var(--warn); background: #fff8ec; }
.callout.bad { border-left-color: var(--bad); background: #fdeeec; }
.callout h3 { margin-bottom: 8px; font-size: 16px; }
.callout p:last-child { margin-bottom: 0; }

pre.snippet {
  font-family: var(--mono); font-size: 12.5px; background: #0f1b2d; border: 1px solid #1d2f4a;
  border-radius: 10px; padding: 13px 14px; overflow-x: auto; margin: 0; color: #dbe6f5; line-height: 1.6;
}
/* Evidence has to be readable in full. A line of code cut off mid statement is worse than useless,
   because the reader cannot tell whether the interesting part was in the part they cannot see. */
.data pre.snippet, .evidence-row pre.snippet {
  white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: visible; font-size: 12px;
}

.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 18px; }
.toolbar select { width: auto; }

ol.steps { list-style: none; padding: 0; margin: 0; display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
ol.steps li { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow); }
ol.steps h3 { margin-bottom: 8px; }
ol.steps p { color: var(--muted); font-size: 15px; margin-bottom: 0; }

dl.faq dt { font-weight: 700; margin-top: 20px; }
dl.faq dd { margin: 6px 0 0; color: var(--muted); }

/* ---------------- editorial ---------------- */
.article { max-width: 760px; }
.article h2 { margin-top: 34px; }
.article h3 { margin-top: 26px; }
.article p, .article li { color: var(--text-soft); }
.article ul, .article ol { padding-left: 20px; }
.article li { margin-bottom: 8px; }
.article blockquote { margin: 20px 0; padding: 14px 18px; border-left: 4px solid var(--accent); background: #fff; color: var(--text-soft); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.article .meta { color: var(--muted); font-size: 13.5px; margin-bottom: 22px; }
.article hr { border: 0; border-top: 1px solid var(--border); margin: 30px 0; }

.timeline { list-style: none; padding: 0; margin: 0; border-left: 2px solid var(--border); }
.timeline li { position: relative; padding: 0 0 26px 26px; }
.timeline li::before {
  content: ""; position: absolute; left: -8px; top: 6px; width: 14px; height: 14px; border-radius: 50%;
  background: #fff; border: 3px solid var(--accent);
}
.timeline li.done::before { border-color: var(--good); }
.timeline li.future::before { border-color: var(--sg-red); }
.timeline .when { font-weight: 700; color: var(--text); }
.timeline .what { color: var(--muted); font-size: 15px; }
.timeline .src { font-size: 12.5px; color: var(--muted); }

.resource { display: flex; gap: 14px; align-items: flex-start; padding: 16px 0; border-bottom: 1px solid var(--border); }
.resource:last-child { border-bottom: 0; }
.resource .kind { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--accent); min-width: 92px; }
.resource .body { flex: 1; }
.resource h3 { font-size: 16px; margin-bottom: 4px; }

.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }

/* Product shots. Real screenshots of the real pages, framed so they read as evidence rather than decoration. */
.showcase { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 22px; }
.shot {
  margin: 0; background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
}
.shot img { display: block; width: 100%; height: auto; border-bottom: 1px solid var(--border); }
.shot .cap { padding: 13px 15px; font-size: 13.5px; color: var(--muted); margin: 0; }

/* Horizontal timeline for the home page. The vertical list lives on the timeline page. */
.timeline-strip { position: relative; display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0; margin-top: 14px; }
.timeline-strip::before { content: ""; position: absolute; top: 15px; left: 6px; right: 6px; height: 2px; background: var(--border); }
.tl-item { position: relative; padding: 42px 18px 0 0; }
.tl-item::before {
  content: ""; position: absolute; top: 8px; left: 0; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; border: 3px solid var(--accent);
}
.tl-item.done::before { border-color: var(--good); }
.tl-item.now::before { border-color: var(--sg-red); }
.tl-item .when { font-weight: 700; font-size: 15.5px; margin-bottom: 4px; }
.tl-item .what { color: var(--muted); font-size: 13.5px; line-height: 1.5; }

@media (max-width: 760px) {
  .timeline-strip::before { display: none; }
  .tl-item { padding: 20px 0 0 22px; border-left: 2px solid var(--border); }
  .tl-item::before { top: 22px; left: -9px; }
}

/* ---------------- auth + gating ---------------- */
.auth-card { max-width: 460px; margin: 0 auto; }
.auth-card .panel { padding: 26px; }
.auth-switch { text-align: center; margin-top: 16px; color: var(--muted); font-size: 14px; }
.form-row { margin-bottom: 14px; }
.locked { position: relative; }
.locked > .lock-veil {
  position: absolute; inset: 0; background: rgba(245, 248, 253, 0.72);
  backdrop-filter: blur(3px); border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center; text-align: center; padding: 20px; z-index: 2;
}
.lock-veil .inner { max-width: 480px; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); }
.lock-veil h3 { margin-bottom: 8px; }
.lock-veil .toolbar { justify-content: center; margin-bottom: 0; margin-top: 4px; }
.account-chip {
  display: inline-flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 12px; font-size: 13px; line-height: 1; color: var(--text-soft);
}
/* The account chip is a link to the account page, so it has to look like one. It used to read as a
   status pill, which is why nobody clicked it. */
a.account-chip { border-color: var(--border-strong); color: var(--text); font-weight: 600; }
a.account-chip:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); text-decoration: none; }
a.account-chip::after { content: "\25be"; font-size: 9px; opacity: 0.55; margin-left: 2px; }

.site-footer { border-top: 1px solid var(--border); padding: 36px 0 54px; color: var(--muted); font-size: 14px; background: var(--bg-alt); }
.site-footer p { margin-bottom: 8px; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

@media print {
  .site-header, .site-footer, .toolbar, nav.main, .tabs, .lock-veil { display: none !important; }
  body { background: #fff; }
  .panel, .card, .stat, .callout, .result { box-shadow: none; }
  /* A formal report carries its own reasoning, so nothing stays folded on paper. The control is hidden
     and the body is shown, which reads as ordinary prose in the printed document. */
  .fold > summary { display: none !important; }
  .fold > *:not(summary) { display: block !important; }
  /* Chrome 128 and later wrap a collapsed body in ::details-content and hide it with content-visibility,
     so showing the children is not enough on its own. Without this the printed report silently lost every
     folded explanation, which is the opposite of what a formal document should do. */
  .fold::details-content { content-visibility: visible !important; }
  .fold { margin-top: 10px; break-inside: avoid; }
  /* The letterhead. On screen the site header already carries the brand, so this appears when printed
     and in the exported report, which is where a document needs to look like one. */
  .print-brand, .print-foot { display: flex !important; }
}

/* ---------------------------------------------------------------- Read the detail on demand
   The pages lead with the figure and keep the reasoning behind a fold. A reader who wants the number has
   it immediately, and a reader who wants to know where it came from opens one row. Native details, so it
   works with a keyboard, with a screen reader, and in print without any script. */
/* A quiet disclosure. It appears in a few places where a reader genuinely benefits from the reasoning
   behind a figure, so it reads as an aside rather than as a call to action: muted text, no fill, and the
   accent only on hover. An earlier pass put one of these under almost every paragraph and it turned the
   pages into a wall of controls, which is worse than the prose it replaced. */
.fold { margin: 12px 0 0; }
.fold > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.15s ease;
}
.fold[open] > summary::before { transform: rotate(90deg); }
.fold > summary:hover { color: var(--accent); }
.fold[open] > summary { color: var(--text); }
.fold > *:not(summary) { margin-top: 10px; }

.print-brand, .print-foot { display: none; align-items: center; gap: 10px; }
.print-brand { margin: 0 0 18px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.print-brand img { width: 36px; height: 36px; }
.print-brand strong { font-size: 16px; letter-spacing: -0.2px; }
.print-brand .print-meta { font-size: 12px; color: var(--muted); }
.print-foot {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: none;
  justify-content: space-between;
  gap: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
}

@media (max-width: 1080px) {
  .site-header .wrap { height: auto; padding: 12px 22px; flex-wrap: wrap; gap: 12px; }
  /* Below this width the header wraps to two rows, so it is taller and anchors need a bigger offset. */
  html { scroll-padding-top: 120px; }
  .nav-wrap { width: 100%; justify-content: space-between; gap: 12px; }
  /* The grouped menus hang below the nav row. A scroll container here (overflow-x: auto) also becomes an
     overflow-y clip, so every dropdown was cut off to the height of the nav bar and its items could not be
     clicked at tablet and small-laptop widths. The nav is only visible above 1000px, which is the width it
     needs (see the query below), so it never has to scroll and the menus open over the page. */
  nav.main { overflow: visible; }
  .account-layout { grid-template-columns: 1fr; gap: 16px; }
  .account-nav { position: static; flex-direction: row; flex-wrap: wrap; }
  /* The header wraps to its own rows here, so the auth slot no longer shares a line with the nav group
     and does not need its width reserved. */
  #auth-nav { min-width: 0; justify-content: flex-start; }
}

/* The nav collapses here, and the number comes from measurement rather than taste. Measured on the
   deployed site: the nav row needs about 865px signed out and about 915px with an account chip in
   the auth slot, because the chip is wide and the auth links are told they may shrink (min-width: 0),
   so past that point they spill out of the header instead of the row wrapping. It used to collapse
   at 760px, which left the header overflowing by up to 132px in the 761-960px band: a small laptop
   window, which is exactly where a person first sees this site. Collapsing here means the row never
   has to scroll and never spills, with room for a longer account name than the one measured. */
@media (max-width: 1000px) {
  nav.main a { padding: 7px 8px; font-size: 13.5px; }
  /* Hover does not exist on touch, so the grouped menus are laid out as a plain stacked list. The
     header stops sticking at this width, otherwise a tall menu would follow the reader down the page. */
  .site-header { position: static; }
  /* The header no longer sticks here, so anchors only need a small gap. */
  html { scroll-padding-top: 14px; }
  /* The menu is closed until it is asked for. An always-open list pushed the page down and looked like
     the site had no navigation design at all. */
  .nav-toggle { display: inline-flex; }
  /* The header row held the button, the menu and the account links side by side. With the menu open it
     was squeezed to about eighteen pixels, so the row now wraps and the menu takes a row of its own. */
  .nav-wrap { flex-wrap: wrap; row-gap: 10px; }
  .nav-toggle { order: 1; }
  #auth-nav { order: 2; padding-left: 0; border-left: 0; }
  nav.main {
    order: 3; display: none; flex-direction: column; align-items: stretch; overflow: visible; gap: 2px;
    flex: 1 0 100%; width: 100%; padding: 8px 0 4px;
  }
  nav.main.open { display: flex; }
  .nav-group { display: flex; flex-direction: column; }
  .nav-menu, .nav-menu.wide {
    position: static; display: flex; flex-direction: column; min-width: 0; width: 100%; max-height: none;
    padding: 0 0 6px 12px; border: 0; box-shadow: none; background: transparent; overflow: visible;
  }
  .nav-menu a { font-size: 13.5px; padding: 7px 6px; white-space: normal; }
  /* An open menu on a phone scrolls inside the header instead of pushing the page sideways. */
  nav.main.open { max-height: calc(100vh - 96px); overflow-y: auto; overscroll-behavior: contain; }
  .caret { display: none; }
  nav.main a.nav-cta { margin: 8px 0 4px; justify-content: center; }
  #auth-nav { padding-left: 8px; }
}

@media (max-width: 760px) {
  h1 { font-size: 31px; }
  h2 { font-size: 22px; }
  .lede { font-size: 16px; }
  /* A long label (a PDF title, say) cannot stay on one line on a phone. Let it wrap inside the button
     rather than push the page sideways; the flex container keeps two of them from overlapping. */
  .btn { white-space: normal; max-width: 100%; }
}

/* QR code frame. Always white behind the code so a camera can lock on, whatever the page theme. */
.qr-frame {
  display: inline-block;
  padding: 12px;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  line-height: 0;
}
.qr-frame svg { display: block; width: 216px; height: 216px; }
.qr-frame img { display: block; width: 216px; height: 216px; image-rendering: pixelated; }
@media (max-width: 560px) {
  .qr-frame svg, .qr-frame img { width: 176px; height: 176px; }
}

/* Left rail of the signed in pages. Profile and security sits below a rule of its own, because it is
   account housekeeping rather than part of the scan workflow. */
.account-nav .nav-sep { height: 1px; background: var(--border); margin: 12px 4px; }
.account-nav a.current { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

/* Account and profile forms. Fields need air above them and the button needs to sit clearly below the
   last field instead of being pressed against it. */
.panel form h3 { margin: 0 0 12px; }
.panel form label { margin-top: 18px; margin-bottom: 7px; }
.panel form h3 + label { margin-top: 0; }
.panel form .grid-2 label { margin-top: 0; }
/* The two factor block is not a form, so its buttons need the same treatment by name. */
.panel form .toolbar, .section-rule .toolbar { margin-top: 24px; margin-bottom: 0; }
.panel form .grid-2 + .toolbar, .panel form .toolbar + .toolbar { margin-top: 24px; }
.panel form .note, .panel form p.note { margin: 12px 0 0; }
.panel form .snippet { margin: 0 0 2px; }
.grid-2.pair { align-items: start; row-gap: 6px; }
.section-rule { margin-top: 28px; border-top: 1px solid var(--border); padding-top: 24px; }
.section-rule h3 { margin-top: 0; }
.field-note { margin: 16px 0 7px; }
.qr-frame { margin: 6px 0 4px; }
.panel form .toolbar + .tiny, .section-rule .toolbar + .tiny { margin-top: 12px; }

/* Live demo. The progress bar carries its own colour so it reads as activity rather than as a score. */
.row-between { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.demo-progress { height: 10px; background: var(--panel-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.demo-progress span { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), #14b8a6); transition: width .22s ease; }
.demo-result .score-card { margin-top: 16px; }
.demo-result .score-value { font-size: 44px; }
.demo-result ol { padding-left: 20px; }
.demo-result ol li { margin-bottom: 14px; }
.panel form.stacked { margin-top: 30px; }

/* The verified copy strip carries the fingerprint and a scannable address side by side. */
.verified-strip { display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap; }
.verified-body { flex: 1 1 320px; }
.verified-qr { flex: 0 0 auto; }
.verified-qr .qr-frame svg { width: 148px; height: 148px; }

/* The map inside another panel, and the live demo's own pieces. */
.map-block { margin-top: 22px; }
.map-block h2 { font-size: 20px; }
.demo-code {
  width: 100%; margin-top: 2px; padding: 14px 16px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: #0d1b34; color: #e6edf7; font: 13px/1.6 var(--mono); resize: vertical; tab-size: 2;
}
.demo-code:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
code.demo-line { display: block; font-size: 12.5px; line-height: 1.5; color: var(--text-soft); white-space: pre-wrap; word-break: break-word; }
.scope-list { display: grid; gap: 12px; }
.scope-item { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); cursor: pointer; }
.scope-item:hover { border-color: var(--border-strong); }
.scope-item input { margin-top: 3px; width: 16px; height: 16px; flex: 0 0 auto; }
.scope-item span { display: block; }
.scope-item strong { display: block; }
.console {
  margin-top: 16px; padding: 16px 18px; border-radius: var(--radius-sm); background: #0b1730; color: #dbe6f6;
  font: 12.5px/1.7 var(--mono); max-height: 380px; overflow: auto;
}
.console-line { white-space: pre-wrap; word-break: break-word; }
.console-cmd { margin-top: 10px; color: #9fd6ff; }
.console-prompt { color: #63e6be; }
.console-rows { padding-left: 14px; }
.console-out { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 2px 0; }
.console-key { color: #8fb4ff; }
.console .badge { border-color: transparent; }

.prod-map {
  /* A second surface over the panel rather than a card beside it: offset past the lower right corner, on
     its own layer, with a hairline so the two edges stay legible where they meet. */
  /* Overlap enough to read as one composition and not so much that it covers the panel's own labels.
     It sits a little lower than the panel, which is what gives the pair their depth. */
  position: absolute; right: 0; bottom: -14px; z-index: 3; width: 35%;
  display: block; background: #fff; border: 1px solid var(--border); border-radius: 16px;
  overflow: hidden; padding: 12px 14px 4px;
  box-shadow:
    0 1px 2px rgba(3, 10, 26, .2),
    0 14px 26px -12px rgba(3, 10, 26, .4),
    0 40px 72px -28px rgba(3, 10, 26, .4);
  color: var(--text);
  text-decoration: none; transition: transform .18s ease, box-shadow .18s ease;
  /* backwards, not both: a forwards fill would keep the animated transform and cancel the hover lift. */
  animation: heroRise .7s cubic-bezier(.2, .7, .3, 1) .12s backwards;
}
.prod-map:hover, .prod-map:focus-visible {
  transform: translateY(-3px); text-decoration: none;
  box-shadow: 0 38px 80px rgba(3, 10, 26, .44), 0 3px 8px rgba(3, 10, 26, .26);
}
.prod-map-head { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; justify-content: space-between; margin-bottom: 4px; }
.prod-map-title { font-weight: 700; font-size: 14px; }
.prod-map-cta { font-size: 12px; font-weight: 700; color: var(--accent); white-space: nowrap; }
.prod-map img { display: block; width: 100%; height: auto; margin: 0 auto; }
@keyframes heroRise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .prod-map { animation: none; }
}
.demo-places { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.demo-places li { display: grid; gap: 2px; }

/* Readiness workbench: the join between the crown jewels register and the inventory. */
.wb-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px 20px; margin-top: 16px; }
.wb-grid input, .wb-grid select { width: 100%; }
.wb-grid label { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* The small "i" beside a field, and the note it opens. */
.info {
  width: 17px; height: 17px; padding: 0; border-radius: 50%; border: 1px solid var(--border-strong);
  background: var(--panel-2); color: var(--muted); font: 700 11px/15px var(--mono); text-align: center;
  cursor: pointer; flex: 0 0 auto;
}
.info:hover { border-color: var(--accent); color: var(--accent); }
.info.open { background: var(--accent); border-color: var(--accent); color: #fff; }
.field-help {
  display: block; width: 100%; margin: 2px 0 6px; padding: 10px 12px; font-size: 13px; line-height: 1.55;
  color: var(--text-soft); background: var(--accent-soft); border-left: 3px solid var(--accent);
  border-radius: 6px;
}
.field-help[hidden] { display: none; }

.link-btn {
  background: none; border: 0; padding: 0; font: inherit; font-size: 12.5px; color: var(--accent);
  font-weight: 600; cursor: pointer; text-decoration: underline; margin-right: 10px;
}
.link-btn:hover { color: var(--accent-dark); }

.map-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center;
  margin-top: 10px; padding: 12px 14px; background: #fff; border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.map-row select { min-width: 190px; }
@media (max-width: 640px) {
  .map-row { grid-template-columns: 1fr; }
}

/* The evidence row under an inventoried item: file, line, branch and the whole line of code. */
.iw-row > td { background: var(--panel-2); border-top: 0; }
.iw-places ul { list-style: none; margin: 0; padding: 0; }
.iw-places li { margin-bottom: 8px; }
.iw-places code { font-size: 12.5px; }
.iw-places .snippet { margin: 4px 0 0; }

/* Charts. One set of pieces, used by the accuracy page, the workbench, reports, the demo and the home
   page, so the same number always looks the same. */
.ch-bars { display: grid; gap: 10px; margin-top: 14px; }
.ch-bar-row { display: grid; grid-template-columns: minmax(120px, 1.5fr) minmax(80px, 3fr) auto; gap: 12px; align-items: center; }
.ch-bar-label { font-size: 13.5px; color: var(--text); display: grid; }
.ch-bar-label .tiny { display: block; }
.ch-bar-track { height: 11px; background: var(--panel-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.ch-bar-track span { display: block; height: 100%; border-radius: 999px; }
.ch-bar-value { font-size: 13px; font-weight: 700; color: var(--text-soft); font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; }
@media (max-width: 620px) {
  .ch-bar-row { grid-template-columns: minmax(100px, 1.4fr) minmax(60px, 2fr) auto; gap: 8px; }
  .ch-bar-label { font-size: 12.5px; }
}

.ch-columns { display: flex; align-items: flex-end; gap: 14px; margin-top: 16px; }
.ch-column { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.ch-column-value { font-size: 12.5px; font-weight: 700; color: var(--text-soft); margin-bottom: 4px; }
.ch-column-bar { width: 100%; max-width: 64px; border-radius: 8px 8px 0 0; }
.ch-column-label { font-size: 12px; color: var(--muted); margin-top: 6px; text-align: center; }

.ch-donut-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; margin-top: 14px; }
.ch-donut { flex: 0 0 auto; }
.ch-legend { display: grid; gap: 8px; min-width: 220px; flex: 1 1 220px; }
.ch-legend-row { display: grid; grid-template-columns: 12px 1fr auto auto; gap: 10px; align-items: center; font-size: 13.5px; }
.ch-legend-row i { width: 12px; height: 12px; border-radius: 3px; display: block; }
.ch-legend-row strong { font-variant-numeric: tabular-nums; }

.ch-stack { margin-top: 14px; }
.ch-stack-bar { display: flex; height: 14px; border-radius: 999px; overflow: hidden; background: var(--panel-2); border: 1px solid var(--border); }
.ch-stack-bar span { display: block; height: 100%; }
.ch-stack-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font-size: 12.5px; color: var(--text-soft); }
.ch-stack-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; margin-right: 6px; }

.ch-matrix { display: block; width: 100%; height: auto; margin-top: 12px; }
.ch-timeline { display: block; width: 100%; height: auto; margin-top: 12px; }

.ch-meter { margin-top: 10px; }
.ch-meter-bar { height: 9px; background: var(--panel-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.ch-meter-bar span { display: block; height: 100%; border-radius: 999px; }

/* A chart with its own heading and a sentence of explanation, so a picture never floats unexplained. */
.ch-figure { margin-top: 18px; padding: 18px 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--panel); }
.ch-figure h3 { margin: 0 0 4px; font-size: 16px; }
.ch-figure > p { margin: 0; font-size: 13.5px; color: var(--muted); }

/* The call graph, drawn. A reader decides where to start a migration from this picture, so it gets room, a light
   frame, and horizontal scroll rather than being squeezed to fit a column. */
.callgraph-frame {
  margin: 4px 0 18px; padding: 6px; overflow-x: auto;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.callgraph-frame svg.qr-callgraph { display: block; min-width: 640px; }
.qr-callgraph text { font-family: var(--mono); }

/* News and Media. A card grid where the media strip is a fixed ratio, so a feed with a mix of
   landscape and square images still lines up. The fallback is drawn locally rather than borrowed,
   because an item whose outlet offered no image must not be padded with someone else's. */
.news-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; align-items: start; }
.news-card { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
.news-card:hover { transform: none; }
.news-media { position: relative; aspect-ratio: 16 / 9; background: var(--panel-2); overflow: hidden; }
.news-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.news-fallback {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: linear-gradient(135deg, var(--ink-deep) 0%, var(--ink-mid) 60%, var(--accent-dark) 100%); color: #fff;
}
.news-fallback span { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: #b9c8e4; }
.news-fallback strong { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.news-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.news-source { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.tag.region { background: var(--accent-soft); color: var(--accent-dark); }
.news-card h3 { margin: 0; font-size: 17px; line-height: 1.35; }
.news-card h3 a { color: var(--ink-deep); text-decoration: none; }
.news-card h3 a:hover { color: var(--accent); }
.news-summary { color: var(--muted); font-size: 14.5px; line-height: 1.6; margin: 0; }
.news-credit { margin-top: auto; padding-top: 10px; font-size: 11.5px; color: var(--muted); border-top: 1px solid var(--border); }
.news-editorial { color: var(--text-soft); font-size: 14.5px; }
.news-editorial p { margin: 0 0 10px; }
.news-editorial p:last-child { margin-bottom: 0; }

/* One title and one line of status. The digest used to sit below an eyebrow, an h1 and a "Latest"
   banner, which pushed the news off the top of the page before a reader reached it. */
.news-head { padding: 36px 0 6px; }
.news-head h1 { margin: 0; }
.news-head p { margin: 9px 0 0; }
.news-editorial-heading { margin: 0 0 20px; font-size: 22px; }

/* The signup is a panel, not a section of its own: it keeps its own heading and one sentence. */
.news-subscribe { padding: 20px 22px; }
.news-subscribe h2 { font-size: 20px; margin-bottom: 6px; }
.news-subscribe .field-row { margin-top: 4px; }

/* Long-form editorial. One column, because a 900-word article in a card grid is unreadable, and the
   measure is capped so a long line does not force the eye back to the start of the next one. */
.news-articles { display: flex; flex-direction: column; gap: 30px; }
.news-article {
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
}
/* Capped rather than full bleed: at the full card width a 16:9 illustration is taller than a phone
   screen and dominates the article it belongs to. It stays left aligned with the text column. The
   aspect ratio reserves the space before the image loads, so the text below it does not jump. */
.news-article .news-article-media { max-width: 620px; margin: 0 0 22px; border-radius: var(--radius-sm); overflow: hidden; background: var(--panel-2); aspect-ratio: 16 / 9; }
.news-article .news-article-media img { width: 100%; height: 100%; display: block; object-fit: contain; }
.news-article-content { padding: 24px 30px 30px; }
/* Cap the measure on the prose, not on the image. */
.news-article-content > *,
.news-article-content .news-editorial { max-width: 760px; }
.news-article-title { margin: 6px 0 12px; font-size: 28px; line-height: 1.24; color: var(--ink-deep); letter-spacing: -0.01em; }
.news-article-standfirst { margin: 0 0 22px; font-size: 17.5px; line-height: 1.6; color: var(--text-soft); }
.news-article .news-editorial { font-size: 16.5px; }
.news-article .news-editorial p { margin: 0 0 16px; line-height: 1.72; }
.news-article .news-editorial h2 { margin: 28px 0 10px; font-size: 19px; line-height: 1.35; color: var(--ink-deep); }
.news-article .news-editorial h2:first-child { margin-top: 4px; }
.news-article .news-credit { margin-top: 22px; }
@media (max-width: 640px) {
  .news-article-content { padding: 20px 18px 24px; }
  .news-article-title { font-size: 23px; }
}
.news-subscribe .field-row { margin-top: 4px; }
.news-consent { display: flex; gap: 9px; align-items: flex-start; margin: 12px 0 4px; font-size: 13px; color: var(--muted); }
.news-consent input { margin-top: 3px; }


/* ---------------- home: the product overview film ---------------- */
/* The film sits between the free scan and the platform pillars, so the hero keeps the fold and the
   film reads as supporting content rather than as a second hero. The poster is a button, so the
   file is fetched only when a visitor presses play: `preload` is none and there is no autoplay.
   The poster is the title card, which already fills the middle of the frame with the mark and the
   name, so the button goes in the empty band along the bottom rather than over the wordmark. */
/* Capped narrower than .wrap on purpose. At the full 1076px content width a 16:9 film is 605px
   tall, which is about 77% of the fold on a 13-inch laptop: the video and the header were the
   whole first screen. 960px keeps it substantial (540px tall, about 68%) and reads closer to how
   a mid-page product video is normally sized. The captions are drawn into the video, so they
   scale with it: 38px of caption text lands near 19px on screen at this width. */
.film {
  position: relative; margin: 0 auto; max-width: 960px;
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; background: var(--ink-deep); box-shadow: var(--shadow);
}
.film-stage { position: relative; }
.film video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: var(--ink-deep); }
/* No native bar until playback: it would otherwise overlap the poster button along the bottom. */
.film video:not([controls]) { pointer-events: none; }
.film figcaption { padding: 11px 16px; }
.film-play {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: 14px;
  width: 100%; padding: 22px 24px 18px; border: 0; color: #fff;
  font: inherit; text-align: left; cursor: pointer;
  background: linear-gradient(0deg, rgba(7, 18, 39, 0.86) 0%, rgba(7, 18, 39, 0.55) 52%, rgba(7, 18, 39, 0) 100%);
}
.film-play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; }
.film-play-icon {
  display: grid; place-items: center; flex: 0 0 auto; width: 58px; height: 58px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 10px 26px rgba(36, 87, 230, 0.45); transition: transform 0.15s ease;
}
.film-play:hover .film-play-icon { transform: scale(1.06); }
.film-play-icon svg { width: 26px; height: 26px; margin-left: 2px; }
.film-play-label { font-weight: 600; letter-spacing: 0.2px; }
.film.is-playing .film-play, .film.is-playing figcaption { display: none; }
@media (max-width: 640px) {
  .film-play { padding: 16px 16px 12px; gap: 11px; }
  .film-play-icon { width: 46px; height: 46px; }
  .film-play-icon svg { width: 21px; height: 21px; }
  .film-play-label { font-size: 14px; }
}
