/* Severity / grade / surface tokens (single source of truth shared
   with the HTML reporter). The @import must come before any other
   rule per CSS spec, hence the position above the comment block. */
@import "_design_tokens.css";

/* ============================================================
   Pipeline-Check — refined theme (modern, editorial)

   Design notes:
   - Single soft glow in the hero, no dual-radial layers.
   - Hairline cards with subtle border-color hover (no transform).
   - Plain-color line icons, no tinted backgrounds.
   - Tabular numerics on stats so digits feel solid.
   - Refined terminal chrome: filename pill, no traffic-light dots.
   - Consistent 5–6rem section rhythm; no banded alternation.
   ============================================================ */

:root {
  /* Brand palette */
  --pg-navy-950: #04101a;
  --pg-navy-900: #061826;
  --pg-navy-800: #0b3954;
  --pg-navy-700: #134e6f;
  /* teal-500 lifted from #087e8b to meet WCAG AA (4.5:1) on the
     dark slate background — Lighthouse flagged inline links and
     tab text at 3.59 / 4.24 ratios. New value reads ~5.5:1. */
  --pg-teal-500: #1ba3a9;
  --pg-teal-400: #33c4ca;
  --pg-teal-300: #6dd5ed;
  --pg-success-500: #2a9d8f;
  --pg-warn-500: #f4a261;
  --pg-crit-500: #ef476f;

  --pg-text-on-dark: #e7eef5;
  /* Brightened from #9fb3c8 to give the hero lede + meta extra
     contrast headroom over the brighter portions of the hero's
     radial-gradient glow. ~10.5:1 on the navy bg, ~5:1 over the
     glow center. */
  --pg-muted-on-dark: #b6c4d4;

  /* Material palette overrides (palette: custom) */
  --md-primary-fg-color:        #0b3954;
  --md-primary-fg-color--light: #134e6f;
  --md-primary-fg-color--dark:  #061826;
  --md-accent-fg-color:         #087e8b;

  /* Editorial spacing scale */
  --pg-space-section: clamp(4rem, 7vw, 6rem);
  --pg-radius-card:   14px;
  --pg-radius-pill:   999px;

  /* ============================================================
     DESIGN SYSTEM TOKENS (additive)
     Severity / grade / surface tokens live in
     pipeline_check/core/_design_tokens.css and arrive here via
     the @import at the top of this file. The --pg-* entries
     above are kept for back-compat with existing selectors and
     will retire as call sites move to the un-prefixed names.
     ============================================================ */

  /* Type families ------------------------------------------- */
  /* Mona Sans is the brand body face — see ``mkdocs.yml`` font.text
     for the rationale. The fallback chain keeps Inter as a graceful
     degrade (it's everywhere via Material's prior caching) rather
     than dropping straight to system-ui, which would shift to
     widely-different metrics on every OS. */
  --font-sans: "Mona Sans", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Type scale ---------------------------------------------- */
  --fs-display: clamp(2.4rem, 4.6vw, 3.6rem);
  --fs-h1:      clamp(1.85rem, 3vw, 2.3rem);
  --fs-h2-pg:   clamp(1.8rem, 3.2vw, 2.4rem);
  --fs-h2:      clamp(1.35rem, 2.2vw, 1.6rem);
  --fs-h3:      1.05rem;
  --fs-h4:      0.92rem;
  --fs-body:    0.86rem;
  --fs-lede:    1.05rem;
  --fs-small:   0.78rem;
  --fs-tiny:    0.72rem;
  --fs-eyebrow: 0.72rem;
  --fs-mono-sm: 0.74rem;
  --fs-mono-md: 0.84rem;

  /* Type weights -------------------------------------------- */
  /* Conventional stops — kept for back-compat with the 30+
     existing call sites that reference them and for terminal /
     log-output coloring where weight is a semantic signal, not a
     typographic refinement. */
  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-h:        650;
  --fw-bold:     700;
  /* Variable-axis stops — Mona Sans + JetBrains Mono are loaded as
     variable fonts (see ``docs/_overrides/main.html``) so values
     between the conventional stops render at their exact weight
     instead of snapping to the nearest static stop.
        --fw-refined  → editorial medium, slightly heavier than 500
        --fw-card-h   → between semibold and bold; refined H2/card titles
        --fw-display  → display moment for H1s and section titles
        --fw-stat     → ultra-display for the stat-row big numbers */
  --fw-refined: 540;
  --fw-card-h:  620;
  --fw-display: 720;
  --fw-stat:    760;

  /* Tracking (negative on display, positive on mono caps) --- */
  --ls-display:   -0.035em;
  --ls-h1:        -0.03em;
  --ls-h2:        -0.02em;
  --ls-h3:        -0.015em;
  --ls-body:       0;
  --ls-eyebrow:    0.18em;
  --ls-tab:        0.04em;
  --ls-uppercase:  0.12em;

  /* Line-height -------------------------------------------- */
  --lh-display: 1.05;
  --lh-heading: 1.15;
  --lh-body:    1.7;
  --lh-prose:   1.6;

  /* Radii (un-prefixed scale; --pg-radius-card kept for back-compat) */
  --radius-card:   14px;
  --radius-md:     12px;
  --radius-sm:     10px;
  --radius-xs:     8px;
  --radius-tiny:   4px;
  --radius-pill:   999px;

  /* Spacing (un-prefixed; --pg-space-section kept for back-compat) */
  --space-section: clamp(4rem, 7vw, 6rem);
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.25rem;
  --space-6:  1.5rem;
  --space-8:  2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;

  /* Elevation ---------------------------------------------- */
  --shadow-card:  0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-hover: 0 12px 28px -16px color-mix(in oklab, var(--pg-teal-500) 50%, transparent);
  --shadow-lift:  0 24px 48px -16px color-mix(in oklab, var(--pg-navy-900) 35%, transparent);
  --shadow-deep:  0 30px 60px -25px rgba(0, 0, 0, 0.6);

  /* Motion ------------------------------------------------- */
  --ease-out: cubic-bezier(0.2, 0.7, 0.3, 1);
  --dur-fast: 0.15s;
  --dur-mid:  0.18s;
  --dur-slow: 0.32s;

  /* Semantic mapping --------------------------------------- */
  --color-bg-app:       var(--md-default-bg-color);
  --color-fg-1:         var(--md-default-fg-color);
  --color-fg-2:         var(--md-default-fg-color--light);
  --color-fg-3:         var(--md-default-fg-color--lighter);
  --color-border:       var(--md-default-fg-color--lightest);
  --color-accent:       var(--pg-teal-500);
  --color-accent-hover: var(--pg-teal-400);
  --color-link:         var(--pg-teal-400);
}

[data-md-color-scheme="slate"] {
  /* Warmer slate than Material default. Canvas darkened from
     hsla(213, 22%, 11%) to hsla(213, 30%, 8%) so it stops reading
     as a different surface from the navy-950 top bar — the chrome
     and the canvas now belong to the same family, with the chrome
     just one step deeper. */
  --md-default-bg-color:                hsla(213, 30%, 8%, 1);
  --md-default-bg-color--light:         hsla(213, 28%, 12%, 1);
  --md-default-fg-color--lightest:      hsla(213, 18%, 20%, 1);
  --md-default-fg-color--lighter:       hsla(213, 12%, 60%, 1);
  --md-default-fg-color--light:         hsla(213, 10%, 78%, 1);
  --md-default-fg-color:                hsla(213, 10%, 92%, 1);
  --md-code-bg-color:                   hsla(213, 32%, 6%, 1);
  --md-code-fg-color:                   hsla(213, 12%, 88%, 1);

  --md-primary-fg-color:        #0b3954;
  --md-primary-fg-color--light: #134e6f;
  --md-primary-fg-color--dark:  #04101a;
  --md-accent-fg-color:         #1ba3a9;
}

/* ------------------------------------------------------------
   Inner-page polish
   ------------------------------------------------------------ */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.md-typeset {
  font-feature-settings: "kern", "liga", "calt";
  font-size: 0.86rem;
  line-height: 1.7;
}

/* ----- Heading rhythm ------------------------------------- */

.md-typeset h1,
.md-typeset h2,
.md-typeset h3 {
  letter-spacing: -0.02em;
  font-weight: 600;
  line-height: 1.25;
}

/* H1: page title with a small teal-gradient accent underline.
   Editorial accent, signals "page start" without an icon. */
.md-typeset h1 {
  font-size: clamp(1.85rem, 3vw, 2.3rem);
  letter-spacing: -0.03em;
  /* Variable-axis display weight — one notch above plain bold so
     every H1 across the site shares the hero's display moment. */
  font-weight: var(--fw-display);
  margin: 0 0 0.85rem;
}

.md-typeset h1::after {
  content: "";
  display: block;
  width: 56px;
  height: 3px;
  background: linear-gradient(90deg, var(--pg-teal-500) 0%, var(--pg-teal-300) 100%);
  border-radius: 2px;
  margin-top: 0.85rem;
  opacity: 0.95;
}

/* H2: left vertical accent bar. Reads as "new section" without
   an icon, and lets the eye scan the page for section starts. */
.md-typeset h2 {
  font-size: clamp(1.35rem, 2.2vw, 1.6rem);
  /* Variable-axis card-h: refined editorial weight, lighter than
     the previous 650 default. Tighter rhythm against the 720
     display weight on H1 above. */
  font-weight: var(--fw-card-h);
  margin: 3rem 0 1rem;
  padding-left: 1rem;
  position: relative;
}

.md-typeset h2::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35em;
  bottom: 0.25em;
  width: 3px;
  background: var(--pg-teal-500);
  border-radius: 2px;
  opacity: 0.85;
}

[data-md-color-scheme="slate"] .md-typeset h2::before {
  background: var(--pg-teal-400);
}

/* H3: simpler — no accent, just typographic distinction */
.md-typeset h3 {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 2rem 0 0.6rem;
  letter-spacing: -0.015em;
}

/* H4: smallest heading rung */
.md-typeset h4 {
  font-size: 0.92rem;
  font-weight: 600;
  margin: 1.5rem 0 0.5rem;
  text-transform: none;
  letter-spacing: 0;
}

/* Constrain prose width for readability — measure ~70-80 char */
.md-typeset p,
.md-typeset li,
.md-typeset blockquote {
  max-width: 64rem;
}

/* ----- Inline code & code blocks --------------------------- */

.md-typeset code {
  font-feature-settings: "calt" 0;
  border-radius: 4px;
  padding: 0.12em 0.4em;
  font-size: 0.86em;
  background: color-mix(in oklab, var(--md-default-bg-color) 90%, var(--pg-teal-500));
  color: var(--md-default-fg-color);
  border: 1px solid color-mix(in oklab, var(--md-default-bg-color) 80%, var(--pg-teal-500));
}

[data-md-color-scheme="slate"] .md-typeset code {
  background: color-mix(in oklab, var(--md-default-bg-color) 80%, var(--pg-teal-500));
  border-color: color-mix(in oklab, var(--md-default-bg-color) 70%, var(--pg-teal-500));
}

/* Pre/code blocks: rounded, hairline border, restful inner padding */
.md-typeset pre > code,
.md-typeset .highlight pre,
.md-typeset .codehilite pre {
  border-radius: 0;
  background: transparent;
  border: none;
  padding: 0.95rem 1rem;
}

.md-typeset .highlight,
.md-typeset .codehilite {
  border-radius: 10px;
  border: 1px solid var(--md-default-fg-color--lightest);
  overflow: hidden;
  margin: 1.25rem 0;
}

[data-md-color-scheme="slate"] .md-typeset .highlight,
[data-md-color-scheme="slate"] .md-typeset .codehilite {
  background: rgba(0, 0, 0, 0.25);
}

