/* nd3fense.com. The nD3FENSE design system, implemented for a static site.

   `brand/` holds the system itself: the brand book, every token with the
   contrast reasoning behind its value, and each component's guidelines. This
   file is that system expressed as CSS for one page, and where the two could
   disagree, `brand/` is right. Read it before changing a value here.

   Two things constrain how this is written, and both come from
   `firebase.json`'s Content Security Policy, which allows same-origin files
   only:

     - no <style> block and no style attribute anywhere in the site, which is
       why every width and accent the design spike set inline is a class at
       the bottom of this file;
     - no third-party request, which is why all four typefaces are self-hosted.

   The design system also ships `components/bundle.css`. The site does not load
   it. There is no build step, and the CSP would have to allow another origin,
   so the components are reimplemented below. That is a copy, and a copy can drift:
   when a component's guidelines change in `brand/`, check this file in the
   same commit. */

/* ── Typefaces ───────────────────────────────────────────────────────────
   Latin subsets, self-hosted, all four under the SIL Open Font License
   (fonts/OFL-*.txt). Orbitron and IBM Plex Sans are variable files covering
   the weight range the system uses; IBM Plex Mono ships one file per weight.
   Fonts are cached for a year, so rename a file when replacing it.

   Orbitron replaced Archivo when the brand book settled on it: a wide,
   geometric face that reads as instrument rather than brand deck, chosen to
   match a system drawn as a star chart. It carries H1, H2, the statistic
   figures and the wordmark, and deliberately not H3; see that rule. */
@font-face {
  font-family: "Orbitron"; font-style: normal; font-weight: 400 900; font-display: swap;
  src: url("fonts/orbitron-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400 500; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-500.woff2") format("woff2");
}

/* ── Tokens ──────────────────────────────────────────────────────────────
   Dark is the primary theme and is what :root carries; light is additive and
   arrives under prefers-color-scheme below. Every value is the brand's, and
   several of them are the result of contrast arithmetic recorded in
   `brand/tokens.json`. Do not round one off without reading its usage note.

   The status scale is three colors and a pattern, never more:
     cyan     at or above target
     lavender below target, in progress
     magenta  deficient
     hatch    not assessed, a pattern rather than a hue, because nobody
              having looked yet is not the bottom of a scale
   Teal acts: it is the only fill a person can press. The wordmark takes soft
   white, so no status color is spent on something that carries no status. */
:root {
  --ground: #080a18;
  --ground-deep: #04050e;
  --panel: #141733;
  --panel-raised: #1b1f42;
  --line: #262b52;
  --line-strong: #34395e;

  --text: #f2f1f8;
  --muted: #a9a4c6;
  /* Retuned from the spike's #7b799f, which cleared `ground` and
     `ground-deep` and dropped to about 4.2:1 on `panel`, under the floor,
     and the panel is exactly where the instrument's footer eyebrows sit.
     This value clears all three while staying a step quieter than `muted`. */
  --faint: #8482a7;

  --magenta: #f565dc;
  --lavender: #bfa9de;
  --cyan: #5cc6dc;
  /* The identity teal, shown as a pigment and never as a button: white on it
     reads about 3.8:1, and a button's label has to clear 4.5:1 at rest and on
     hover alike. `--teal-deep` rests, `--teal-hover` hovers; both hold one
     value in either theme, because a button supplies its own ground. */
  --teal: #10938f;
  --teal-deep: #0c7b78;
  --teal-hover: #0d8480;
  --navy: #34395e;

  --shadow-panel: 0 24px 70px rgba(3, 5, 15, 0.6);

  /* The hero's sky, as one value per layer so the light theme can restate it
     rather than fight it. Hand-placed rather than random, so nothing lands
     under the headline, and no animation: a starfield drifting behind reading
     text is decoration fighting the type. */
  --sky-nebula:
    radial-gradient(40% 48% at 72% 18%, rgba(92, 198, 220, 0.16), transparent 70%),
    radial-gradient(34% 42% at 18% 74%, rgba(245, 101, 220, 0.12), transparent 72%),
    radial-gradient(46% 42% at 46% 2%, rgba(16, 147, 143, 0.14), transparent 70%),
    radial-gradient(28% 34% at 88% 62%, rgba(191, 169, 222, 0.09), transparent 74%);
  --sky-stars:
    radial-gradient(1.3px 1.3px at 8% 18%, rgba(242, 241, 248, 0.65), transparent),
    radial-gradient(1px 1px at 22% 62%, rgba(242, 241, 248, 0.4), transparent),
    radial-gradient(1.1px 1.1px at 35% 12%, rgba(92, 198, 220, 0.6), transparent),
    radial-gradient(1px 1px at 48% 84%, rgba(242, 241, 248, 0.35), transparent),
    radial-gradient(1.4px 1.4px at 63% 34%, rgba(242, 241, 248, 0.55), transparent),
    radial-gradient(1px 1px at 71% 72%, rgba(191, 169, 222, 0.6), transparent),
    radial-gradient(1.1px 1.1px at 84% 26%, rgba(242, 241, 248, 0.42), transparent),
    radial-gradient(1px 1px at 92% 58%, rgba(242, 241, 248, 0.3), transparent),
    radial-gradient(1.2px 1.2px at 57% 8%, rgba(242, 241, 248, 0.35), transparent),
    radial-gradient(1px 1px at 14% 40%, rgba(245, 101, 220, 0.45), transparent);

  /* The recurring gaps and paddings, named. The brand book's own note applies:
     where a component's literal value falls a pixel or two off the nearest
     step, the component is authoritative. */
  --space-1: 4px;
  --space-2: 6px;
  --space-3: 8px;
  --space-4: 12px;
  --space-5: 14px;
  --space-6: 16px;
  --space-7: 20px;
  --space-8: 22px;
  --space-9: 24px;

  --radius-sm: 3px;
  --radius-pill: 99px;

  --sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --display: "Orbitron", ui-sans-serif, system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", monospace;

  --gutter: clamp(16px, 5vw, 56px);
  color-scheme: dark light;
}