/* Reset inline code style INSIDE pre blocks (no extra background) */
.md-typeset pre code {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  font-size: 0.86rem !important;
}

/* ----- Brand-tinted links --------------------------------- */
.md-typeset a {
  color: var(--pg-teal-500);
  text-decoration-color: color-mix(in oklab, var(--pg-teal-500) 35%, transparent);
  text-underline-offset: 0.18em;
}
.md-typeset a:hover {
  text-decoration-color: var(--pg-teal-500);
}
[data-md-color-scheme="slate"] .md-typeset a {
  color: var(--pg-teal-400);
  text-decoration-color: color-mix(in oklab, var(--pg-teal-400) 40%, transparent);
}
[data-md-color-scheme="slate"] .md-typeset a:hover {
  text-decoration-color: var(--pg-teal-400);
}

/* External link arrow: small ↗ after links to other domains.
   Skips badges (img children) and self-links. */
.md-typeset a[href^="http"]:not([href*="dmartinochoa.github.io"]):not(:has(img))::after {
  content: " ↗";
  font-size: 0.85em;
  opacity: 0.45;
  margin-left: 0.05em;
  letter-spacing: 0;
  display: inline-block;
  transform: translateY(-0.05em);
}

/* ----- Tables --------------------------------------------- */
.md-typeset table:not([class]) {
  display: table;
  width: 100%;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 10px;
  overflow: hidden;
  font-size: 0.84rem;
  margin: 1.25rem 0;
  border-collapse: separate;
  border-spacing: 0;
}

.md-typeset table:not([class]) thead th {
  background: color-mix(in oklab, var(--md-default-bg-color) 92%, var(--pg-navy-700));
  font-weight: var(--fw-card-h);
  letter-spacing: -0.005em;
  text-align: left;
  padding: 0.7rem 0.95rem;
  border-bottom: 2px solid var(--pg-teal-500);
  font-size: 0.8rem;
  text-transform: none;
}

[data-md-color-scheme="slate"] .md-typeset table:not([class]) thead th {
  background: color-mix(in oklab, var(--md-default-bg-color) 75%, var(--pg-navy-700));
}

.md-typeset table:not([class]) td {
  padding: 0.65rem 0.95rem;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
  vertical-align: top;
}

.md-typeset table:not([class]) tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--md-default-bg-color) 96%, var(--pg-navy-900));
}

[data-md-color-scheme="slate"] .md-typeset table:not([class]) tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--md-default-bg-color) 90%, var(--pg-navy-900));
}

.md-typeset table:not([class]) tbody tr:hover td {
  background: color-mix(in oklab, var(--md-default-bg-color) 90%, var(--pg-teal-500));
}

.md-typeset table:not([class]) tbody tr:last-child td {
  border-bottom: none;
}

/* ----- Admonitions: 3-tone brand palette ------------------- */
/* Material ships ~12 types in a rainbow palette. Consolidate
   to: info (teal), caution (amber), danger (coral). */
.md-typeset .admonition,
.md-typeset details {
  border-radius: 10px;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-left: 3px solid var(--pg-teal-500);
  background: color-mix(in oklab, var(--md-default-bg-color) 96%, var(--pg-teal-500));
  box-shadow: none;
  font-size: 0.86rem;
}

[data-md-color-scheme="slate"] .md-typeset .admonition,
[data-md-color-scheme="slate"] .md-typeset details {
  background: color-mix(in oklab, var(--md-default-bg-color) 88%, var(--pg-teal-500));
}

.md-typeset .admonition-title,
.md-typeset summary {
  background: transparent !important;
  font-weight: 600;
  font-size: 0.86rem;
  letter-spacing: -0.005em;
  padding-block: 0.6rem !important;
}

.md-typeset .admonition-title::before,
.md-typeset summary::before {
  background-color: var(--pg-teal-500) !important;
}

/* Caution family: warning, bug, attention */
.md-typeset .admonition.warning,
.md-typeset .admonition.bug,
.md-typeset .admonition.attention,
.md-typeset details.warning,
.md-typeset details.bug,
.md-typeset details.attention {
  border-left-color: var(--pg-warn-500);
  background: color-mix(in oklab, var(--md-default-bg-color) 95%, var(--pg-warn-500));
}

.md-typeset .admonition.warning .admonition-title::before,
.md-typeset .admonition.bug .admonition-title::before,
.md-typeset .admonition.attention .admonition-title::before {
  background-color: var(--pg-warn-500) !important;
}

/* Danger family: danger, failure, error */
.md-typeset .admonition.danger,
.md-typeset .admonition.failure,
.md-typeset .admonition.error,
.md-typeset details.danger,
.md-typeset details.failure,
.md-typeset details.error {
  border-left-color: var(--pg-crit-500);
  background: color-mix(in oklab, var(--md-default-bg-color) 95%, var(--pg-crit-500));
}

.md-typeset .admonition.danger .admonition-title::before,
.md-typeset .admonition.failure .admonition-title::before,
.md-typeset .admonition.error .admonition-title::before {
  background-color: var(--pg-crit-500) !important;
}

/* ----- Blockquotes ---------------------------------------- */
.md-typeset blockquote {
  border-left: 3px solid var(--pg-teal-500);
  padding-left: 1rem;
  font-style: italic;
  color: var(--md-default-fg-color--light);
  margin: 1.25rem 0;
}

[data-md-color-scheme="slate"] .md-typeset blockquote {
  border-left-color: var(--pg-teal-400);
}

/* ----- Lists ---------------------------------------------- */
.md-typeset ul li::marker,
.md-typeset ol li::marker {
  color: var(--pg-teal-500);
}

[data-md-color-scheme="slate"] .md-typeset ul li::marker,
[data-md-color-scheme="slate"] .md-typeset ol li::marker {
  color: var(--pg-teal-400);
}

.md-typeset ul li,
.md-typeset ol li {
  margin-bottom: 0.35rem;
}

/* ----- Horizontal rule with editorial asterism ------------ */
.md-typeset hr {
  border: none;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--md-default-fg-color--lightest) 20%,
    var(--md-default-fg-color--lightest) 80%,
    transparent 100%);
  margin: 3rem 0;
  position: relative;
}

.md-typeset hr::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pg-teal-500);
  opacity: 0.65;
  box-shadow:
    0 0 0 4px var(--md-default-bg-color);
}

[data-md-color-scheme="slate"] .md-typeset hr::after {
  background: var(--pg-teal-400);
}

/* ============================================================
   Reading-progress bar
   ============================================================ */
/* Thin teal line at the very top of the viewport that fills as
   the page is scrolled. CSS-only via animation-timeline: scroll(),
   added as a body::before pseudo-element so no markup change is
   required. Browsers without scroll-driven animations: the line
   stays invisible (scaleX(0)) — graceful no-op. */

@supports (animation-timeline: scroll()) {
  body::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    height: 2px;
    width: 100%;
    background: linear-gradient(90deg,
      var(--pg-teal-500) 0%,
      var(--pg-teal-300) 100%);
    transform-origin: 0 50%;
    transform: scaleX(0);
    z-index: 1001;
    animation: pg-progress-fill linear;
    animation-timeline: scroll(root);
    pointer-events: none;
  }
}

@keyframes pg-progress-fill {
  to { transform: scaleX(1); }
}

/* ============================================================
   Documentation index cards (providers/, standards/)
   ============================================================ */

.pg-doc-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.85rem;
  margin: 2rem 0 3rem;
}

.pg-doc-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1.1rem 1.2rem 1.15rem;
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 12px;
  text-decoration: none !important;
  color: var(--md-default-fg-color);
  transition:
    border-color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease,
    background 0.18s ease;
  overflow: hidden;
}

.pg-doc-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 12px;
  pointer-events: none;
  background: linear-gradient(135deg,
    rgba(27, 163, 169, 0) 0%,
    rgba(27, 163, 169, 0) 60%,
    rgba(27, 163, 169, 0.06) 100%);
  opacity: 0;
  transition: opacity 0.18s ease;
}

.pg-doc-card:hover {
  border-color: var(--pg-teal-500);
  transform: translateY(-1px);
  box-shadow: 0 12px 28px -16px color-mix(in oklab, var(--pg-teal-500) 50%, transparent);
}

.pg-doc-card:hover::before {
  opacity: 1;
}

.pg-doc-card h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: var(--fw-card-h);
  letter-spacing: -0.02em;
  color: var(--md-default-fg-color);
}

.pg-doc-card p {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--md-default-fg-color--light);
  flex: 1;
}

/* Coverage meta line on standards cards — small monospace caption
   carrying the live "N controls · N checks evidenced" count. The
   ``mkdocs_standards_stats.py`` hook templates the numbers in at
   build time, so the figure can never drift from the registry. */
.pg-doc-card__meta {
  display: block;
  margin: 0.7rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--md-default-fg-color--lightest);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.7rem;
  color: var(--md-default-fg-color--light);
  letter-spacing: 0.01em;
}

.pg-doc-card:hover .pg-doc-card__meta {
  color: var(--pg-teal-500);
  border-top-color: color-mix(in oklab,
    var(--pg-teal-500) 30%,
    var(--md-default-fg-color--lightest) 70%);
}

[data-md-color-scheme="slate"] .pg-doc-card:hover .pg-doc-card__meta {
  color: var(--pg-teal-300);
}

.pg-doc-card__tag {
  display: inline-block;
  align-self: flex-start;
  margin: 0 0 0.55rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.18rem 0.45rem;
  border-radius: 4px;
  background: color-mix(in oklab, var(--md-default-bg-color) 85%, var(--pg-teal-500));
  color: var(--pg-teal-500);
  font-weight: 600;
}

[data-md-color-scheme="slate"] .pg-doc-card__tag {
  background: color-mix(in oklab, var(--md-default-bg-color) 75%, var(--pg-teal-500));
  color: var(--pg-teal-300);
}

.pg-doc-card__tag--accent {
  background: color-mix(in oklab, var(--md-default-bg-color) 85%, var(--pg-warn-500));
  color: var(--pg-warn-500);
}

[data-md-color-scheme="slate"] .pg-doc-card__tag--accent {
  background: color-mix(in oklab, var(--md-default-bg-color) 75%, var(--pg-warn-500));
  color: var(--pg-warn-500);
}

.pg-doc-card__meta {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--md-default-fg-color--lighter);
  letter-spacing: 0.02em;
  margin-top: 0.55rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--md-default-fg-color--lightest);
}

.pg-doc-card__meta code {
  font-size: 0.86em;
  padding: 0.1em 0.35em;
}

/* Strip external-link arrows from doc cards */
.pg-doc-card::after { content: "" !important; }

/* ------------------------------------------------------------
   Top bar — adapts to the page palette.
   Inner doc pages: header matches the body (white in light mode,
   slate in dark mode) with a hairline bottom border so it reads
   as part of the page rather than a separate dark band.
   Home page: header bleeds into the navy hero — same dark navy
   so the bar and hero gradient read as one continuous surface.
   ------------------------------------------------------------ */
/* Per .claude/design_system/IMPLEMENTATION.md: navy-950 chrome with a
   1px navy-700 border-bottom on every page. The home page used to
   carry a special override; that's no longer needed because every
   page now wears the same navy bar. */
.md-header,
.md-tabs {
  background: var(--pg-navy-950);
  color: var(--pg-text-on-dark);
  box-shadow: none;
  border-bottom: 1px solid var(--pg-navy-700);
}

.md-header[data-md-state="shadow"] {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
}

.md-header__title {
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--pg-text-on-dark);
}

.md-header__button {
  color: var(--pg-text-on-dark);
}
.md-header__button:hover { color: var(--pg-teal-400); }
[data-md-color-scheme="slate"] .md-header__button:hover { color: var(--pg-teal-400); }

/* Topbar logo intentionally suppressed. The wordmark
   "Pipeline-Check" already carries the brand in the chrome, and
   the goose mascot is reserved for the favicon, hero, and README.
   Hiding both the header and sidebar logo slots so Material's
   default-icon fallback never shows when ``logo:`` is unset. */
.md-header__button.md-logo,
.md-nav__button.md-logo {
  display: none;
}

/* Tabs row: tighter, more editorial */
.md-tabs__list {
  padding: 0 0.4rem;
}
.md-tabs__item {
  height: 2.4rem;
}
.md-tabs__link {
  font-size: 0.78rem;
  font-weight: var(--fw-refined);
  opacity: 0.72;
  letter-spacing: 0.01em;
  color: var(--md-default-fg-color);
}
.md-tabs__link:hover,
.md-tabs__link--active,
.md-tabs__item--active > .md-tabs__link {
  opacity: 1;
  color: var(--pg-teal-500);
}
[data-md-color-scheme="slate"] .md-tabs__link:hover,
[data-md-color-scheme="slate"] .md-tabs__link--active,
[data-md-color-scheme="slate"] .md-tabs__item--active > .md-tabs__link {
  color: var(--pg-teal-400);
}

/* Home-page override: header bleeds into the hero */
body:has(.pg-home) .md-header,
body:has(.pg-home) .md-tabs {
  background: var(--pg-navy-950);
  color: var(--pg-text-on-dark);
  border-bottom-color: rgba(255, 255, 255, 0.06);
}

body:has(.pg-home) .md-header__title,
body:has(.pg-home) .md-header__button,
body:has(.pg-home) .md-tabs__link {
  color: var(--pg-text-on-dark);
}

body:has(.pg-home) .md-tabs__link { opacity: 0.78; }

body:has(.pg-home) .md-tabs__link:hover,
body:has(.pg-home) .md-tabs__link--active,
body:has(.pg-home) .md-header__button:hover {
  color: var(--pg-teal-400);
  opacity: 1;
}

body:has(.pg-home) .md-header[data-md-state="shadow"] {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.28);
}

/* ------------------------------------------------------------
   Footer — single calm dark band, matched to the top bar.
   Material's default footer uses two stacked stripes (prev/next
   strip + copyright strip) in different shades of "footer dark";
   they read as separate UI rather than one calm bottom band.
   ------------------------------------------------------------ */
.md-footer,
.md-footer-meta {
  background: var(--pg-navy-950);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.md-footer-meta {
  border-top-color: rgba(255, 255, 255, 0.04);
}

.md-footer-meta__inner {
  padding: 1rem 1rem;
  font-size: 0.78rem;
  color: var(--pg-muted-on-dark);
}

.md-footer-copyright,
.md-copyright {
  color: var(--pg-muted-on-dark);
  font-size: 0.78rem;
  letter-spacing: 0.01em;
}

.md-footer-social {
  padding-top: 0;
}

.md-footer-social .md-footer-social__link,
.md-social__link {
  color: var(--pg-muted-on-dark);
  transition: color 0.15s ease, opacity 0.15s ease;
}

.md-footer-social .md-footer-social__link:hover,
.md-social__link:hover {
  color: var(--pg-teal-400);
  opacity: 1;
}

/* Prev/next nav: tighter padding, less Material default chrome. */
.md-footer__inner {
  padding: 1rem 0.75rem;
}

.md-footer__link {
  padding: 0.85rem 1rem;
  border-radius: 8px;
  transition: background 0.15s ease;
}

.md-footer__link:hover {
  background: rgba(255, 255, 255, 0.04);
  opacity: 1;
}

.md-footer__direction {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  font-weight: var(--fw-refined);
  opacity: 0.6;
  text-transform: uppercase;
}

.md-footer__title {
  font-size: 0.95rem;
  font-weight: var(--fw-refined);
  line-height: 1.3;
}

/* Hide prev/next nav on the landing page — there's no logical
   "next" from home (the page already CTAs into Get started). */
body:has(.pg-home) .md-footer__inner {
  display: none;
}

/* Search input — adapts to the header palette per page. */
.md-search__form {
  background: color-mix(in oklab, var(--md-default-fg-color) 6%, transparent);
  border-radius: 8px;
}
.md-search__form:hover {
  background: color-mix(in oklab, var(--md-default-fg-color) 10%, transparent);
}
.md-search__input { color: var(--md-default-fg-color); }
.md-search__input::placeholder {
  color: color-mix(in oklab, var(--md-default-fg-color) 50%, transparent);
}

/* Home page: search keeps the white-tint treatment over navy. The
   inner-page search input inherits the body palette via
   ``.md-search__input { color: var(--md-default-fg-color) }`` above —
   if those rules are dropped, light-mode search text becomes invisible
   on the white-near header. */
body:has(.pg-home) .md-search__form {
  background: rgba(255, 255, 255, 0.08);
}
body:has(.pg-home) .md-search__form:hover {
  background: rgba(255, 255, 255, 0.12);
}
body:has(.pg-home) .md-search__input { color: var(--pg-text-on-dark); }
body:has(.pg-home) .md-search__input::placeholder {
  color: rgba(255, 255, 255, 0.55);
}

/* ============================================================
   Landing page
   ============================================================ */

.pg-home {
  width: 100%;
  margin: 0;
  padding: 0;
}

/* Make landing span full viewport width AND bleed edge-to-edge.
   Material's default chrome wraps content in .md-main → .md-content
   → .md-content__inner, each adding padding/margin/max-width that
   reveals the page background between sections (or above/below the
   navy hero/CTA bands). Zero them all on the home route so the
   navy gradients touch the header and footer with no seam. */
body:has(.pg-home) .md-main,
body:has(.pg-home) .md-main__inner,
body:has(.pg-home) .md-content,
body:has(.pg-home) .md-content__inner {
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* Body fallback: any uncovered viewport edge falls back to the
   same navy as the hero/CTA so a stray pixel of grey can't show. */
body:has(.pg-home) {
  background: var(--pg-navy-950);
}

/* The primary nav sidebar is kept in the DOM on the home page so the
   mobile hamburger drawer still has something to open (Material reuses
   the same .md-sidebar--primary element for both the desktop rail and
   the < 76.25em slide-out drawer). Hide the desktop rail only — the
   drawer's visibility is driven by the [data-md-toggle="drawer"]
   checkbox at smaller widths and stays untouched. */
@media screen and (min-width: 76.25em) {
  body:has(.pg-home) .md-sidebar--primary {
    display: none;
  }
}

/* ----- Hero ------------------------------------------------- */
.pg-hero {
  position: relative;
  /* Layered backgrounds, top → bottom:
     1. Inline SVG fractalNoise data-URL — ~3% opacity grain that
        keeps the navy from reading as a flat digital surface. No
        extra HTTP request; the SVG is base-encoded in the URL.
     2. Linear navy gradient — the brand backdrop. */
  background:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/></svg>"),
    linear-gradient(180deg, var(--pg-navy-950) 0%, var(--pg-navy-900) 100%);
  background-size: 200px 200px, auto;
  color: var(--pg-text-on-dark);
  /* Tighter top padding so the shield mark + wordmark + H1 read
     as one anchored stack — keeps the navy chrome and the hero
     from reading as one continuous void of empty navy. */
  padding: clamp(2rem, 4.5vw, 3.25rem) 1.5rem clamp(4.5rem, 9vw, 8rem);
  overflow: hidden;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  isolation: isolate;
}

/* Faint grid overlay — 48px square, 0.05 opacity, with a radial
   mask so it fades out at the edges and reveals the gradient
   glow underneath. Subtle "blueprint" texture without crowding
   the hero's foreground content. */
.pg-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 48px 48px;
  background-position: 0 0;
  z-index: -1;
  pointer-events: none;
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 78%);
}

/* Ambient gradient drift — slow low-frequency motion in the
   background glow. ~30s cycle, kept gentle so it never reads
   as movement, just "alive". Disabled for reduced-motion. */
.pg-hero::after {
  content: "";
  position: absolute;
  inset: -10%;
  background:
    radial-gradient(700px 380px at 75% 10%, rgba(27, 163, 169, 0.22), transparent 60%),
    radial-gradient(500px 260px at 20% 80%, rgba(8, 126, 139, 0.10), transparent 60%);
  z-index: -2;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .pg-hero::after {
    animation: pg-hero-drift 30s ease-in-out infinite alternate;
  }
}

@keyframes pg-hero-drift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(2%, 1%) scale(1.04); }
  100% { transform: translate(-1%, -2%) scale(1.02); }
}

.pg-hero__inner {
  position: relative;
  max-width: 78rem;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

@media (max-width: 960px) {
  .pg-hero__inner {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
}

/* Hero brand mark — outlined shield with a teal checkmark. Sits
   above the wordmark on its own row. Sized as a refined brand
   anchor (not a billboard): the H1 carries the visual weight,
   the shield just announces "Pipeline-Check, the secure gate".
   The SVG itself is constrained to the wrapper so an unsized
   inline ``<svg viewBox=...>`` can't blow past the slot. */
.pg-hero__mark,
img.pg-hero__mark {
  position: relative;
  display: inline-block;
  width: clamp(58px, 6vw, 76px);
  height: clamp(58px, 6vw, 76px);
  margin: 0 0 1.25rem;
  isolation: isolate;
}
.pg-hero__mark svg {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  z-index: 1;
}
/* Soft teal halo behind the shield — gives the mark a perceived
   light source consistent with the hero's radial glow without
   adding another DOM node. */
.pg-hero__mark::after {
  content: "";
  position: absolute;
  inset: -38%;
  background: radial-gradient(
    closest-side,
    color-mix(in oklab, var(--pg-teal-500) 35%, transparent) 0%,
    transparent 70%
  );
  z-index: 0;
  pointer-events: none;
}

/* One-shot entrance: shield stroke draws in, then the checkmark
   stamps in on top. Triggers on page load only — no idle motion. */
@media (prefers-reduced-motion: no-preference) {
  .pg-hero__mark svg path:nth-of-type(1) {
    stroke-dasharray: 180;
    stroke-dashoffset: 180;
    animation: pg-shield-trace 0.9s var(--ease-out) 0.1s forwards;
  }
  .pg-hero__mark svg path:nth-of-type(2) {
    stroke-dasharray: 36;
    stroke-dashoffset: 36;
    animation: pg-shield-check 0.45s var(--ease-out) 0.85s forwards;
  }
}

@keyframes pg-shield-trace {
  to { stroke-dashoffset: 0; }
}
@keyframes pg-shield-check {
  to { stroke-dashoffset: 0; }
}

/* ── Goose patrol — full animation section ───────────────────────
   Hosts the 16:7 patrol scene from
   ``.claude/design_system/preview/brand-logo-animation.html`` in
   its own dedicated section near the bottom of the landing page.

   Unlike the hero mark (which rides on the hero's existing
   gradient), this card carries its own navy + grid chrome — the
   ``.pg-section`` background is the page default, so the patrol
   needs the chrome the design-system preview wraps it in. World
   coords stay 800×350; we constrain by max-width and aspect-ratio
   so the scene scales gracefully on narrow viewports. */
.pg-patrol {
  position: relative;
  max-width: 64rem;
  margin: 0 auto;
  aspect-ratio: 16 / 7;
  border: 1px solid var(--color-border);
  border-radius: 12px;
  overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 70%, rgba(27, 163, 169, .08), transparent 60%),
    #04101a;
}
.pg-patrol::before {
  content: "";
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .04) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse at 50% 60%, #000 50%, transparent 90%);
          mask-image: radial-gradient(ellipse at 50% 60%, #000 50%, transparent 90%);
  pointer-events: none;
}
/* The goose patrol is loaded as a standalone SVG via ``<img>`` so
   the file is portable (works in any embed context, not just inline
   here). All animation lives inside ``docs/patrol.svg`` so the file
   stays self-contained. This selector just sizes the img to fill
   the wrapper card; nothing else from the page reaches inside the
   img-loaded SVG document. */
.pg-patrol .pg-patrol__embed {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}

/* Markdown wraps the goose image (and the wordmark span) in
   <p>; the brand stack reads as a single editorial block, not
   three separate paragraphs. Apply the reset to every <p> inside
   the hero column so every browser, with or without :has(),
   handles it the same way. */
.pg-hero .md-typeset > div > p {
  margin: 0 0 0.4rem;
}
/* The hero H1 is a markdown ``# ...`` heading that picks up
   ``.md-typeset h1`` styles by default — small inner-page size with
   the teal-gradient underline. Both wrong here: the hero deserves a
   real display moment, and the underline reads as docs-page chrome
   in a section that's already its own brand surface. Override both. */
.pg-hero .md-typeset > div > h1 {
  margin: 0.6rem 0 1.1rem;
  font-size: clamp(3rem, 6.5vw, 5.5rem);
  line-height: 0.98;
  /* Variable-axis display weight — see ``--fw-display`` token
     comment for the rationale. */
  font-weight: var(--fw-display);
  letter-spacing: -0.04em;
  color: #fff;
  text-wrap: balance;
}
/* Suppress the inner-page ::after teal-underline accent — hero
   already announces "page start" through the wordmark + goose. */
.pg-hero .md-typeset > div > h1::after {
  display: none;
}

.pg-hero__wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pg-teal-400);
  margin-bottom: 1.5rem;
}