/* The light theme. Additive, never a replacement: the neutrals invert, and
   the three hues that also serve as text are deepened rather than reused:
   at their dark-theme brightness they read under 4.5:1 on a light ground.
   `navy` goes the other way, lighter rather than deeper, because `muted` in
   light sits at a luminance no darker value in that hue family can clear.
   The teals do not move at all. */
@media (prefers-color-scheme: light) {
  :root {
    --ground: #f5f4fa;
    --ground-deep: #ecebf5;
    --panel: #ffffff;
    --panel-raised: #e5e3f0;
    --line: #e2dff0;
    --line-strong: #8981b3;

    --text: #161a33;
    --muted: #5b5578;
    --faint: #615b82;

    --magenta: #c81f9e;
    --lavender: #6b4fa0;
    --cyan: #0a6f81;
    --navy: #dbdce6;

    /* The theme's own ink at low alpha, so elevation reads as a soft lift
       rather than the dark theme's near-black halo showing through. */
    --shadow-panel: 0 20px 48px rgba(22, 26, 51, 0.14);

    /* The same nebula placements, at the deepened hues and lower alpha, so it
       reads as a tinted sky rather than a washed-out one. The stars are the theme's ink
       instead of soft white, which is the only way a point of light reads at
       all on a near-white ground. */
    --sky-nebula:
      radial-gradient(40% 48% at 72% 18%, rgba(10, 111, 129, 0.10), transparent 70%),
      radial-gradient(34% 42% at 18% 74%, rgba(200, 31, 158, 0.07), transparent 72%),
      radial-gradient(46% 42% at 46% 2%, rgba(12, 123, 120, 0.09), transparent 70%),
      radial-gradient(28% 34% at 88% 62%, rgba(107, 79, 160, 0.07), transparent 74%);
    --sky-stars:
      radial-gradient(1.3px 1.3px at 8% 18%, rgba(22, 26, 51, 0.45), transparent),
      radial-gradient(1px 1px at 22% 62%, rgba(22, 26, 51, 0.28), transparent),
      radial-gradient(1.1px 1.1px at 35% 12%, rgba(10, 111, 129, 0.5), transparent),
      radial-gradient(1px 1px at 48% 84%, rgba(22, 26, 51, 0.24), transparent),
      radial-gradient(1.4px 1.4px at 63% 34%, rgba(22, 26, 51, 0.38), transparent),
      radial-gradient(1px 1px at 71% 72%, rgba(107, 79, 160, 0.45), transparent),
      radial-gradient(1.1px 1.1px at 84% 26%, rgba(22, 26, 51, 0.3), transparent),
      radial-gradient(1px 1px at 92% 58%, rgba(22, 26, 51, 0.22), transparent),
      radial-gradient(1.2px 1.2px at 57% 8%, rgba(22, 26, 51, 0.24), transparent),
      radial-gradient(1px 1px at 14% 40%, rgba(200, 31, 158, 0.35), transparent);
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 72px; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding-inline: var(--gutter);
}

a { color: inherit; }
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* The gradients the identity mark's three stars sit on. One set, defined once
   in a hidden <svg>, referenced by both lockups. The stop colors are set
   here rather than as attributes so the mark follows the theme. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.g-cyan { stop-color: var(--cyan); }
.g-magenta { stop-color: var(--magenta); }
.g-lavender { stop-color: var(--lavender); }

/* Off-screen for a sighted reader, read aloud for everybody else. The
   briefing form is a third party's page and opens in a new tab, which a screen
   reader has no way to know unless the link says so. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

/* The address, wherever it appears: underlined rather than colored, because
   cyan means at-or-above-target in this palette and a mailbox carries no
   status. */
.mail, .footBadges a[href^="mailto:"] { text-decoration: underline; text-underline-offset: 2px; }
.mail:hover, .footBadges a[href^="mailto:"]:hover { color: var(--cyan); }

/* Off-screen until focused, so a keyboard reaches the content without
   walking the navigation first. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 30;
  padding: 10px var(--space-6); background: var(--panel-raised); color: var(--text);
  font-family: var(--mono); font-size: 12px; text-decoration: none;
}
.skip:focus { left: 0; }

/* ── Type styles ─────────────────────────────────────────────────────────
   The brand book's styles, one rule each. H3 borrows `--sans` on purpose:
   at 17px, real multi-word labels turn mushy in Orbitron, whose counters are
   cut for large geometric caps rather than small mixed-case reading. That is
   a documented exception in the system, not an oversight here. */
.eyebrow {                                        /* mono-eyebrow */
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.3;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0;
}

h1, h2 { font-family: var(--display); text-wrap: balance; margin: 0; }
h3 { font-family: var(--sans); text-wrap: balance; margin: 0; }
h1 { font-size: clamp(34px, 5.4vw, 60px); line-height: 1.02; letter-spacing: -0.025em; font-weight: 700; }
h2 { font-size: clamp(23px, 3vw, 32px); line-height: 1.12; letter-spacing: -0.018em; font-weight: 600; }
h3 { font-size: 17px; line-height: 1.3; letter-spacing: -0.005em; font-weight: 600; }
p { margin: 0; }
.lede { color: var(--muted); font-size: clamp(15px, 1.5vw, 17px); max-width: 56ch; }

/* ── Header ──────────────────────────────────────────────────────────── */
header.top {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 20;
  background: color-mix(in srgb, var(--ground-deep) 86%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topRow { display: flex; align-items: center; gap: var(--space-8); padding-block: 13px; }

/* The lockup: icon on the left, wordmark beside it, gap space-4. This is the
   primary mark wherever there is room for both; the icon alone is for a
   square only. The icon renders a touch taller than the wordmark's
   cap-height, because the constellation's loose points read visually lighter
   than the solid letterforms and want the extra room.

   The wordmark is one color, whole. An earlier three-run split was tried and
   dropped: it read as three separate words, and it spent two of the status
   colors on something that carries no status. */
.mark {
  display: inline-flex; align-items: center; gap: var(--space-4);
  text-decoration: none; white-space: nowrap;
}
.mark .word {                                     /* display-wordmark */
  font-family: var(--display); font-weight: 700; font-size: 17px;
  line-height: 1; letter-spacing: 0.14em; color: var(--text);
}
.icon { display: block; flex: none; }
.icon .i-line { stroke: var(--muted); fill: none; stroke-width: 1; }
.icon .s-cyan { fill: var(--cyan); }
.icon .s-magenta { fill: var(--magenta); }
.icon .s-lavender { fill: var(--lavender); }
.icon .s-text { fill: var(--text); }

nav.links { margin-left: auto; display: flex; gap: var(--space-7); }
nav.links a {
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); text-decoration: none;
}
nav.links a:hover { color: var(--text); }
@media (max-width: 720px) { nav.links { display: none; } }

/* Two variants, filled and quiet, never a third; one primary action per view.
   Labels are mono-label, uppercase, two or three words. A button label never
   wraps to a second line. */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: 9px var(--space-6); border-radius: var(--radius-sm);
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none;
  border: 1px solid transparent; cursor: pointer;
}
/* White on `--teal-deep` clears about 5.1:1, and on `--teal-hover` about
   4.5:1. The identity `--teal` reads 3.8:1 under white and is not a button
   fill in either state. */
.btn-primary { background: var(--teal-deep); color: #ffffff; border-color: var(--teal-deep); }
.btn-primary:hover { background: var(--teal-hover); border-color: var(--teal-hover); }
.btn-quiet { color: var(--text); border-color: var(--line-strong); background: transparent; }
.btn-quiet:hover { border-color: var(--cyan); color: var(--cyan); }
/* Below 720px the header carries the mark alone. A walkthrough is still one
   scroll away, since the hero's own primary button is the same action, and
   there is not room beside the lockup for the label without wrapping it,
   which a button label never does. */
@media (max-width: 720px) { header.top .btn { display: none; } }

/* ── Hero, on a sky ──────────────────────────────────────────────────── */
.sky {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}
.sky::before {
  content: "";
  position: absolute; inset: -20% -10% auto -10%; height: 150%;
  z-index: -2;
  background: var(--sky-nebula);
}
.sky::after {
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  background-image: var(--sky-stars);
  background-repeat: no-repeat;
}

.hero { padding-block: clamp(40px, 7vw, 84px) clamp(34px, 5vw, 60px); }
.heroGrid {
  display: grid; gap: clamp(28px, 4vw, 54px);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: start;
}
@media (max-width: 900px) { .heroGrid { grid-template-columns: minmax(0, 1fr); } }
.heroCopy { display: grid; gap: var(--space-7); justify-items: start; }
.heroCopy h1 span { color: var(--cyan); }
.actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* The instrument: what the product shows, rendered as the product shows it.
   The system's only shadow, spent once here. Never a general card shadow. */
.instrument {
  border: 1px solid var(--line-strong);
  background: var(--panel);
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: var(--shadow-panel);
}
.instHead {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-6); border-bottom: 1px solid var(--line); background: var(--ground-deep);
}
.instBody { display: grid; gap: var(--space-5); padding: var(--space-7); }

.domain { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: var(--space-4); align-items: center; }
.domain .code {                                   /* mono-data */
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--muted);
}
.track { height: 6px; border-radius: var(--radius-pill); background: var(--panel-raised); overflow: hidden; }
.fill { height: 100%; border-radius: var(--radius-pill); background: var(--cyan); }
.fill.holding { background: var(--lavender); }
.fill.short { background: var(--magenta); }
.fill.none { background: repeating-linear-gradient(90deg, var(--line-strong) 0 4px, transparent 4px 8px); }