.pg-hero__wordmark::before {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}

.pg-hero__title {
  font-size: clamp(2.4rem, 4.6vw, 3.6rem);
  line-height: 1.05;
  font-weight: 700;
  margin: 0 0 1.1rem;
  letter-spacing: -0.035em;
  color: #fff;
  text-wrap: balance;
}

.pg-hero__title .accent {
  background: linear-gradient(135deg, #1ba3a9 0%, #6dd5ed 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.pg-hero__lede {
  /* Bumped from 1.05rem to keep proportional with the bigger H1
     above. Lede should read as supporting copy, not a footnote. */
  font-size: clamp(1.05rem, 1.3vw, 1.18rem);
  line-height: 1.55;
  color: var(--pg-muted-on-dark);
  max-width: 36rem;
  margin: 0 0 2rem;
  text-wrap: balance;
}

.pg-hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-bottom: 2rem;
}

/* Buttons sitting on a dark navy band (hero + closing CTA share the
   same chrome). Treatment matches the design system spec at
   .claude/design_system/IMPLEMENTATION.md: solid teal-500 fill with
   navy-950 text on the primary; transparent + slate hairline on the
   ghost; no glassmorphism, no inset highlights, no drop shadows on
   the button itself. Hover shifts the background one step lighter
   and tints the ghost's border teal — no transform. */
.pg-hero__cta .md-button,
.pg-cta .md-button {
  border-radius: var(--radius-xs);
  padding: 0.625rem 1rem;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.9rem;
  letter-spacing: 0;
  transition: background 0.18s var(--ease-out),
              border-color 0.18s var(--ease-out),
              color 0.18s var(--ease-out);
}

/* Primary: solid teal-500 with dark navy text. ``!important`` because
   Material's own ``.md-typeset .md-button--primary`` rule reaches
   specificity (0,2,0) via the page wrapper; explicit wins over
   stylesheet-order luck. */
.pg-hero__cta .md-button--primary,
.pg-cta .md-button--primary,
.md-typeset .pg-hero__cta .md-button--primary,
.md-typeset .pg-cta .md-button--primary {
  background: var(--pg-teal-500) !important;
  border: 1px solid var(--pg-teal-500) !important;
  color: var(--pg-navy-950) !important;
  text-shadow: none;
  box-shadow: none;
}

.pg-hero__cta .md-button--primary:hover,
.pg-cta .md-button--primary:hover,
.md-typeset .pg-hero__cta .md-button--primary:hover,
.md-typeset .pg-cta .md-button--primary:hover {
  background: var(--pg-teal-400) !important;
  border-color: var(--pg-teal-400) !important;
  color: var(--pg-navy-950) !important;
  text-shadow: none;
  box-shadow: none;
}

/* Ghost: transparent fill, slate hairline. Hover tints the border
   teal-500 and washes the surface with an 8% teal color-mix. */
.pg-hero__cta .md-button:not(.md-button--primary),
.pg-cta .md-button:not(.md-button--primary) {
  color: var(--pg-text-on-dark);
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: transparent;
}

.pg-hero__cta .md-button:not(.md-button--primary):hover,
.pg-cta .md-button:not(.md-button--primary):hover {
  background: color-mix(in oklab, var(--pg-teal-500) 8%, transparent);
  border-color: var(--pg-teal-500);
  color: #fff;
}

.pg-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 1.5rem;
  font-size: 0.8rem;
  color: var(--pg-muted-on-dark);
  line-height: 1;
}

.pg-hero__meta span {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  white-space: nowrap;
}

.pg-hero__meta svg {
  width: 14px !important;
  height: 14px !important;
  opacity: 0.85;
  color: var(--pg-teal-400);
  flex-shrink: 0;
}

/* ----- Refined terminal ------------------------------------ */
.pg-terminal {
  background: rgba(4, 16, 26, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  box-shadow: 0 30px 60px -25px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  font-family: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.84rem;
}

.pg-terminal__chrome {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0.9rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.pg-terminal__file {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.74rem;
  color: var(--pg-muted-on-dark);
  letter-spacing: 0.02em;
}

.pg-terminal__file svg {
  width: 12px !important;
  height: 12px !important;
  opacity: 0.7;
  flex-shrink: 0;
}

.pg-terminal__tag {
  margin-left: auto;
  font-size: 0.68rem;
  color: var(--pg-teal-400);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.pg-terminal__body {
  padding: 1.1rem 1.15rem 1.25rem;
  line-height: 1.65;
  color: #d6e3ee;
  /* Wrap long lines instead of forcing a horizontal scrollbar.
     pre-wrap preserves the leading whitespace that aligns the
     scan output, while still letting verbose lines break to
     the next row when the right column is narrow. */
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.pg-terminal .prompt    { color: var(--pg-teal-400); }
.pg-terminal .arg       { color: #c8d6e0; }
.pg-terminal .crit      { color: #ff5f7a; font-weight: 600; }
.pg-terminal .high      { color: #ff9b6a; }
.pg-terminal .med       { color: #ffd166; }
.pg-terminal .low       { color: #6ec1ff; }
.pg-terminal .ok        { color: #4ade80; }
.pg-terminal .grade-d   { color: #ff5f7a; font-weight: 700; }
.pg-terminal .dim       { color: var(--pg-muted-on-dark); }
.pg-terminal .label     { color: #fff; font-weight: 600; }

/* ----- Animated scan output -------------------------------- */
/* Each line lands sequentially with realistic scanner cadence:
   short pauses between findings, longer pauses around section
   breaks. Plays once on page load. Reduced-motion users get the
   final state instantly. */

.pg-terminal .line {
  display: block;
}

@media (prefers-reduced-motion: no-preference) {
  .pg-terminal .line {
    opacity: 0;
    transform: translateY(4px);
    animation: pg-line-in 0.32s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  }

  .pg-terminal .l1  { animation-delay: 0.20s; }
  .pg-terminal .l2  { animation-delay: 0.32s; }
  .pg-terminal .l3  { animation-delay: 0.50s; }
  .pg-terminal .l4  { animation-delay: 0.68s; }
  .pg-terminal .l5  { animation-delay: 1.00s; }
  .pg-terminal .l6  { animation-delay: 1.18s; }
  .pg-terminal .l7  { animation-delay: 1.50s; }
  .pg-terminal .l8  { animation-delay: 1.68s; }
  .pg-terminal .l9  { animation-delay: 2.00s; }
  .pg-terminal .l10 { animation-delay: 2.18s; }
  .pg-terminal .l11 { animation-delay: 2.45s; }
  .pg-terminal .l12 { animation-delay: 2.65s; }
  .pg-terminal .l13 { animation-delay: 2.85s; }
  .pg-terminal .l14 { animation-delay: 3.00s; }
  .pg-terminal .l15 { animation-delay: 3.20s; }
  .pg-terminal .l16 { animation-delay: 3.40s; }
  .pg-terminal .l17 { animation-delay: 3.62s; }
  .pg-terminal .l18 { animation-delay: 3.82s; }
  .pg-terminal .l19 { animation-delay: 4.05s; }
}

@keyframes pg-line-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Blinking cursor at the prompt position after the last line lands. */
.pg-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  background: var(--pg-teal-400);
  vertical-align: -0.12em;
  margin-left: 0.35em;
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .pg-cursor {
    animation: pg-cursor-blink 1.05s steps(1, end) 4.5s infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pg-cursor {
    opacity: 1;
  }
}

@keyframes pg-cursor-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* ============================================================
   Stat row (tabular numerics, no boxes)
   ============================================================ */
.pg-stats {
  background: var(--md-default-bg-color);
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}

.pg-stats__inner {
  max-width: 78rem;
  margin: 0 auto;
  padding: 3rem 1.5rem;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

@media (max-width: 760px) {
  .pg-stats__inner {
    grid-template-columns: repeat(2, 1fr);
  }
}

.pg-stat {
  text-align: center;
  padding: 0.5rem;
  position: relative;
}

.pg-stat:not(:last-child)::after {
  content: "";
  position: absolute;
  right: 0;
  top: 25%;
  bottom: 25%;
  width: 1px;
  background: var(--md-default-fg-color--lightest);
}

@media (max-width: 760px) {
  .pg-stat:nth-child(2n)::after { display: none; }
}

.pg-stat__num {
  font-size: clamp(2.2rem, 3.6vw, 2.9rem);
  /* Ultra-display weight — Mona Sans variable axis at 760 gives the
     stat numbers a sharper, more deliberate display moment than
     plain 700. The clamp sizes are big enough that the extra
     weight reads as intentional rather than aggressive. */
  font-weight: var(--fw-stat);
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums lining-nums;
  background: linear-gradient(135deg, var(--pg-navy-700) 0%, var(--pg-teal-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  line-height: 1;
}

[data-md-color-scheme="slate"] .pg-stat__num {
  background: linear-gradient(135deg, var(--pg-teal-300) 0%, var(--pg-teal-400) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.pg-stat__label {
  margin-top: 0.5rem;
  font-size: 0.78rem;
  color: var(--md-default-fg-color--light);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: var(--fw-refined);
}

/* ============================================================
   Sections (consistent rhythm, no banded alternation)
   ============================================================ */
.pg-section {
  max-width: 78rem;
  margin: 0 auto;
  padding: var(--pg-space-section) 1.5rem;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}

.pg-section:last-of-type {
  border-bottom: none;
}

.pg-section__head {
  margin-bottom: 2.5rem;
  max-width: 44rem;
}

.pg-section__eyebrow {
  font-size: 0.72rem;
  font-weight: var(--fw-refined);
  letter-spacing: 0.04em;
  color: var(--pg-teal-500);
  margin: 0 0 0.85rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  line-height: 1;
}

[data-md-color-scheme="slate"] .pg-section__eyebrow {
  color: var(--pg-teal-400);
}

.pg-section__title {
  font-size: clamp(1.8rem, 3.2vw, 2.4rem);
  /* Display weight matches H1s — section headlines are display
     moments too, just nested below the page title. */
  font-weight: var(--fw-display);
  letter-spacing: -0.025em;
  margin: 0 0 0.75rem;
  line-height: 1.15;
  text-wrap: balance;
}

.pg-section__lede {
  font-size: 1rem;
  color: var(--md-default-fg-color--light);
  margin: 0;
  line-height: 1.6;
  text-wrap: pretty;
}

/* ----- Feature grid (hairline cards, no lift) -------------- */
/* Six features: lock the desktop grid to 3 columns so the layout
   reads as a clean 3×2 block rather than the asymmetric 5+1 the
   prior auto-fit produced at common widescreen breakpoints. */
.pg-features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--md-default-fg-color--lightest);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: var(--pg-radius-card);
  overflow: hidden;
}

@media (max-width: 960px) {
  .pg-features { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .pg-features { grid-template-columns: 1fr; }
}

.pg-feature {
  background: var(--md-default-bg-color);
  padding: 1.75rem 1.5rem;
  transition: background 0.15s ease;
  display: flex;
  flex-direction: column;
}

.pg-feature:hover {
  background: color-mix(in oklab, var(--md-default-bg-color) 90%, var(--pg-teal-500));
}

.pg-feature p { flex: 1; }

.pg-feature__icon {
  color: var(--pg-teal-500);
  margin-bottom: 1rem;
}

[data-md-color-scheme="slate"] .pg-feature__icon {
  color: var(--pg-teal-400);
}

.pg-feature__icon svg {
  width: 26px !important;
  height: 26px !important;
  stroke-width: 1.6;
}

.pg-feature h3 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  font-weight: var(--fw-card-h);
  letter-spacing: -0.015em;
}

.pg-feature p {
  margin: 0;
  color: var(--md-default-fg-color--light);
  line-height: 1.6;
  font-size: 0.93rem;
}

.pg-feature a.pg-feature__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--pg-teal-500);
  text-decoration: none;
}

.pg-feature a.pg-feature__link:hover { text-decoration: underline; }
.pg-feature a.pg-feature__link::after {
  content: "→";
  display: inline-block;
  transition: transform 0.15s ease;
}
.pg-feature a.pg-feature__link:hover::after { transform: translateX(2px); }

/* ----- Provider grid (compact, mono labels) ----------------
   Min width 180px keeps the longest provider names — CloudFormation,
   GitHub Actions, Azure DevOps — on a single line so card heights
   stay uniform across the row. */
.pg-providers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.6rem;
}

.pg-provider {
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 10px;
  padding: 0.85rem 1rem;
  text-align: left;
  text-decoration: none;
  color: var(--md-default-fg-color);
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.pg-provider:hover {
  border-color: var(--pg-teal-500);
  color: var(--pg-teal-500);
  background: color-mix(in oklab, var(--md-default-bg-color) 96%, var(--pg-teal-500));
}

.pg-provider__name {
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: -0.005em;
}

.pg-provider__count {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--md-default-fg-color--light);
  letter-spacing: 0.04em;
}

/* ----- Mermaid container ----------------------------------- */
.mermaid {
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: var(--pg-radius-card);
  padding: 2rem 1.25rem;
  text-align: center;
}

/* ============================================================
   Interactive scan-pipeline flow
   ============================================================ */

.pg-flow {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  position: relative;
}

@media (max-width: 900px) {
  .pg-flow { grid-template-columns: 1fr; }
}

.pg-flow__step {
  position: relative;
  padding: 0 0.5rem;
}

/* Connector line between steps (desktop horizontal, mobile vertical) */
.pg-flow__step:not(:last-child)::after {
  content: "";
  position: absolute;
  background: linear-gradient(90deg,
    color-mix(in oklab, var(--md-default-fg-color--lightest) 40%, transparent) 0%,
    var(--pg-teal-500) 100%);
  opacity: 0.6;
}

@media (min-width: 901px) {
  .pg-flow__step:not(:last-child)::after {
    top: 36px;
    right: -0.5rem;
    left: calc(100% - 1rem);
    height: 2px;
  }
}

@media (max-width: 900px) {
  .pg-flow__step:not(:last-child)::after {
    left: 24px;
    top: calc(100% - 0.5rem);
    bottom: -0.5rem;
    width: 2px;
    background: linear-gradient(180deg,
      color-mix(in oklab, var(--md-default-fg-color--lightest) 40%, transparent) 0%,
      var(--pg-teal-500) 100%);
  }
  .pg-flow__step { margin-bottom: 1rem; }
}

/* Node — the visible interactive button */
.pg-flow__node {
  position: relative;
  width: 100%;
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 12px;
  padding: 1rem 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  transition: border-color 0.18s ease, transform 0.18s ease,
              box-shadow 0.18s ease, background 0.18s ease;
  z-index: 1;
}

.pg-flow__node:hover,
.pg-flow__node:focus-visible {
  border-color: var(--pg-teal-500);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -16px color-mix(in oklab, var(--pg-teal-500) 60%, transparent);
  outline: none;
  background: color-mix(in oklab, var(--md-default-bg-color) 96%, var(--pg-teal-500));
}

.pg-flow__icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--md-default-bg-color) 86%, var(--pg-teal-500));
  color: var(--pg-teal-500);
  margin-bottom: 0.6rem;
  transition: background 0.18s ease, color 0.18s ease;
}

.pg-flow__node:hover .pg-flow__icon,
.pg-flow__node:focus-visible .pg-flow__icon {
  background: var(--pg-teal-500);
  color: #fff;
}

[data-md-color-scheme="slate"] .pg-flow__icon {
  background: color-mix(in oklab, var(--md-default-bg-color) 80%, var(--pg-teal-500));
  color: var(--pg-teal-400);
}

.pg-flow__num {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--md-default-fg-color--lighter);
  font-weight: var(--fw-refined);
}

.pg-flow__label {
  font-size: 1rem;
  font-weight: var(--fw-card-h);
  letter-spacing: -0.02em;
  color: var(--md-default-fg-color);
}

.pg-flow__sub {
  font-size: 0.78rem;
  color: var(--md-default-fg-color--light);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.01em;
}

/* Popover card */
.pg-flow__card {
  position: absolute;
  top: calc(100% + 0.75rem);
  left: 0.5rem;
  right: 0.5rem;
  z-index: 10;
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-top: 3px solid var(--pg-teal-500);
  border-radius: 10px;
  padding: 1rem 1.1rem 1.1rem;
  box-shadow: 0 24px 48px -16px color-mix(in oklab, var(--pg-navy-900) 35%, transparent);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ease;
  pointer-events: none;
  font-size: 0.84rem;
  line-height: 1.55;
}

@media (min-width: 901px) {
  /* On wider grids, give the popover a comfortable fixed width
     and let it overlap neighbours via z-index + shadow. */
  .pg-flow__card {
    width: 320px;
    max-width: 320px;
    right: auto;
  }

  /* The last two steps' popovers anchor right-edge so they don't
     overflow the viewport. */
  .pg-flow__step:nth-child(4) .pg-flow__card,
  .pg-flow__step:nth-child(5) .pg-flow__card {
    left: auto;
    right: 0.5rem;
  }
}

.pg-flow__step:hover .pg-flow__card,
.pg-flow__step:focus-within .pg-flow__card {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}

.pg-flow__card-title {
  font-weight: var(--fw-card-h);
  font-size: 0.95rem;
  letter-spacing: -0.015em;
  margin-bottom: 0.45rem;
  color: var(--md-default-fg-color);
}

.pg-flow__card p {
  margin: 0 0 0.65rem;
  color: var(--md-default-fg-color--light);
}

.pg-flow__card ul {
  margin: 0 0 0.85rem;
  padding-left: 1rem;
  list-style: none;
}

.pg-flow__card ul li {
  position: relative;
  padding-left: 0.85rem;
  margin-bottom: 0.3rem;
  color: var(--md-default-fg-color--light);
}

.pg-flow__card ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--pg-teal-500);
}

[data-md-color-scheme="slate"] .pg-flow__card ul li::before {
  background: var(--pg-teal-400);
}

.pg-flow__card code {
  font-size: 0.82em;
  padding: 0.1em 0.35em;
}

.pg-flow__link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--pg-teal-500);
  text-decoration: none;
}

.pg-flow__link:hover { text-decoration: underline; }
.pg-flow__link::after {
  content: "→";
  transition: transform 0.15s ease;
}
.pg-flow__link:hover::after { transform: translateX(2px); }

[data-md-color-scheme="slate"] .pg-flow__link {
  color: var(--pg-teal-400);
}

/* Strip the external-link arrow inside flow cards (it's all
   internal docs links there) */
.pg-flow__card a::after { content: ""; }

/* ----- Output formats grid -------------------------------- */
.pg-outputs {
  margin-top: 4rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--md-default-fg-color--lightest);
}

.pg-outputs__head {
  margin-bottom: 1.25rem;
}

.pg-outputs__lede {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0.4rem 0 0;
  letter-spacing: -0.015em;
  color: var(--md-default-fg-color);
}

.pg-outputs__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.65rem;
}

.pg-output {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.85rem 1rem;
  background: var(--md-default-bg-color);
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 10px;
  text-decoration: none !important;
  color: var(--md-default-fg-color);
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.pg-output:hover {
  border-color: var(--pg-teal-500);
  background: color-mix(in oklab, var(--md-default-bg-color) 96%, var(--pg-teal-500));
}

.pg-output strong {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--md-default-fg-color);
}

.pg-output span {
  font-size: 0.78rem;
  color: var(--md-default-fg-color--light);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  letter-spacing: 0.01em;
}

.pg-output:hover strong { color: var(--pg-teal-500); }

[data-md-color-scheme="slate"] .pg-output:hover strong { color: var(--pg-teal-400); }

.pg-output::after { content: "" !important; }

/* ----- Closing CTA (lighter dark, no heavy gradient) ------- */
.pg-cta {
  background: linear-gradient(180deg, var(--pg-navy-950) 0%, var(--pg-navy-900) 100%);
  color: var(--pg-text-on-dark);
  padding: var(--pg-space-section) 1.5rem;
  text-align: center;
  position: relative;
  overflow: hidden;
}

.pg-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(600px 300px at 50% 0%, rgba(27, 163, 169, 0.18), transparent 60%);
  pointer-events: none;
}

.pg-cta__inner {
  position: relative;
  max-width: 42rem;
  margin: 0 auto;
}

.pg-cta h2 {
  color: #fff;
  font-size: clamp(1.8rem, 3vw, 2.3rem);
  margin: 0 0 0.85rem;
  letter-spacing: -0.025em;
  /* Display weight — closes the page on the same display rhythm
     as the hero H1 and section titles. */
  font-weight: var(--fw-display);
}

.pg-cta p {
  color: var(--pg-muted-on-dark);
  font-size: 1rem;
  margin: 0 0 1.75rem;
  line-height: 1.55;
}

/* CTA install snippet — make it standalone, not Material's default */
.pg-cta .pg-install {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.95rem;
  color: var(--pg-text-on-dark);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 0.85rem 1.25rem;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  letter-spacing: 0;
}

.pg-cta .pg-install::before {
  content: "$";
  color: var(--pg-teal-400);
  font-weight: 700;
}

.pg-cta__buttons {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-top: 1.5rem;
}

/* ── Sortable tables ─────────────────────────────────────────────────
   Every <th> that ``tablesort.js`` attaches a handler to gets the
   ``pg-sortable`` class. The chevron is drawn via ``::after`` so we
   don't have to touch the markdown source. Three states:

   - default (``aria-sort="none"``): faint up-down chevron (¦),
     hinting "click me to sort"
   - ascending (``aria-sort="ascending"``): solid ▲
   - descending (``aria-sort="descending"``): solid ▼

   Cursor + hover affordance signals interactivity without changing
   the layout. The header keeps its column width because the chevron
   is ``inline-block`` and reserves its own space at all three states. */
th.pg-sortable {
  cursor: pointer;
  user-select: none;
  position: relative;
  /* Reserve room for the chevron so the column doesn't shift when the
     state flips between ascending and descending. */
  padding-right: 1.4em !important;
}

th.pg-sortable:hover {
  background: rgba(255, 255, 255, 0.04);
}

th.pg-sortable::after {
  content: "↕";
  display: inline-block;
  position: absolute;
  right: 0.55em;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0.4;
  font-size: 0.85em;
  transition: opacity 0.15s ease;
}

th.pg-sortable:hover::after {
  opacity: 0.75;
}

th.pg-sortable.pg-sort-asc::after {
  content: "▲";
  opacity: 0.95;
  color: var(--pg-teal-300);
}

th.pg-sortable.pg-sort-desc::after {
  content: "▼";
  opacity: 0.95;
  color: var(--pg-teal-300);
}

/* Keyboard focus ring — keeps the affordance accessible. The header
   gets ``role="button" tabindex="0"`` from the JS, so Tab lands on
   each sortable header. */
th.pg-sortable:focus-visible {
  outline: 2px solid var(--pg-teal-300);
  outline-offset: -2px;
}

/* ============================================================
   Mobile / drawer pass
   ============================================================
   At widths where Material collapses the primary nav into a slide-
   out drawer (< 76.25em), the drawer is *inside* the body and
   inherits some of the home page's ``body:has(.pg-home) ...`` navy
   chrome by accident — drawer titles render in white-on-white, the
   inner nav shows a navy band where Material expects the body
   palette. We reset to the page palette, then dress the drawer up
   with depth, accent rails, and proper hover/active states so it
   reads as a modern slide-out rather than a plain stacked list.
   ============================================================ */

@media screen and (max-width: 76.1875em) {
  /* ── Backdrop ───────────────────────────────────────────────────
     Material renders ``.md-overlay`` behind the drawer when open.
     Default is a flat semi-opaque black; we add a slight blur for
     depth on browsers that support ``backdrop-filter``. The blur
     is gracefully ignored elsewhere — opacity alone still dims. */
  .md-overlay {
    background: rgba(8, 14, 22, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
  }

  /* ── Drawer surface ─────────────────────────────────────────────
     Soft drop shadow on the right edge for depth. Slight rounding
     on the right edge so the drawer reads as an over-laid panel
     rather than a flush-cut sidebar. Material uses a transform-
     based slide-in — keep the hardware acceleration intact. */
  .md-sidebar--primary {
    background: var(--md-default-bg-color);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.18),
                4px 0 24px rgba(0, 0, 0, 0.08);
    border-top-right-radius: 14px;
    border-bottom-right-radius: 14px;
    overflow: hidden;
    transition: transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);
  }

  [data-md-color-scheme="slate"] .md-sidebar--primary {
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45),
                4px 0 24px rgba(0, 0, 0, 0.30);
  }

  /* Reset drawer interior to page palette. The home page's
     ``body:has(.pg-home)`` navy rules would otherwise leak into
     ``.md-nav__title``. Belt-and-braces explicit reset for both
     home and inner pages. */
  .md-sidebar--primary,
  .md-sidebar--primary .md-nav,
  body:has(.pg-home) .md-sidebar--primary,
  body:has(.pg-home) .md-sidebar--primary .md-nav,
  body:has(.pg-home) .md-sidebar--primary .md-nav__title {
    background: var(--md-default-bg-color);
    color: var(--md-default-fg-color);
  }

  body:has(.pg-home) .md-sidebar--primary .md-nav__link,
  body:has(.pg-home) .md-sidebar--primary .md-nav__title {
    color: var(--md-default-fg-color);
  }

  /* ── Drawer header strip ────────────────────────────────────────
     Material draws a top-aligned ``.md-nav__title`` carrying the
     site title + close button. We give it a teal accent under-
     line, a slightly larger wordmark, and tighter chrome so it
     reads as a brand strip rather than a generic title bar.

     Explicit ``display: flex`` + ``gap`` because the bumped 1.7rem
     logo (rule below) was crowding the wordmark — Material's
     default flex layout has no explicit gap, so a larger image
     visually overlapped the title text. */
  .md-sidebar--primary .md-nav--primary > .md-nav__title {
    background: var(--md-default-bg-color);
    color: var(--md-default-fg-color);
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    line-height: 1.3;
    padding: 1rem 1rem 0.95rem;
    border-bottom: 1px solid var(--md-default-fg-color--lightest);
    box-shadow: 0 1px 0 0 color-mix(in oklab, var(--pg-teal-500) 35%, transparent);
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.6rem;
  }

  /* The logo button is a flex item; lock its size so the wordmark
     gets the remaining width without wrapping under the image. */
  .md-sidebar--primary .md-nav--primary > .md-nav__title .md-nav__button.md-logo {
    flex: 0 0 auto;
    padding: 0;
    margin: 0;
  }

  /* Teal accent rail at the bottom of the drawer header — a
     hairline stripe in the brand colour that visually separates
     the wordmark strip from the nav list below. */
  .md-sidebar--primary .md-nav--primary > .md-nav__title::after {
    content: "";
    position: absolute;
    left: 1rem;
    right: 1rem;
    bottom: -1px;
    height: 2px;
    background: linear-gradient(90deg,
      var(--pg-teal-500) 0%,
      color-mix(in oklab, var(--pg-teal-500) 0%, transparent) 100%);
    border-radius: 2px;
  }

  /* Hide the site logo inside the drawer — the wordmark alone is
     unambiguous brand identification at this size, and the duplicate
     mark crowded the title. The header still shows the logo. */
  .md-sidebar--primary .md-nav__button.md-logo {
    display: none;
  }

  /* Close button — match the rest of the chrome rather than
     Material's default chunky inverted style. */
  .md-sidebar--primary .md-nav__title .md-nav__button[type="checkbox"] + label,
  .md-sidebar--primary .md-nav__title .md-nav__icon {
    color: var(--md-default-fg-color--light);
    opacity: 0.7;
    transition: opacity 0.15s ease, color 0.15s ease;
  }

  .md-sidebar--primary .md-nav__title .md-nav__icon:hover {
    opacity: 1;
    color: var(--pg-teal-500);
  }

  /* ── Section titles (nested ``.md-nav__title`` inside groups) ───
     Sections like "Providers" / "Standards" get small-caps tracking
     so they read as labels rather than competing with item text. */
  .md-sidebar--primary .md-nav .md-nav .md-nav__title {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--md-default-fg-color--light);
    padding: 1.1rem 1rem 0.4rem;
    background: transparent;
    box-shadow: none;
  }

  /* ── Nav items — rounded hover/active states ────────────────────
     Material's defaults render flat full-bleed link rows. We round
     them slightly and inset by 0.4rem so the hover/active fill
     reads as a discrete chip rather than a band crossing the
     drawer edge to edge. */
  .md-sidebar--primary .md-nav__list {
    padding: 0.4rem 0.5rem;
  }

  .md-sidebar--primary .md-nav__item {
    margin: 0;
  }

  .md-sidebar--primary .md-nav__link {
    padding: 0.65rem 0.85rem;
    line-height: 1.4;
    border-radius: 8px;
    color: var(--md-default-fg-color);
    transition: background 0.12s ease, color 0.12s ease;
    position: relative;
  }

  .md-sidebar--primary .md-nav__link:hover {
    background: color-mix(in oklab,
      var(--md-default-bg-color) 86%, var(--pg-teal-500));
    color: var(--md-default-fg-color);
  }

  /* Active page — left rail accent + teal text. The rail is
     ``::before`` because Material reserves the link's own padding
     box for content. */
  .md-sidebar--primary .md-nav__link--active {
    color: var(--pg-teal-500);
    font-weight: 600;
    background: color-mix(in oklab,
      var(--md-default-bg-color) 92%, var(--pg-teal-500));
  }

  [data-md-color-scheme="slate"] .md-sidebar--primary .md-nav__link--active {
    color: var(--pg-teal-300);
  }

  .md-sidebar--primary .md-nav__link--active::before {
    content: "";
    position: absolute;
    left: -0.5rem;
    top: 0.45rem;
    bottom: 0.45rem;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--pg-teal-500);
  }

  [data-md-color-scheme="slate"] .md-sidebar--primary .md-nav__link--active::before {
    background: var(--pg-teal-300);
  }

  /* Disclosure caret (``▶``) for nested groups — recolor to the
     brand muted tone so it doesn't compete with the link text. */
  .md-sidebar--primary .md-nav__icon {
    color: var(--md-default-fg-color--light);
    transition: color 0.12s ease, transform 0.18s ease;
  }

  .md-sidebar--primary .md-nav__link:hover .md-nav__icon {
    color: var(--pg-teal-500);
  }

  /* ── Scroll inertia + scrollbar polish ──────────────────────────
     iOS gets momentum scrolling. Modern Chrome/Edge get a thinner
     scrollbar (Firefox has its own ``scrollbar-width`` knob). */
  .md-sidebar--primary .md-sidebar__scrollwrap {
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--md-default-fg-color--lighter) transparent;
  }

  .md-sidebar--primary .md-sidebar__scrollwrap::-webkit-scrollbar {
    width: 6px;
  }

  .md-sidebar--primary .md-sidebar__scrollwrap::-webkit-scrollbar-thumb {
    background: var(--md-default-fg-color--lighter);
    border-radius: 3px;
  }

  /* ── Reduced motion ────────────────────────────────────────────
     Strip the slide animation when the user has asked for it.
     Material handles this for the transform itself; this catches
     the colour transitions on links/icons too. */
  @media (prefers-reduced-motion: reduce) {
    .md-sidebar--primary,
    .md-sidebar--primary .md-nav__link,
    .md-sidebar--primary .md-nav__icon {
      transition: none;
    }
  }

  /* ── Wide tables — already handled, kept here for context ──────
     Provider rule lists and NIST/OWASP control matrices don't fit
     a phone viewport. Force horizontal scroll on the table itself
     so the layout doesn't bust. */
  .md-typeset__scrollwrap,
  .md-typeset .pg-doc-cards,
  .md-typeset table:not([class]) {
    max-width: 100%;
  }

  .md-typeset table:not([class]) {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Hero — pull padding in slightly on phones so the band doesn't
     monopolize the first viewport. */
  .pg-hero {
    padding-top: 3rem;
    padding-bottom: 3.25rem;
  }
}