/* The scale, named. A galaxy palette earns its place in GRC by being legible
   as status, so the page says which color means what rather than leaving a
   reader to infer it from a bar. Shown once, under the first group of rows. */
.legend {
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
  padding: 11px var(--space-6); border-top: 1px solid var(--line); background: var(--ground-deep);
}
.legend span {                                    /* mono-eyebrow */
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--faint);
}
.legend i { width: 14px; height: 4px; border-radius: var(--radius-pill); display: inline-block; }
.legend .k-met { background: var(--cyan); }
.legend .k-hold { background: var(--lavender); }
.legend .k-short { background: var(--magenta); }
.legend .k-none { background: repeating-linear-gradient(90deg, var(--line-strong) 0 4px, transparent 4px 8px); }
.domain .score {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.domain .score.dim { color: var(--faint); }

.instFoot {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}
.instFoot div { padding: var(--space-4) var(--space-6); }
.instFoot div + div { border-left: 1px solid var(--line); }
.instFoot .big {                                  /* mono-stat */
  font-family: var(--mono); font-size: 19px; line-height: 1.2;
  color: var(--text); font-variant-numeric: tabular-nums;
}
/* Lavender is the scale's "in progress", which is what a decision nobody has
   made yet is. Not magenta: magenta means deficient, and a count of pending
   decisions is not a maturity that fell short. */
.instFoot .big.pending { color: var(--lavender); }
/* The denominator beside a figure: quieter, and never the same size. */
.instFoot .of { color: var(--faint); font-size: 13px; }

/* ── Figures strip ───────────────────────────────────────────────────── */
.figures { border-bottom: 1px solid var(--line); background: var(--ground-deep); }
.figureGrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 760px) { .figureGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.figure { padding: var(--space-8) 0; }
.figureGrid > .figure + .figure { border-left: 1px solid var(--line); padding-left: var(--space-8); }
@media (max-width: 760px) {
  .figureGrid > .figure { padding-left: 0; border-left: 0; }
  .figureGrid > .figure:nth-child(even) { border-left: 1px solid var(--line); padding-left: var(--space-8); }
}
.figure .n {                                      /* display-figure */
  font-family: var(--display); font-weight: 600; font-size: clamp(24px, 3vw, 32px);
  line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.figure .cap { color: var(--muted); font-size: 13px; margin-top: var(--space-1); max-width: 26ch; }

/* ── Frameworks, set as type ─────────────────────────────────────────────
   This is where a logo wall would go, and no publisher's mark may appear
   here: ISO, NIST, MITRE, CIS and The Cyber AB each forbid or gate it, and
   SCF publishes no terms at all. AGENTS.md has the table. The substitute is
   the names in the brand's own framework-tag style, which is ours to set and
   needs nobody's permission.

   Chips rather than a dotted run: at eighteen names a separator dot strands
   itself at the end of every wrapped line, and a bordered tag reads as a list
   of things rather than a sentence that ran on. */
.frameworks { border-bottom: 1px solid var(--line); padding-block: clamp(30px, 4vw, 46px); }
.fwList {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  margin: var(--space-6) 0 0; padding: 0; list-style: none;
}
.fwList li {                                      /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-4);
}

/* ── Sections ────────────────────────────────────────────────────────── */
section.band { padding-block: clamp(56px, 8vw, 104px); }
/* The capability sections sit close together. Each is a title, a line and a
   picture, so a full band of air between them read as five separate pages
   rather than one platform, and most of the scroll was empty. */
section.band.feature { padding-block: clamp(28px, 4vw, 48px); }
section.band.feature#posture { padding-top: clamp(48px, 6vw, 80px); }
section.band.feature#about { padding-block: clamp(48px, 6vw, 80px); }
.bandHead { display: grid; gap: var(--space-4); max-width: 62ch; margin-bottom: clamp(34px, 5vw, 56px); }

/* One control, four frameworks. The claim the whole product rests on. */
.cross { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr); gap: clamp(16px, 3vw, 32px); align-items: center; }
@media (max-width: 820px) { .cross { grid-template-columns: minmax(0, 1fr); } }
.source {
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: linear-gradient(180deg, var(--panel-raised), var(--panel));
  padding: var(--space-7);
}
.source .id { font-family: var(--mono); font-size: 13px; color: var(--magenta); letter-spacing: 0.08em; }
.source .name {                                   /* display-sm */
  font-family: var(--sans); font-weight: 600; font-size: 17px;
  line-height: 1.3; letter-spacing: -0.005em; margin-top: var(--space-1);
}
.source .say { color: var(--muted); font-size: 13px; margin-top: var(--space-3); }
/* The readout wraps to its own line rather than breaking mid-phrase: at
   mono-data's tracking "Level 3 · target 4" is a few pixels wider than what
   is left beside the pips in a 260px card. */