/* ============================================================
   Mermaid flow chart container
   ============================================================
   The "Inputs in. Graded report out." flow renders via Mermaid
   inside a ``<div class="pg-flowchart">`` wrapper. Out of the box
   Mermaid's SVG output reads as raw geometry — the colors come from
   ``classDef`` declarations in the markdown but the *frame* around
   the whole thing has none of the project's chrome (subtle border,
   drop shadow, max width, dark surface in slate mode). This block
   wraps the SVG in a card so it sits in the page rhythm rather
   than floating against bare background. We also override the
   default Mermaid font with Inter to keep typography consistent
   with the rest of the page.
   ============================================================ */

.pg-flowchart {
  margin: 1.75rem 0 0;
  padding: 1.5rem 1rem;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 14px;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--md-default-bg-color) 100%, transparent) 0%,
    color-mix(in oklab, var(--md-default-bg-color) 92%, var(--pg-navy-900)) 100%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset,
              0 18px 40px -28px color-mix(in oklab, var(--pg-navy-900) 50%, transparent);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Material wraps the mermaid block in a ``.mermaid`` div with
     ``display: flex; justify-content: center;`` — keep the SVG
     centred even when the wrapper isn't full-width. */
  text-align: center;
}

[data-md-color-scheme="slate"] .pg-flowchart {
  background: linear-gradient(180deg,
    var(--pg-navy-900) 0%,
    color-mix(in oklab, var(--pg-navy-900) 70%, var(--pg-navy-950)) 100%);
}