.source .lvl {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--line-strong);
}
.pips { display: flex; gap: 3px; }
.pip { width: 12px; height: 6px; border-radius: 1px; background: var(--line); }
.pip.on { background: var(--cyan); }
.lvlText {                                        /* mono-data */
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em;
  color: var(--muted); font-variant-numeric: tabular-nums;
}

.answers { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.answer {
  display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: var(--space-5);
  padding: var(--space-5) var(--space-7); background: var(--panel); align-items: baseline;
}
@media (max-width: 520px) { .answer { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); } }
.answer .fw {                                     /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.answer .ref { font-family: var(--mono); font-size: 12.5px; line-height: 1.4; color: var(--cyan); }
.answer .txt { color: var(--text); font-size: 14px; }
.crossNote {                                      /* mono-note */
  font-family: var(--mono); font-size: 12.5px; line-height: 1.4;
  color: var(--faint); margin-top: var(--space-5);
}

/* Propose, then adopt. Three roles, in order, because the order is the point. */
.flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-sm); }
@media (max-width: 820px) { .flow { grid-template-columns: minmax(0, 1fr); } }
.step { background: var(--panel); padding: var(--space-9); display: grid; gap: var(--space-3); align-content: start; }
.step .role {                                     /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--lavender);
}
.step .role em { font-style: normal; color: var(--faint); }
.step p { color: var(--muted); font-size: 14px; }
.step .out { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--cyan); margin-top: var(--space-1); }

/* ── A capability section ────────────────────────────────────────────────
   The section title is the category a buyer already has a word for: Security
   posture, Vulnerability management, Risk management. It replaced a sentence
   ("The whole program, in one record") because a sentence is something a
   reader has to parse before they can decide whether this section is theirs.

   These sections carry no eyebrow, and that is a deliberate departure from the
   brand book's one-eyebrow rule. The rule exists so somebody scanning knows
   what a band is about; when the H2 IS the category, an eyebrow above it says
   the same thing twice, which the same brand book's voice rules forbid.

   `Learn more` is a <details>, not a link, because there are no sub-pages yet
   and a button that promises more has to deliver some. It is a native
   disclosure: keyboard reachable, announced correctly, and working with
   scripting off, which matters under a Content Security Policy that allows no
   inline script. When sub-pages exist, this becomes an anchor. */
.feature .featureHead { display: grid; gap: var(--space-4); max-width: 62ch; margin-bottom: clamp(28px, 4vw, 40px); }

/* ── The drawn views ─────────────────────────────────────────────────────
   Each capability section shows the product doing the thing rather than a
   paragraph claiming it does. They are drawn in HTML against the same tokens
   as everything else, not exported as images, for three reasons: they follow
   the theme, they stay legible at any zoom, and they cost nothing to keep
   current when a screen changes. The CSP forbids no part of it.

   They reuse the hero instrument's chrome (`.instrument`, `.instHead`), so a
   reader who has understood the panel at the top understands these on sight.

   **Everything in them is a real shape from the product**: a control's own
   maturity scale with its target marked, a triage queue keyed on the condition
   rather than the host, a probability-by-impact plot with the residual as its
   own point, a proposal nobody has adopted. Do not invent a screen the
   application cannot show. */