.pg-flowchart .mermaid {
  margin: 0 auto;
  max-width: 100%;
}

/* Type rendering inside the SVG. Mermaid emits ``<text>`` and
   ``<foreignObject>`` for labels — both pick up font from inline
   ``style`` if we don't insist via CSS. ``font-family`` set on
   ``foreignObject`` cascades into nested HTML; ``text`` needs its
   own declaration. The ``classDef``-set fill stays untouched. */
.pg-flowchart .mermaid svg text,
.pg-flowchart .mermaid svg foreignObject {
  font-family: var(--font-sans) !important;
  font-size: 13px;
  letter-spacing: -0.005em;
}

/* Mermaid renders node text via ``foreignObject`` containing a
   ``<div class="nodeLabel">``. The default has zero internal
   margin against the SVG ``<rect>`` border, which produces the
   "text touching the box edge" effect at certain breakpoints.
   Force breathing room and prevent line-wrap clipping. */
.pg-flowchart .mermaid svg .nodeLabel,
.pg-flowchart .mermaid svg .label foreignObject div {
  padding: 4px 6px;
  line-height: 1.35;
  white-space: nowrap;
  overflow: visible;
}

/* Drop shadow on the rendered nodes so they read as foreground
   elements rather than flat shapes. ``filter: drop-shadow`` is the
   SVG-friendly way; ``box-shadow`` doesn't work on SVG ``<g>``.
   Filters on a parent cascade to children, so we apply at the
   cluster level. */
.pg-flowchart .mermaid svg .nodes g.node > rect,
.pg-flowchart .mermaid svg .nodes g.node > polygon,
.pg-flowchart .mermaid svg .nodes g.node > path {
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.18));
  transition: filter 0.18s ease;
}

[data-md-color-scheme="slate"]
.pg-flowchart .mermaid svg .nodes g.node > rect,
[data-md-color-scheme="slate"]
.pg-flowchart .mermaid svg .nodes g.node > polygon,
[data-md-color-scheme="slate"]
.pg-flowchart .mermaid svg .nodes g.node > path {
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.45));
}

/* Hover lift for clickable nodes. Mermaid sets ``cursor: pointer``
   on nodes that have a ``click`` directive; we accentuate it with a
   subtle filter bump so the user gets visual confirmation. */
.pg-flowchart .mermaid svg .nodes g.node[style*="pointer"]:hover > rect,
.pg-flowchart .mermaid svg .nodes g.node[style*="pointer"]:hover > polygon,
.pg-flowchart .mermaid svg .nodes g.node[style*="pointer"]:hover > path {
  filter: drop-shadow(0 6px 16px rgba(27, 163, 169, 0.35));
}

/* Edge labels (the "auto-detect", "pass", "fail" stickers on the
   arrows). Default Mermaid renders them with a small white box;
   we make them tiny pills that match the chrome instead. */
.pg-flowchart .mermaid svg .edgeLabel {
  background: var(--md-default-bg-color);
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--md-default-fg-color--lightest);
  font-size: 11px;
  color: var(--md-default-fg-color--light);
  letter-spacing: 0.01em;
}

[data-md-color-scheme="slate"] .pg-flowchart .mermaid svg .edgeLabel {
  background: var(--pg-navy-900);
}

/* Edges themselves — slightly translucent so the nodes pop. */
.pg-flowchart .mermaid svg .flowchart-link {
  stroke-linecap: round;
  opacity: 0.85;
}

/* Mobile — let the chart scroll horizontally instead of squashing
   itself unreadable into a phone viewport. Vertical layout would
   require regenerating the diagram with ``flowchart TB``; the
   horizontal-with-scroll pattern is the lower-friction win. */
@media screen and (max-width: 720px) {
  .pg-flowchart {
    padding: 1rem 0.5rem;
  }

  .pg-flowchart .mermaid {
    min-width: 720px;
  }
}

/* ============================================================
   Cross-size defensive layout pass
   ============================================================
   Bootstrap-style "containers always lay out cleanly at any
   width" without actually pulling Bootstrap in. Each rule below
   addresses an observed text-touching-border failure mode at a
   specific breakpoint, not a hypothetical one.

   The defensive utility we lean on most is ``min-width: 0`` on
   every flex/grid item — without it, items refuse to shrink past
   their content's intrinsic minimum, which is what causes long
   labels to overflow their cards and overlap neighbouring
   borders. ``overflow-wrap: break-word`` is the secondary belt:
   a word that's wider than the column should break instead of
   horizontal-scrolling the page.
   ============================================================ */

/* Every ``pg-*`` card is a flex/grid item somewhere; let them
   shrink and wrap honestly. */
.pg-stat,
.pg-provider,
.pg-doc-card,
.pg-output,
.pg-flow__step,
.pg-flow__node {
  min-width: 0;
  overflow-wrap: break-word;
}

/* Provider chips — long names ("Google Cloud Build") were clipping
   when the column dropped below ~200px. Allow the secondary
   "checks" count to wrap to its own line on narrow widths. */
.pg-provider {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.85rem 1rem;
  text-decoration: none !important;
}

.pg-provider__name {
  font-weight: 600;
  font-size: 0.92rem;
  letter-spacing: -0.005em;
  overflow-wrap: anywhere;
}