.viz { margin-top: clamp(28px, 4vw, 40px); max-width: 720px; }

.row { display: grid; grid-template-columns: 92px auto minmax(0, 1fr); gap: var(--space-4); align-items: center; }
.row .k {                                         /* mono-eyebrow */
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--faint);
}
.row .v { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--text); }
.row .v.wide { grid-column: 2 / -1; }

/* A control's maturity, drawn the way the control page draws it: the recorded
   level filled, the target outlined. Never both in one fill, or a reader
   cannot tell what was measured from what was chosen. */
.scale { display: inline-flex; gap: 3px; }
.scale i { width: 22px; height: 8px; border-radius: 1px; background: var(--line); display: block; }
.scale i.on { background: var(--cyan); }
.scale i.target { background: transparent; border: 1px solid var(--cyan); }

/* The triage queue. One row is one condition, and the host count is the whole
   argument: forty machines failing one check is one decision. */
.q { display: grid; gap: 1px; background: var(--line); }
.qRow {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-4);
  padding: var(--space-5) var(--space-7); background: var(--panel); align-items: center;
}
.qWhat { font-size: 14px; color: var(--text); }
.qId { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--muted); margin-right: var(--space-2); }
.hosts { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--muted); white-space: nowrap; }
.sev {
  font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.12em;
  padding: 3px 7px; border-radius: var(--radius-sm); white-space: nowrap;
}
.sev.cat1 { color: var(--magenta); border: 1px solid var(--magenta); }
.sev.cat2 { color: var(--lavender); border: 1px solid var(--lavender); }
.kev { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; color: var(--magenta); border: 1px solid var(--magenta); border-radius: var(--radius-sm); padding: 2px 5px; margin-left: var(--space-2); }
.qRow.set .qWhat, .qRow.set .qId { color: var(--faint); }
.aside { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--faint); margin-left: var(--space-2); }

/* Probability by impact. The grid is deliberately uncolored: a heat ramp would
   invent a fourth status scale, and this palette has exactly three colors and
   a hatch. Position carries the reading; the markers carry which risk. */
.matrixWrap { grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: clamp(20px, 3vw, 36px); }
@media (max-width: 620px) { .matrixWrap { grid-template-columns: minmax(0, 1fr); } }
.matrix { display: grid; grid-template-columns: auto 1fr; grid-template-rows: 1fr auto; gap: var(--space-2); }
.matrix .grid { display: grid; grid-template-columns: repeat(5, 22px); grid-auto-rows: 22px; gap: 3px; }
.matrix .grid i { background: var(--panel-raised); border-radius: 1px; display: block; }
.matrix .grid i.hit { background: var(--magenta); }
.matrix .grid i.residual { background: var(--lavender); }
.axisY, .axisX {                                  /* mono-eyebrow */
  font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--faint); align-self: center;
}
.axisY { writing-mode: vertical-rl; transform: rotate(180deg); }
.axisX { grid-column: 2; text-align: center; }
.matrixKey { display: grid; gap: var(--space-5); }
.dot { width: 10px; height: 10px; border-radius: 1px; display: inline-block; vertical-align: -1px; margin-right: var(--space-2); }
.dot.hit { background: var(--magenta); }
.dot.residual { background: var(--lavender); }

/* A proposal nobody has adopted. The two controls are drawn, not live: this is
   a picture of the product, and a button on a marketing page that looks like
   it acts and does not is worse than no button. */
.proposal { display: grid; gap: var(--space-3); }
.verdict { font-family: var(--mono); font-size: 19px; line-height: 1.2; color: var(--lavender); }
.quote { color: var(--text); font-size: 14px; max-width: 58ch; }
.src { color: var(--faint); font-size: 13px; }
.decide { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); margin-top: var(--space-3); padding-top: var(--space-5); border-top: 1px solid var(--line); }
.btn.fake { cursor: default; color: var(--muted); }
.decideNote { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.06em; color: var(--faint); }

/* Diagrams and documents. Both are generated from what the platform already
   holds, the inventory and the control record, and both are edited in place,
   so the pair sits side by side: the drawing, and the document it lands in.
   The architecture is drawn as SVG with its colors in classes, so it follows
   the theme like everything else. The CUI flow is cyan because the flow is
   what the diagram exists to show; the boundary crossing is magenta because
   that is the point an assessor stops at. */
.duo { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: var(--space-7); align-items: start; margin-top: clamp(28px, 4vw, 40px); }
@media (max-width: 900px) { .duo { grid-template-columns: minmax(0, 1fr); } }
.duo .viz { margin-top: 0; max-width: none; }

.arch { width: 100%; height: auto; display: block; }
.arch .encl { fill: none; stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 5 4; }
.arch .el { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.2em; fill: var(--faint); }
.arch .edge, .arch .edgeP { stroke: var(--line-strong); stroke-width: 1; fill: none; }
.arch .flow { fill: none; stroke: var(--cyan); stroke-width: 1.6; }
.arch .node { fill: var(--panel-raised); stroke: var(--line-strong); stroke-width: 1; }
.arch .node.out { fill: var(--panel); }
.arch .nl { font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; fill: var(--text); text-anchor: middle; }
.arch .cross { fill: var(--magenta); }
.archKey { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6); align-items: center; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint); }
.archKey span { white-space: nowrap; }
.archKey i { display: inline-block; margin-right: var(--space-2); vertical-align: middle; }
.kFlow { width: 16px; height: 2px; background: var(--cyan); }
.kCross { width: 8px; height: 8px; border-radius: 50%; background: var(--magenta); }

.ssp { gap: var(--space-5); }
.sspSec { display: flex; align-items: baseline; gap: var(--space-4); flex-wrap: wrap; }
.sspRef { font-family: var(--mono); font-size: 12.5px; color: var(--cyan); }
.sspTitle { font-weight: 600; font-size: 17px; line-height: 1.3; }
.chip { font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 3px 7px; }
.sspText { color: var(--muted); font-size: 14px; }
.formats { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint); padding-top: var(--space-4); border-top: 1px solid var(--line); }