.pg-provider__count {
  font-size: 0.78rem;
  color: var(--md-default-fg-color--light);
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

/* Stat numbers — at very narrow widths the four-column grid drops
   to two and ``font-size: clamp(2.2rem, 3.6vw, 2.9rem)`` could
   leave numbers like "430+" running into the divider rail.
   Tabular numerals + a slightly tighter clamp on the small end
   keep them aligned and inside the gutter. */
.pg-stat {
  padding: 0.65rem 0.5rem;
}

.pg-stat__num {
  font-variant-numeric: tabular-nums lining-nums;
  font-size: clamp(1.9rem, 3.6vw, 2.9rem);
}

.pg-stat__label {
  font-size: clamp(0.7rem, 1.2vw, 0.78rem);
  overflow-wrap: anywhere;
}

/* Doc cards (the providers/standards card lists) — their inner
   ``code`` snippets can be long enough to push the card over its
   container width on phones. Ditto provider names. */
.pg-doc-card * {
  min-width: 0;
}

.pg-doc-card code {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* The ``.pg-install`` pill on the closing CTA contains
   ``pip install pipeline-check`` — short enough on desktop, but
   on phones it sometimes ran to a second line and the text
   crossed the rounded background edge. Center + cap width. */
.pg-install {
  max-width: min(100%, 24rem);
  margin: 0 auto;
  word-break: keep-all;
  white-space: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Section heads — long titles ("Inputs in. Graded report out.")
   could wrap to three lines on a 320px screen and the leading
   ``//`` eyebrow could touch the next character if no margin. */
.pg-section__eyebrow {
  margin-bottom: 0.4rem;
}

.pg-section__title {
  overflow-wrap: balance;
  hyphens: auto;
}

/* Make sure section padding scales down on phones so the band
   edges don't crowd the card content. */
@media screen and (max-width: 720px) {
  .pg-section {
    padding-left: 1rem;
    padding-right: 1rem;
  }

  .pg-stats__inner {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

/* ============================================================
   Severity chips + per-rule cards
   ============================================================
   Provider docs are long lists (30+ rules per CI provider). The
   pre-existing render emitted each rule as a flat H2 + plain-text
   ``**Severity:** HIGH`` line, which gave the eye no grip when
   skimming. This section adds three pieces:

   1. ``.pg-sev`` — a colour-coded severity chip (red/orange/amber/
      teal/grey) used both in the summary table and the per-rule
      tag row. Same chip in both places so eye flows from table
      to body without re-mapping.
   2. ``.pg-tag`` — neutral pill chips for OWASP / ESF / CWE
      mappings. Visually quiet so they don't compete with the
      severity chip.
   3. ``.pg-rule`` — a card wrapper around each rule with a
      severity-coloured left rail. Combined with the
      ``.pg-rule__rec`` framed recommendation block, the page
      reads as "scan severity → drill into rule → here's the fix"
      rather than as one long undifferentiated stream.

   Colour palette principles:
   - Critical / High: warm hues (rose/coral) → urgency
   - Medium: amber → "attention needed"
   - Low / Info: cool hues (teal/grey) → "nice to fix"
   - Slate-mode variants brighten the foregrounds because the
     low-saturation low-luminance tones disappear on dark.
   ============================================================ */

.pg-sev {
  display: inline-block;
  padding: 0.12rem 0.55rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 999px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid transparent;
  vertical-align: middle;
  line-height: 1.5;
}

.pg-sev--critical {
  background: rgba(157, 39, 85, 0.14);
  color: #8a224b;
  border-color: rgba(157, 39, 85, 0.35);
}

.pg-sev--high {
  background: rgba(231, 111, 81, 0.14);
  color: #c84e2e;
  border-color: rgba(231, 111, 81, 0.35);
}

.pg-sev--medium {
  background: rgba(244, 185, 66, 0.14);
  color: #a36e0e;
  border-color: rgba(244, 185, 66, 0.45);
}

.pg-sev--low {
  background: rgba(42, 157, 143, 0.14);
  color: #1e7468;
  border-color: rgba(42, 157, 143, 0.35);
}

.pg-sev--info {
  background: var(--md-default-fg-color--lightest);
  color: var(--md-default-fg-color--light);
  border-color: var(--md-default-fg-color--lighter);
}

[data-md-color-scheme="slate"] .pg-sev--critical {
  background: rgba(231, 88, 142, 0.18);
  color: #f0739a;
  border-color: rgba(231, 88, 142, 0.42);
}

[data-md-color-scheme="slate"] .pg-sev--high {
  background: rgba(243, 145, 117, 0.18);
  color: #f29470;
  border-color: rgba(243, 145, 117, 0.42);
}

[data-md-color-scheme="slate"] .pg-sev--medium {
  background: rgba(244, 185, 66, 0.16);
  color: #f4b942;
  border-color: rgba(244, 185, 66, 0.42);
}

[data-md-color-scheme="slate"] .pg-sev--low {
  background: rgba(95, 212, 200, 0.14);
  color: #5fdce0;
  border-color: rgba(95, 212, 200, 0.35);
}

/* ── OWASP / ESF / CWE neutral pill chips ──────────────────── */

.pg-tag {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  font-size: 0.7rem;
  font-weight: var(--fw-refined);
  letter-spacing: 0.005em;
  border-radius: 6px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  background: color-mix(in oklab,
    var(--md-default-bg-color) 92%,
    var(--md-default-fg-color));
  color: var(--md-default-fg-color--light);
  border: 1px solid var(--md-default-fg-color--lightest);
  vertical-align: middle;
  line-height: 1.6;
}

.pg-tag--owasp {
  color: var(--pg-teal-500);
  border-color: color-mix(in oklab,
    var(--md-default-fg-color--lightest) 60%,
    var(--pg-teal-500) 40%);
}

[data-md-color-scheme="slate"] .pg-tag--owasp {
  color: var(--pg-teal-300);
}

.pg-tag--cwe {
  font-style: italic;
}

/* ── Autofix indicator chip ─────────────────────────────────
   Marks rules that ``pipeline_check --fix`` can patch. Same
   pill geometry as ``.pg-tag`` but with a teal accent — the
   eye reads "this is an action you can take", not just
   metadata. Used both as ``.pg-fix`` in summary tables and
   as ``.pg-fix.pg-fix--rule`` in the per-rule chip row. */
.pg-fix {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  border-radius: 6px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  background: color-mix(in oklab,
    var(--md-default-bg-color) 88%,
    var(--pg-teal-500));
  color: var(--pg-teal-500);
  border: 1px solid color-mix(in oklab,
    var(--pg-teal-500) 30%,
    var(--md-default-fg-color--lightest) 70%);
  vertical-align: middle;
  line-height: 1.6;
  white-space: nowrap;
}

[data-md-color-scheme="slate"] .pg-fix {
  background: color-mix(in oklab,
    var(--md-default-bg-color) 75%,
    var(--pg-teal-500));
  color: var(--pg-teal-300);
}

/* Per-rule chip row already wraps inside ``.pg-rule__tags`` —
   no extra spacing rule needed; the row's flex gap covers it. */

/* ── Per-rule card ─────────────────────────────────────────── */

.pg-rule {
  position: relative;
  margin: 2rem 0 2.25rem;
  padding: 0.4rem 0 0.4rem 1.1rem;
  border-left: 3px solid var(--md-default-fg-color--lightest);
  border-radius: 0 6px 6px 0;
}

.pg-rule--critical { border-left-color: #9d2755; }
.pg-rule--high     { border-left-color: #e76f51; }
.pg-rule--medium   { border-left-color: #f4b942; }
.pg-rule--low      { border-left-color: #2a9d8f; }
.pg-rule--info     { border-left-color: var(--md-default-fg-color--lighter); }

[data-md-color-scheme="slate"] .pg-rule--critical { border-left-color: #f0739a; }
[data-md-color-scheme="slate"] .pg-rule--high     { border-left-color: #f29470; }
[data-md-color-scheme="slate"] .pg-rule--medium   { border-left-color: #f4b942; }
[data-md-color-scheme="slate"] .pg-rule--low      { border-left-color: #5fdce0; }

/* Tighter top margin on the H2 so the rail aligns with the text */
.pg-rule > h2:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.pg-rule__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.4rem;
  margin: 0.4rem 0 1rem;
  align-items: center;
}

/* ── Recommendation block ──────────────────────────────────── */

.pg-rule__rec {
  margin-top: 1.1rem;
  padding: 0.85rem 1.1rem 1rem;
  background: color-mix(in oklab,
    var(--md-default-bg-color) 95%,
    var(--pg-teal-500));
  border-left: 2px solid var(--pg-teal-500);
  border-radius: 0 8px 8px 0;
}

[data-md-color-scheme="slate"] .pg-rule__rec {
  background: color-mix(in oklab,
    var(--md-default-bg-color) 86%,
    var(--pg-teal-500));
  border-left-color: var(--pg-teal-400);
}

.pg-rule__rec > p:first-child,
.pg-rule__rec > p:first-of-type {
  margin-top: 0;
}

.pg-rule__rec > *:last-child {
  margin-bottom: 0;
}

/* The "Recommended action" lead — slightly smaller, uppercase
   tracking so it reads as a label rather than competing with
   surrounding H3s. Markdown emits this as ``<p><strong>...``. */
.pg-rule__rec > p:first-of-type strong:first-child {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pg-teal-500);
  display: inline-block;
  margin-bottom: 0.3rem;
}

[data-md-color-scheme="slate"] .pg-rule__rec > p:first-of-type strong:first-child {
  color: var(--pg-teal-300);
}

/* Severity column in the summary table — let the chip hug its
   content rather than stretch to the column width. */
.md-typeset table:not([class]) td .pg-sev {
  font-size: 0.66rem;
}

/* Mobile — the tag row gets crowded; drop chip padding a touch. */
@media screen and (max-width: 720px) {
  .pg-rule {
    padding-left: 0.85rem;
  }

  .pg-rule__rec {
    padding: 0.7rem 0.85rem 0.8rem;
  }

  .pg-tag {
    font-size: 0.66rem;
  }
}

/* Mid-screen TOC sidebar (``.md-sidebar--secondary``) overlap. At
   widths where the secondary sidebar is shown but cramped (say
   60-76em), Material lets it crowd the article. Hide it below the
   primary breakpoint so the article gets the full content column. */
@media screen and (max-width: 60em) {
  .md-sidebar--secondary {
    display: none;
  }
}

/* ============================================================
   Refinement layer — typography, interaction, print
   ============================================================
   Additive polish that sits on top of the established design
   system. None of these change layout; they sharpen rendering
   and unify the interaction language across the site.
   ============================================================ */

/* ── Anchor scroll: smooth, with header clearance ──────────────
   Material's header is sticky. Without scroll-padding, jumping to
   an in-page anchor (`#section-id`) hides the heading underneath
   the chrome. Padding equals the topbar + tabs height. Smoothness
   is opt-out for reduced-motion users. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 4.5rem;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ── Variable-font optical sizing + legibility ─────────────────
   Mona Sans + JetBrains Mono ship optical-size axes; opting in
   means the hero's clamp-scaled display H1 actually uses the
   "display" optical cut, while body copy uses the "text" cut.
   ``optimizeLegibility`` enables kerning + contextual ligatures
   on browsers that gate them behind this hint. */
html {
  text-rendering: optimizeLegibility;
  font-optical-sizing: auto;
}

/* ── Modern line-breaking on prose ──────────────────────────────
   Headings already get ``text-wrap: balance`` per section. For
   body paragraphs and lists, ``pretty`` is the better trade-off:
   the browser scans the last few lines and rebalances to avoid
   single-word last lines (widows). Costs nothing on browsers
   that don't support it (silently falls back to the default).
   Only target unclassed prose <p> so designer-set ``balance`` on
   hero/section/CTA leads (which carry classes like .pg-hero__lede)
   keeps winning by intent rather than by specificity tie-break. */
.md-typeset p:not([class]),
.md-typeset li,
.md-typeset dd,
.md-typeset blockquote {
  text-wrap: pretty;
}

/* ── Brand-tinted text selection ───────────────────────────────
   The default browser blue selection on a near-black slate canvas
   reads as alien chrome. A 30% teal wash matches the rest of the
   accent language. */
::selection {
  background: color-mix(in oklab, var(--pg-teal-500) 30%, transparent);
  color: inherit;
}

[data-md-color-scheme="slate"] ::selection {
  background: color-mix(in oklab, var(--pg-teal-400) 32%, transparent);
  color: #fff;
}

/* ── Unified focus-visible baseline ────────────────────────────
   ``:where(...)`` keeps specificity at zero so any component
   (.md-button, .pg-flow__node, .pg-sortable, …) that already
   declares its own focus styling wins automatically. This rule
   is the safety net for everything else: prose links, footnote
   refs, ToC items, form controls Material doesn't restyle. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--pg-teal-400);
  outline-offset: 2px;
  border-radius: 4px;
}

/* On dark navy chrome (header/footer/home), shift to the brighter
   teal-300 so the ring stays visible. */
body:has(.pg-home) :where(a, button, input):focus-visible,
.md-header :where(a, button, input):focus-visible,
.md-footer :where(a, button, input):focus-visible {
  outline-color: var(--pg-teal-300);
}

/* ── Tabular numerics on inner-page tables ─────────────────────
   Provider rule lists, scoring matrices, and standards control
   tables all align numeric columns ("36 checks", "v0.4.2", line
   numbers). Lining + tabular figures lock each digit to the same
   advance width so columns stop drifting between rows. */
.md-typeset table:not([class]) td {
  font-variant-numeric: tabular-nums lining-nums;
}

/* ── Refined <kbd> key cap ─────────────────────────────────────
   Material's default kbd reads as a 90s tech-blog inline tag.
   Hairline pill in the brand palette with a faint inset highlight
   reads like a real key cap. */
.md-typeset kbd {
  font-family: var(--font-mono);
  font-size: 0.78em;
  font-weight: 600;
  padding: 0.1em 0.5em;
  border-radius: 6px;
  background: color-mix(in oklab,
    var(--md-default-bg-color) 92%,
    var(--md-default-fg-color));
  border: 1px solid var(--md-default-fg-color--lightest);
  box-shadow: 0 1px 0 var(--md-default-fg-color--lightest);
  color: var(--md-default-fg-color);
  vertical-align: 1px;
  letter-spacing: 0.02em;
}

[data-md-color-scheme="slate"] .md-typeset kbd {
  background: color-mix(in oklab,
    var(--md-default-bg-color) 70%,
    var(--md-default-fg-color));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 1px 0 rgba(0, 0, 0, 0.4);
}

/* ── Search input focus ring ───────────────────────────────────
   Material's default search input has no visible focus state — the
   surface stays the same colour. A subtle teal halo confirms the
   keyboard caret is captured, matching the rest of the focus
   language. */
.md-search__form:focus-within {
  background: color-mix(in oklab,
    var(--md-default-fg-color) 12%, transparent);
  box-shadow: 0 0 0 2px color-mix(in oklab,
    var(--pg-teal-400) 35%, transparent);
}

body:has(.pg-home) .md-search__form:focus-within,
.md-header .md-search__form:focus-within {
  background: rgba(255, 255, 255, 0.14);
  box-shadow: 0 0 0 2px color-mix(in oklab,
    var(--pg-teal-400) 50%, transparent);
}

/* ── Inline code: dial-back the slate tint ─────────────────────
   The base rule mixes the dark canvas with 20% teal, which can
   read as "highlighted" rather than "muted brand" against the
   navy chrome. ~14% lands in the right place. Light-mode tint is
   left untouched. */
[data-md-color-scheme="slate"] .md-typeset code {
  background: color-mix(in oklab,
    var(--md-default-bg-color) 86%,
    var(--pg-teal-500));
  border-color: color-mix(in oklab,
    var(--md-default-bg-color) 78%,
    var(--pg-teal-500));
}

/* ── Print + save-as-PDF ──────────────────────────────────────
   Auditors save pages to PDF for evidence packets. Strip the
   chrome and force black-on-white prose so the printed page
   reads like a clean technical document, not a screenshot of
   a docs site. Hyperlinks expand inline so reference URLs
   survive the print. */
@media print {
  .md-header,
  .md-tabs,
  .md-footer,
  .md-sidebar,
  body::before {
    display: none !important;
  }

  .md-main,
  .md-main__inner,
  .md-content,
  .md-content__inner {
    max-width: none !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  body,
  .md-typeset {
    background: #fff !important;
    color: #000 !important;
  }

  .md-typeset h1,
  .md-typeset h2,
  .md-typeset h3,
  .md-typeset h4 {
    color: #000 !important;
    page-break-after: avoid;
  }

  .md-typeset h1::after,
  .md-typeset h2::before {
    display: none !important;
  }

  .md-typeset a {
    color: #000 !important;
    text-decoration: underline !important;
  }

  /* Expand external links inline so the reference is preserved
     when the page is printed and the cursor is gone. */
  .md-typeset a[href^="http"]::after {
    content: " (" attr(href) ")" !important;
    font-size: 0.85em;
    color: #555;
  }

  .md-typeset pre,
  .md-typeset .highlight,
  .md-typeset .codehilite {
    background: #f6f8fa !important;
    border: 1px solid #d0d7de !important;
    page-break-inside: avoid;
  }

  .md-typeset table:not([class]) {
    page-break-inside: avoid;
  }

  /* Home-page hero / stats / CTA collapse to plain prose blocks
     on paper — the navy gradients and animated lines are noise
     in print. */
  .pg-hero,
  .pg-cta,
  .pg-stats,
  .pg-section {
    background: #fff !important;
    color: #000 !important;
    padding: 1rem 0 !important;
    border: none !important;
  }

  .pg-hero__lede,
  .pg-cta p,
  .pg-section__lede {
    color: #333 !important;
  }

  .pg-terminal,
  .pg-patrol,
  .pg-flowchart {
    display: none !important;
  }
}