/* About: a line, then three short facts in the framework-tag style. */
.facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-7) clamp(28px, 4vw, 52px); margin: clamp(24px, 3vw, 36px) 0 0;
  max-width: 980px;
}
@media (max-width: 760px) { .facts { grid-template-columns: minmax(0, 1fr); } }
.facts div { border-top: 1px solid var(--line-strong); padding-top: var(--space-5); }
.facts dt {                                       /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text);
}
.facts dd { margin: var(--space-2) 0 0; color: var(--muted); font-size: 14px; }

.contactNote { margin-top: var(--space-7); }

/* A tile states a fact and does not act: no button, no link inside one. */
.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-7); }
@media (max-width: 860px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .tiles { grid-template-columns: minmax(0, 1fr); } }
.tile {
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-7);
  background: var(--panel); display: grid; gap: var(--space-2); align-content: start;
}
.tile .k {                                        /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.tile p { color: var(--muted); font-size: 14px; }

/* ── Close and footer ────────────────────────────────────────────────── */
.close { border-top: 1px solid var(--line); padding-block: clamp(40px, 6vw, 72px); }
.closeRow { display: flex; flex-wrap: wrap; gap: var(--space-8); align-items: center; justify-content: space-between; }
.closeRow h2 { max-width: 30ch; }

footer { border-top: 1px solid var(--line); padding-block: var(--space-7); background: var(--ground-deep); }
.footCol { display: grid; gap: var(--space-4); }
/* Trust badges are loud on purpose: short, uppercase, tracked, meant to be
   noticed. A disclaimer is not one of them. */
.footBadges { display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-9); align-items: center; }
.footBadges span, .footBadges a {                 /* mono-label */
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.footBadges .mark .word { color: var(--text); }
.footBadges .sep { color: var(--line-strong); }
/* Fine print, treated as fine print: sentence case, sans, on its own line
   under the badges. Plainly worded and legible, and visually the quietest
   thing here. A disclaimer set in the badge row's tracked capitals reads as a
   claim, which is exactly what it is not. */
.footLegal { font-size: 11px; line-height: 1.4; color: var(--faint); }

/* ── 404 ─────────────────────────────────────────────────────────────── */
.lost { display: grid; gap: 18px; justify-items: start; padding-block: clamp(60px, 12vw, 140px); }

/* ── The readings, as classes ────────────────────────────────────────────
   The Content Security Policy forbids a style attribute, so the one thing
   that was inline in the design spike lives here: how far a domain's bar is
   filled. Each width is the domain's score over the scale's five points,
   which is why they are not round numbers. */
.fill.w-82 { width: 82%; }
.fill.w-70 { width: 70%; }
.fill.w-44 { width: 44%; }
.fill.w-36 { width: 36%; }
.fill.w-100 { width: 100%; }

/* One figure accent, in lavender, which is the one the brand book sanctions.
   The other three figures stay in `--text`: cyan is spoken for by the hero's
   accented word, and magenta means deficient, so spending it on "0 scores
   the platform decides for you" would color a good number as a bad one. */
.figure .n.is-accent { color: var(--lavender); }

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

/* ── Legal pages ─────────────────────────────────────────────────────────
   Privacy and Terms read as one column of plain sentences. Section heads use
   the h3 treatment (sans) because Orbitron at h2 size is a headline face,
   and these are signposts. */
.legal { display: grid; gap: var(--space-3); max-width: 68ch; padding-block: clamp(48px, 9vw, 110px); }
.legal h1 { margin-bottom: var(--space-2); }
.legal h2 { font-family: var(--sans); font-size: 19px; line-height: 1.3; letter-spacing: -0.005em; font-weight: 600; margin-top: var(--space-5); }
.legal p { color: var(--text); font-size: 16px; line-height: 1.6; margin: 0; }
.legal .lede { color: var(--muted); }
.legal .legal-date { color: var(--faint); font-family: var(--mono); font-size: 12px; letter-spacing: .04em; margin-top: var(--space-5); }
