/* GENERATED FILE — do not edit.
 * Built from variables.css, typography.css, layout.css, components.css, utilities.css by css/build.php.
 * Edit those sources, then run: php css/build.php
 */

/* ===== variables.css ===== */
/* ---------- Inter (self-hosted) ----------
 * Inter is licensed under the SIL Open Font License 1.1 — see
 * assets/fonts/LICENSE.txt, which must ship alongside these files.
 *
 * Self-hosted rather than loaded from Google Fonts, on measured grounds: with
 * the third-party font request blocked, /osha-recordkeeping moved from CLS
 * 0.109 to 0 and from FCP/LCP 2.9s to 1.6s in Lighthouse mobile simulation.
 * The third-party stylesheet was render-blocking on a separate origin, so it
 * cost a DNS + TLS handshake before any text could be styled, and the late
 * swap resized content that had already been laid out.
 *
 * One variable file covers every weight the site uses (400-800), which is what
 * Google was already serving — so this is fewer bytes and fewer connections,
 * not a trade. Subsetting matches Google's own latin / latin-ext split.
 */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Fraunces (self-hosted) — V2 editorial display serif ----------
 * Latin subset only, same self-hosting rationale as Inter (one request, no
 * third-party origin, no render-blocking swap). Used for display + section
 * headings via --font-serif; Inter remains the UI/body voice. Two weights
 * cover the display range the site uses (400 regular, 600 for headings).
 * NOTE (pre-deploy): the woff2 binaries are provisioned into the font asset
 * pipeline the same way inter-latin.woff2 is (they are not git-tracked here). */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 560 600;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/**
 * Design tokens. Every color, spacing value, radius, and shadow used anywhere
 * on the site should reference one of these — never a raw hex/px value in a
 * component file. This is what keeps every page consistent.
 *
 * V2 "Clean Editorial": brand accent is blue #2457f5 with a green #12b56a
 * secondary; navy is the utility surface (nav/footer/stat bands); Fraunces is
 * the display serif. Existing token NAMES are kept so pages not yet migrated
 * keep working; the values shift to the editorial palette.
 */
:root {
  /* Color — V2 editorial palette */
  --color-bg: #ffffff;
  --color-bg-secondary: #f7f9fc;
  --color-paper: #fbfaf7;
  --color-text: #0d1726;
  --color-text-secondary: #44536a;
  --color-text-muted: #6b7a93;
  --color-border: #e4eaf3;
  --color-border-strong: #d3deed;
  --color-accent: #2457f5;
  --color-accent-hover: #1a3fc0;
  --color-accent-bg: #eef3ff;
  --color-green: #12b56a;
  --color-green-d: #0a8c51;
  --color-green-bg: #e7f8ef;
  --color-green-hl: #c9f3dd;
  --color-navy: #0b1b33;
  --color-success: #12b56a;
  --color-success-bg: #e7f8ef;
  --color-danger: #e5484d;
  --color-danger-bg: #fdeced;
  --color-amber: #f5a524;
  --color-amber-bg: #fef4e2;
  --color-violet: #7c5cff;

  /* Text on dark surfaces (footer, dark CTA bands) — now navy */
  --color-dark-bg: #0b1b33;
  --color-dark-bg-secondary: #122444;
  --color-dark-text: #eaf0fb;
  --color-dark-text-secondary: #9fb0cf;
  --color-dark-border: rgba(255, 255, 255, 0.1);

  /* Typography */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;

  /* V2 "Clean Editorial" short aliases — used by the .v2 / .v2home component
   * library so component CSS stays terse while every value still traces back to
   * a defined token. */
  --ink: var(--color-text);
  --ink-2: var(--color-text-secondary);
  --ink-3: var(--color-text-muted);
  --ink-4: #97a4ba;
  --line: var(--color-border);
  --line-2: var(--color-border-strong);
  --blue: var(--color-accent);
  --blue-d: var(--color-accent-hover);
  --green: var(--color-green);
  --green-d: var(--color-green-d);
  --green-bg: var(--color-green-bg);
  --green-hl: var(--color-green-hl);
  --navy: var(--color-navy);
  --paper: var(--color-paper);
  --serif: var(--font-serif);
  --gradh: linear-gradient(100deg, #2457f5, #1b86e0 55%, #12b56a);
  --sh-sm: 0 1px 2px rgba(13, 23, 38, 0.05), 0 2px 6px rgba(13, 23, 38, 0.04);
  --sh: 0 12px 34px -14px rgba(13, 23, 38, 0.2), 0 4px 10px -6px rgba(13, 23, 38, 0.08);
  --sh-lg: 0 40px 80px -36px rgba(13, 23, 38, 0.4);

  /* Spacing scale — 4px base, used for every margin/padding/gap */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem; /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.25rem; /* 20px */
  --space-6: 1.5rem; /* 24px */
  --space-8: 2rem; /* 32px */
  --space-10: 2.5rem; /* 40px */
  --space-12: 3rem; /* 48px */
  --space-16: 4rem; /* 64px */
  --space-20: 5rem; /* 80px */
  --space-24: 6rem; /* 96px */
  --space-32: 8rem; /* 128px */

  /* Radius */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-full: 999px;

  /* Shadow — soft, never heavy */
  --shadow-sm: 0 1px 2px 0 rgb(15 23 42 / 0.04);
  --shadow-md: 0 4px 16px -4px rgb(15 23 42 / 0.08), 0 2px 6px -2px rgb(15 23 42 / 0.04);
  --shadow-lg: 0 16px 40px -12px rgb(15 23 42 / 0.14), 0 4px 12px -4px rgb(15 23 42 / 0.06);
  --shadow-focus: 0 0 0 3px rgb(36 87 245 / 0.25);

  /* Layout */
  --content-max: 1280px;
  --content-narrow: 760px;

  /* Motion — subtle, consistent easing everywhere */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 150ms;
  --duration-base: 250ms;
  --duration-slow: 500ms;
}

/* ===== typography.css ===== */
/**
 * Type scale. Large, confident headlines; restrained body text. Every
 * heading/body size used on the site should come from here, not a one-off
 * font-size in a component file.
 */

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-sans);
  color: var(--color-text);
  font-size: 1rem;
  line-height: 1.6;
  font-feature-settings: 'cv11', 'ss01';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text);
  margin: 0;
}

/* Hero-scale headline — used once per page, at most */
.text-display {
  font-size: clamp(2.5rem, 4.5vw, 3.75rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.08;
}

h1, .h1 {
  font-size: clamp(2rem, 3.5vw, 2.75rem);
}

h2, .h2 {
  font-size: clamp(1.625rem, 2.75vw, 2.125rem);
}

h3, .h3 {
  font-size: 1.375rem;
}

h4, .h4 {
  font-size: 1.125rem;
}

p {
  margin: 0;
}

.text-lead {
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}

.text-body {
  font-size: 1rem;
  color: var(--color-text-secondary);
  line-height: 1.7;
}

.text-small {
  font-size: 0.875rem;
  color: var(--color-text-secondary);
}

.text-eyebrow {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
}

a {
  color: inherit;
  text-decoration: none;
}

::selection {
  background: var(--color-accent);
  color: #fff;
}

/* ===== layout.css ===== */
/**
 * Reset, container, and section rhythm. Mobile-first: base rules target
 * mobile, breakpoints add complexity going up.
 */

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

* {
  margin: 0;
}

html, body {
  height: 100%;
}

body {
  background: var(--color-bg);
  overflow-x: hidden;
}

img, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

button {
  font: inherit;
}

/* Content container — max-width per spec, fluid gutters below it */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.container-narrow {
  width: 100%;
  max-width: var(--content-narrow);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .container, .container-narrow {
    padding-inline: var(--space-8);
  }
}

/* Section rhythm — consistent vertical spacing between every section on every page */
.section {
  padding-block: var(--space-16);
}

@media (min-width: 768px) {
  .section {
    padding-block: var(--space-24);
  }
}

.section-tight {
  padding-block: var(--space-10);
}

@media (min-width: 768px) {
  .section-tight {
    padding-block: var(--space-16);
  }
}

.section-bg {
  background: var(--color-bg-secondary);
}

.section-dark {
  background: var(--color-dark-bg);
  color: var(--color-dark-text);
}

/* typography.css sets color directly on h1-h6 (not just via inheritance), so it
   always wins over .section-dark's inherited color unless overridden explicitly
   here too — this is what was making dark-band headings nearly invisible. */
.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4,
.section-dark h5,
.section-dark h6 {
  color: var(--color-dark-text);
}

.section-dark .text-body,
.section-dark .text-small,
.section-dark .text-lead {
  color: var(--color-dark-text-secondary);
}

.section-dark .text-eyebrow {
  color: #93c5fd;
}

/* Grid helpers */
.grid {
  display: grid;
  gap: var(--space-6);
}

.grid-2 { grid-template-columns: repeat(1, 1fr); }
.grid-3 { grid-template-columns: repeat(1, 1fr); }
.grid-4 { grid-template-columns: repeat(1, 1fr); }

@media (min-width: 640px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 900px) {
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

.flex {
  display: flex;
}

.flex-center {
  display: flex;
  align-items: center;
}

.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

/* Two-column alternating layout (image + text), used across feature sections */
.split {
  display: grid;
  gap: var(--space-10);
  align-items: center;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-16);
  }
  /* Gives the visual side more room — used sparingly, for the sections
   * meant to feel like the flagship/widest compositions on the page. */
  .split-wide {
    grid-template-columns: 0.85fr 1.15fr;
  }
  .split-reverse {
    direction: rtl;
  }
  .split-reverse > * {
    direction: ltr;
  }
}

.text-center {
  text-align: center;
}

.mx-auto {
  margin-inline: auto;
}

/* ===== components.css ===== */
/**
 * Component library. Every page is built from these — a page file should
 * rarely need a one-off style block.
 */

/* ---------- Buttons ---------- */
.btn svg {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 46px;
  padding-inline: var(--space-6);
  border-radius: var(--radius-full);
  font-size: 0.9375rem;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
  white-space: nowrap;
}

.btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.btn-sm {
  height: 38px;
  padding-inline: var(--space-5);
  font-size: 0.875rem;
}

.btn-primary {
  background: var(--color-accent);
  color: #fff;
}

.btn-primary:hover {
  background: var(--color-accent-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn-secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-border);
}

.btn-secondary:hover {
  border-color: var(--color-text-secondary);
  transform: translateY(-1px);
}

.btn-on-dark {
  background: rgba(248, 250, 252, 0.08);
  color: var(--color-dark-text);
  border-color: var(--color-dark-border);
}

.btn-on-dark:hover {
  background: rgba(248, 250, 252, 0.14);
  transform: translateY(-1px);
}

.btn-block {
  width: 100%;
}

/* ---------- Badge / eyebrow pill ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-full);
  background: var(--color-accent-bg);
  color: var(--color-accent);
  font-size: 0.8125rem;
  font-weight: 600;
}

.badge svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ---------- Cards ---------- */
.card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  transition: transform var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}

.card-hover:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: rgb(37 99 235 / 0.25);
}

.card-flat {
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
}

/* Icon circle used inside feature cards */
.icon-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--color-accent-bg);
  color: var(--color-accent);
  flex-shrink: 0;
}

.icon-circle svg {
  width: 24px;
  height: 24px;
}

.icon-circle-lg {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
}

/* ---------- Site header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
}

.site-logo {
  display: flex;
  align-items: center;
}

.site-logo img {
  height: 28px;
  width: auto;
}

.site-nav {
  display: none;
  align-items: center;
  gap: var(--space-8);
}

.site-nav a {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text-secondary);
  transition: color var(--duration-fast) var(--ease-out);
}

.site-nav a:hover,
.site-nav a.active {
  color: var(--color-text);
}

.site-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: none;
  cursor: pointer;
  color: var(--color-text);
}

.nav-toggle .icon-close {
  display: none;
}

.nav-toggle.is-open .icon-menu {
  display: none;
}

.nav-toggle.is-open .icon-close {
  display: inline-flex;
}

/* Tied to the exact same 900px breakpoint as .site-nav/.nav-toggle so Login and
   Request a Demo never show alongside the hamburger — they live in the mobile
   menu below 900px instead. (Not reusing .hide-mobile: that utility is shared
   with unrelated content elsewhere at a different breakpoint.) */
.header-cta {
  display: none;
}

@media (min-width: 900px) {
  .site-nav {
    display: flex;
  }
  .nav-toggle {
    display: none;
  }
  .header-cta {
    display: inline-flex;
  }
}

.mobile-menu {
  display: none;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg);
}

.mobile-menu.is-open {
  display: block;
}

.mobile-menu .container {
  padding-block: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.mobile-menu a {
  padding: var(--space-3) 0;
  font-weight: 500;
  color: var(--color-text-secondary);
  border-bottom: 1px solid var(--color-border);
}

.mobile-menu a:last-child {
  border-bottom: none;
}

@media (min-width: 900px) {
  .mobile-menu {
    display: none !important;
  }
}

/* ---------- Hero ---------- */
/* Layered, atmospheric background — several soft radial glows plus a sparse
 * dot grid, all at low alpha, so the page reads as "lit by the product"
 * rather than a flat white section with a picture on it. Kept as ordinary
 * background-image layers (not pseudo-elements) since nothing here needs a
 * blend mode; the grain texture below is the one layer that does. */
.hero {
  position: relative;
  isolation: isolate;
  padding-block: var(--space-12) var(--space-10);
  overflow: hidden;
  background-color: #fbfcfe;
  background-image:
    radial-gradient(circle, rgb(37 99 235 / 0.05) 1px, transparent 1px),
    radial-gradient(ellipse 55% 42% at 50% 4%, rgb(99 102 241 / 0.09), transparent 70%),
    radial-gradient(ellipse 65% 55% at 50% 60%, rgb(37 99 235 / 0.13), transparent 70%),
    radial-gradient(ellipse 45% 40% at 92% 96%, rgb(34 211 238 / 0.09), transparent 65%),
    radial-gradient(ellipse 40% 35% at 4% 92%, rgb(167 139 250 / 0.07), transparent 60%),
    radial-gradient(ellipse 90% 70% at 50% 30%, #ffffff, transparent 75%);
  background-size: 26px 26px, auto, auto, auto, auto, auto;
  background-repeat: repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat;
}

/* Faint grain so the gradients above read as atmosphere, not a flat digital
 * blend — a tiled SVG turbulence filter at ~2% opacity via overlay blend. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.025;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (min-width: 768px) {
  .hero {
    padding-block: var(--space-20) var(--space-16);
  }
}

.hero-content {
  max-width: 760px;
  margin-inline: auto;
  text-align: center;
}

.hero-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-8);
}

@media (min-width: 540px) {
  .hero-actions {
    flex-direction: row;
  }
}

.hero-preview {
  position: relative;
  margin-top: var(--space-16);
  max-width: 1180px;
  margin-inline: auto;
}

/* Lets the dashboard's own blue/indigo/aqua tones bleed well past its
 * rounded corners and dissolve into the hero background, so the glow reads
 * as coming from the product rather than stopping abruptly at its edge. */
.hero-preview::before {
  content: '';
  position: absolute;
  inset: -90px;
  z-index: -1;
  filter: blur(50px);
  pointer-events: none;
  background:
    radial-gradient(ellipse 55% 50% at 28% 32%, rgb(37 99 235 / 0.22), transparent 65%),
    radial-gradient(ellipse 50% 45% at 74% 26%, rgb(99 102 241 / 0.18), transparent 65%),
    radial-gradient(ellipse 48% 45% at 62% 82%, rgb(34 211 238 / 0.15), transparent 65%);
}

@media (min-width: 768px) {
  .hero-preview::before {
    inset: -160px;
    filter: blur(70px);
  }
}

.hero-dashboard-img {
  position: relative;
  width: 100%;
  height: auto;
  display: block;
  animation: heroFloat 6s ease-in-out infinite;
}

@keyframes heroFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-14px); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-dashboard-img {
    animation: none;
  }
}

/* A wide dashboard shot shrinks to illegible tiny text at mobile widths —
 * crop into the KPI row instead of shrinking the whole composition, so the
 * mobile hero stays legible rather than merely decorative. */
@media (max-width: 767px) {
  .hero-dashboard-img {
    height: 220px;
    object-fit: cover;
    object-position: 32% 28%;
    border-radius: var(--radius-md);
  }
}

/* Wide annotated photos (e.g. the Company page story images) crop hard on
 * the sides at a narrow mobile column if the height stays fixed — reducing
 * the height keeps closer to the source aspect ratio so corner content
 * (callout labels, etc.) doesn't get cut off. */
.split-photo {
  width: 100%;
  height: 360px;
  object-fit: cover;
  border-radius: var(--radius-lg);
  display: block;
}

@media (max-width: 767px) {
  .split-photo {
    height: 220px;
  }
}

.hero-preview .pv {
  min-height: 380px;
}

@media (min-width: 640px) {
  .hero-preview .pv {
    min-height: 460px;
  }
}

/* ---------- Stats ---------- */
.stat-value {
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

.section-dark .stat-value {
  color: var(--color-dark-text);
}

.stat-label {
  margin-top: var(--space-1);
  font-size: 0.9375rem;
}

/* ---------- Testimonial ---------- */
.testimonial-quote {
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--color-text);
}

.testimonial-author {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.testimonial-avatar {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background: var(--color-accent-bg);
  color: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.9375rem;
  flex-shrink: 0;
}

/* ---------- FAQ (native <details>, no JS needed) ---------- */
.faq-item {
  border-bottom: 1px solid var(--color-border);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-5);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary .faq-chevron {
  flex-shrink: 0;
  transition: transform var(--duration-base) var(--ease-out);
  color: var(--color-text-secondary);
}

.faq-item[open] summary .faq-chevron {
  transform: rotate(180deg);
}

.faq-item p {
  padding-bottom: var(--space-5);
  color: var(--color-text-secondary);
}

/* ---------- Forms ---------- */
.form-field {
  margin-bottom: var(--space-5);
}

.form-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: 0.875rem;
  font-weight: 600;
}

.form-input,
.form-textarea {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.9375rem;
  color: var(--color-text);
  background: var(--color-bg);
  transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

.form-input:focus,
.form-textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

.form-input.is-invalid,
.form-textarea.is-invalid {
  border-color: var(--color-danger);
}

/* Browser autofill otherwise forces a yellow background + its own text color */
.form-input:-webkit-autofill,
.form-textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--color-text);
  box-shadow: 0 0 0 1000px var(--color-bg) inset;
}

.form-error {
  margin-top: var(--space-2);
  font-size: 0.8125rem;
  color: var(--color-danger);
}

.form-textarea {
  resize: vertical;
  min-height: 140px;
}

.form-alert {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
  margin-bottom: var(--space-5);
}

.form-alert.alert-success {
  background: var(--color-success-bg);
  color: #15803d;
  border: 1px solid rgb(34 197 94 / 0.25);
}

.form-alert.alert-danger {
  background: var(--color-danger-bg);
  color: #b91c1c;
  border: 1px solid rgb(239 68 68 / 0.25);
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--color-dark-bg);
  color: var(--color-dark-text-secondary);
  padding-block: var(--space-16) var(--space-8);
}

/* Column headings. h3 rather than h6: the footer follows page sections that use
   h2, and jumping straight to h6 is a heading-order violation on every page. */
.site-footer h3 {
  color: var(--color-dark-text);
  font-size: 0.9375rem;
  font-weight: 600;
  margin-bottom: var(--space-4);
}

/* .text-small carries the light-background secondary colour, which measures
   2.35:1 against the dark footer — below the 4.5:1 minimum. On this surface the
   dark-theme token applies instead, at roughly 6.7:1. */
.site-footer .text-small {
  color: var(--color-dark-text-secondary);
}

.site-footer a {
  color: var(--color-dark-text-secondary);
  transition: color var(--duration-fast) var(--ease-out);
}

.site-footer a:hover {
  color: var(--color-dark-text);
}

.site-footer .site-logo img {
  filter: brightness(0) invert(1);
}

.footer-links {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: 0.9375rem;
}

.footer-bottom {
  margin-top: var(--space-12);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-dark-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  font-size: 0.875rem;
}

@media (min-width: 640px) {
  .footer-bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.social-links {
  display: flex;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
}

.social-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-dark-border);
}

.social-links svg {
  width: 16px;
  height: 16px;
}

/* ---------- Breadcrumb (used on secondary-page headers) ---------- */
.page-header {
  padding-block: var(--space-12) var(--space-10);
  background: var(--color-bg-secondary);
  border-bottom: 1px solid var(--color-border);
}

/* Standalone breadcrumb bar for pages built on render_hero(), which have no
   .page-header to host the trail. Sits flush above the hero and inherits the
   hero's own background so it reads as part of it. */
.breadcrumb-bar {
  background-color: #fbfcfe;
  padding-block: var(--space-6) 0;
}

.breadcrumb-bar .breadcrumb {
  margin-bottom: 0;
}

.breadcrumb-bar + .hero {
  padding-block-start: var(--space-10);
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.875rem;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-4);
}

.breadcrumb svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.breadcrumb a {
  color: var(--color-text-secondary);
}

.breadcrumb a:hover {
  color: var(--color-accent);
}

.breadcrumb .current {
  color: var(--color-text);
  font-weight: 500;
}

/* ---------- Legal page body (Privacy Policy / Terms) ---------- */
.legal-content > p {
  color: var(--color-text-secondary);
  line-height: 1.7;
  margin-bottom: var(--space-6);
}

.legal-content h2 {
  font-size: 1.375rem;
  margin-top: var(--space-12);
  margin-bottom: var(--space-4);
}

.legal-content h2:first-child {
  margin-top: 0;
}

.legal-content h3 {
  font-size: 1.0625rem;
  margin-top: var(--space-6);
  margin-bottom: var(--space-3);
}

.legal-content ul {
  color: var(--color-text-secondary);
  line-height: 1.7;
  padding-left: 1.25rem;
  margin-bottom: var(--space-6);
}

.legal-content ul li {
  margin-bottom: var(--space-2);
}

.legal-content .legal-contact {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  color: var(--color-text-secondary);
}

.legal-content .legal-contact svg {
  color: var(--color-accent);
}

/* ---------- Product visuals ----------
 * Composed "product moments" for hero/feature sections — floating cards,
 * KPI stats, rings, bars — never a real app screenshot. Each .pv is a
 * self-contained stage: soft gradient + blurred color blobs behind,
 * one or two focal cards floating above. Keep every composition cropped
 * and partial; nothing here should render like a full app screen.
 */
/* No background, border, or radius of its own — this is layout space, not
 * a container. The illustration inside supplies its own elevation (see
 * .pv-card / .pv-photo) and is meant to read as an object floating in the
 * page's own whitespace, not a card nested inside another card. */
.pv {
  position: relative;
  min-height: 320px;
  padding: var(--space-10) var(--space-8);
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (min-width: 640px) {
  .pv {
    min-height: 380px;
    padding: var(--space-16) var(--space-12);
  }
}

.pv-stage {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 380px;
}

/* Layered shadow — a crisp near shadow, a soft mid shadow, and a wide,
 * very low-opacity blue-tinted shadow standing in for ambient glow beneath
 * the object. This is what makes the illustration read as an elevated
 * product render rather than a flat panel. */
.pv-card {
  position: relative;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(226, 232, 240, 0.8);
  border-radius: var(--radius-lg);
  box-shadow:
    0 1px 2px rgb(15 23 42 / 0.06),
    0 10px 20px -8px rgb(15 23 42 / 0.10),
    0 32px 56px -20px rgb(15 23 42 / 0.14),
    0 40px 70px -24px rgb(37 99 235 / 0.16);
  padding: var(--space-6);
}

/* Same elevation treatment for illustrations that are a plain photo/image
 * rather than a composed .pv-card (e.g. the Reporting screenshot). */
.pv-photo {
  display: block;
  border-radius: var(--radius-lg);
  box-shadow:
    0 1px 2px rgb(15 23 42 / 0.06),
    0 10px 20px -8px rgb(15 23 42 / 0.10),
    0 32px 56px -20px rgb(15 23 42 / 0.14),
    0 40px 70px -24px rgb(37 99 235 / 0.16);
}

.pv-card-sm {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
}

.pv-float {
  position: absolute;
  z-index: 2;
  transition: transform var(--duration-slow) var(--ease-out);
}

/* A composition with 4+ floating cards is too crowded on a narrow stage —
 * this trims secondary cards below 640px rather than reusing .hide-mobile,
 * whose `display: initial` reset would collapse these to inline and break
 * their box model. */
.pv-float.pv-hide-mobile {
  display: none;
}

@media (min-width: 640px) {
  .pv-float.pv-hide-mobile {
    display: block;
  }
}

.pv:hover .pv-float {
  transform: translateY(-4px) rotate(var(--pv-rot, 0deg));
}

/* ---------- Rings / bars / sparklines ---------- */
.pv-ring {
  display: block;
}

.pv-ring-track {
  fill: none;
  stroke: var(--color-border);
  stroke-width: 8;
}

.pv-ring-fill {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 8;
  stroke-linecap: round;
  transform-origin: center;
  transform: rotate(-90deg);
}

.pv-ring-label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.pv-ring-value {
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-text);
  line-height: 1;
}

.pv-ring-caption {
  margin-top: var(--space-1);
  max-width: 78%;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.3;
}

.pv-bar-track {
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-border);
  overflow: hidden;
}

.pv-bar-fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}

.pv-sparkline {
  display: block;
  overflow: visible;
}

/* ---------- Stats, trends, pills, avatars ---------- */
.pv-stat-value {
  font-size: 1.625rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-text);
  line-height: 1.1;
}

.pv-stat-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-secondary);
}

.pv-trend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.8125rem;
  font-weight: 700;
}

.pv-trend svg {
  width: 14px;
  height: 14px;
}

.pv-trend-up { color: var(--color-success); }
.pv-trend-down { color: var(--color-danger); }
.pv-trend-flat { color: var(--color-text-secondary); }

.pv-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
}

.pv-pill svg { width: 13px; height: 13px; }

.pv-pill-accent { background: var(--color-accent-bg); color: var(--color-accent); }
.pv-pill-success { background: var(--color-success-bg); color: #15803d; }
.pv-pill-danger { background: var(--color-danger-bg); color: #b91c1c; }
.pv-pill-warning { background: #fffbeb; color: #b45309; }
.pv-pill-neutral { background: var(--color-bg-secondary); color: var(--color-text-secondary); }

.pv-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-accent-bg);
  color: var(--color-accent);
  font-size: 0.75rem;
  font-weight: 700;
  flex-shrink: 0;
}

/* ---------- Notification / toast card ---------- */
.pv-notification {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  max-width: 240px;
  border-left: 4px solid var(--color-border);
}

.pv-notification.sev-danger { border-left-color: var(--color-danger); }
.pv-notification.sev-warning { border-left-color: #d97706; }
.pv-notification.sev-accent { border-left-color: var(--color-accent); }
.pv-notification.sev-success { border-left-color: var(--color-success); }
/* A GENUINE REPRESENTATIONAL GAP, not a want (D-027's constraint). The product has a
   neutral tone — EquipmentReadiness::tone() returns 'neutral' for no_schedule — and the
   notification primitive could not express it, so an absence would have rendered
   indistinguishable from an unstyled row. This is a tone variant on an existing primitive,
   not a new primitive. */
.pv-notification.sev-neutral { border-left-color: var(--color-text-secondary); }

.pv-notification-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  flex-shrink: 0;
}

.pv-notification-icon svg { width: 16px; height: 16px; }

.pv-notification-title {
  display: block;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--color-text);
  line-height: 1.3;
}

.pv-notification-sub {
  display: block;
  margin-top: 2px;
  font-size: 0.75rem;
  color: var(--color-text-secondary);
  line-height: 1.3;
}

/* ---------- Certificate card ---------- */
.pv-certificate {
  position: relative;
  text-align: center;
  border: 1px solid rgb(180 140 60 / 0.4);
  background:
    radial-gradient(circle at 50% 0%, rgb(217 180 80 / 0.14), transparent 70%),
    #fffdf8;
}

.pv-certificate::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: 1px solid rgb(180 140 60 / 0.25);
  border-radius: calc(var(--radius-md) - 2px);
  pointer-events: none;
}

.pv-certificate-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background: #fdf3d8;
  color: #b45309;
  margin-bottom: var(--space-2);
}

.pv-certificate-icon svg { width: 20px; height: 20px; }

.pv-certificate-title {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-secondary);
}

.pv-certificate-name {
  margin-top: var(--space-1);
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-text);
}

.pv-certificate-course {
  margin-top: 2px;
  font-size: 0.8125rem;
  color: var(--color-text-secondary);
}

/* ---------- Timeline snippet ---------- */
.pv-timeline {
  display: flex;
  align-items: center;
}

.pv-timeline-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  position: relative;
}

.pv-timeline-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--color-border);
  border: 2px solid var(--color-bg);
  box-shadow: 0 0 0 2px var(--color-border);
  z-index: 1;
}

.pv-timeline-item.is-done .pv-timeline-dot,
.pv-timeline-item.is-active .pv-timeline-dot {
  background: var(--color-accent);
  box-shadow: 0 0 0 2px var(--color-accent);
}

.pv-timeline-item::before {
  content: '';
  position: absolute;
  top: 6px;
  left: -50%;
  width: 100%;
  height: 2px;
  background: var(--color-border);
  z-index: 0;
}

.pv-timeline-item:first-child::before {
  display: none;
}

.pv-timeline-item.is-done::before {
  background: var(--color-accent);
}

.pv-timeline-label {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-text-secondary);
  text-align: center;
}

.pv-timeline-item.is-done .pv-timeline-label,
.pv-timeline-item.is-active .pv-timeline-label {
  color: var(--color-text);
}

.pv-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.pv-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.pv-mini-bars {
  display: flex;
  align-items: flex-end;
  align-self: stretch;
  gap: 5px;
  height: 44px;
}

.pv-mini-bars > span {
  flex: 1;
  border-radius: 3px;
  background: var(--color-accent);
  opacity: 0.85;
}

/* ---------- KPI tile wall (Dashboard) ---------- */
.pv-tile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 100%;
}

.pv-tile {
  padding: var(--space-5) var(--space-4);
  border-right: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.pv-tile:nth-child(3n) {
  border-right: none;
}

.pv-tile:nth-child(n+4) {
  border-bottom: none;
}

/* A full-width strip beneath the tile grid — extra density so the
 * dashboard reads as a wide, data-dense enterprise widget wall rather
 * than a small stat card. */
.pv-tile-footer {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-border);
}

.pv-tile-label {
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.pv-tile-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-right: 5px;
  vertical-align: middle;
}

.pv-tile-value {
  margin-top: var(--space-1);
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

/* ---------- Stage stepper (Actions, Documents) ---------- */
.pv-stepper {
  display: flex;
  align-items: flex-start;
  padding-inline: var(--space-2);
}

.pv-stepper-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
}

.pv-stepper-step::before {
  content: '';
  position: absolute;
  top: 21px;
  left: -50%;
  width: 100%;
  height: 2px;
  background: var(--color-border);
  z-index: 0;
}

.pv-stepper-step:first-child::before {
  display: none;
}

.pv-stepper-step.is-done::before {
  background: #86efac;
}

.pv-stepper-icon {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-text-secondary);
  border: 2px solid var(--color-border);
}

.pv-stepper-icon svg {
  width: 20px;
  height: 20px;
}

.pv-stepper-step.is-done .pv-stepper-icon {
  background: var(--color-success-bg);
  color: #15803d;
  border-color: #86efac;
  box-shadow: 0 0 0 4px var(--color-success-bg);
}

.pv-stepper-step.is-active .pv-stepper-icon {
  background: var(--color-accent);
  color: #fff;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px var(--color-accent-bg);
}

.pv-stepper-label {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--color-text-secondary);
  text-align: center;
}

.pv-stepper-step.is-done .pv-stepper-label,
.pv-stepper-step.is-active .pv-stepper-label {
  color: var(--color-text);
}

/* Accent wash behind a stepper to raise its visual weight within a card
 * (used for Documents, where the approval workflow should read as the
 * primary content rather than a footnote under the title). */
.pv-stepper-band {
  background: var(--color-bg-secondary);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-3);
}

/* ---------- Calendar grid (Compliance Calendar) ---------- */
.pv-calendar {
  width: 100%;
}

.pv-calendar-head {
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: var(--space-3);
}

.pv-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.pv-calendar-dow {
  font-size: 0.625rem;
  font-weight: 700;
  color: var(--color-text-secondary);
  text-align: center;
  text-transform: uppercase;
  padding-bottom: 2px;
}

.pv-calendar-cell {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text);
  border-radius: var(--radius-sm);
}

.pv-calendar-cell.is-today {
  background: var(--color-accent);
  color: #fff;
}

.pv-calendar-cell.has-event::after {
  content: '';
  position: absolute;
  bottom: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-text-secondary);
}

.pv-calendar-cell.tone-accent::after { background: var(--color-accent); }
.pv-calendar-cell.tone-warning::after { background: #d97706; }
.pv-calendar-cell.tone-success::after { background: var(--color-success); }
.pv-calendar-cell.is-today.has-event::after { background: #fff; }

.pv-calendar-legend {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.pv-calendar-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}

.pv-calendar-legend-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* ---------- ID card + QR motif (Assets) ---------- */
.pv-idcard {
  width: 232px;
  text-align: center;
}

.pv-idcard-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px dashed var(--color-border);
}

.pv-qr {
  display: inline-grid;
  grid-template-columns: repeat(11, 6px);
  grid-auto-rows: 6px;
  gap: 1.5px;
  padding: var(--space-5);
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.pv-qr span {
  width: 6px;
  height: 6px;
  border-radius: 1.5px;
}

.pv-qr span.on {
  background: #0f172a;
}

.pv-qr span.off {
  background: transparent;
}

/* ---------- Combo chart (Reporting) ---------- */
.pv-combo-chart {
  display: block;
  overflow: visible;
}

/* ---------- Feature chapter divider ---------- */
/* Understated category label used to break the features page into
 * chapters (Operations / Compliance / Workforce / Assets) — whitespace
 * and a hairline rather than a heavy section block. */
.pv-chapter {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.pv-chapter-label {
  flex-shrink: 0;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-secondary);
}

.pv-chapter-rule {
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

/* ---------------------------------------------------------------------------
   App/browser frame for real product screenshots (pv_screenshot()).
   A quiet chrome bar + rounded corners + soft shadow so a cropped screen
   reads as a live application, not a floating image.
---------------------------------------------------------------------------- */
.app-frame {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  background: var(--color-bg);
}
.app-frame-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 11px 15px;
  background: var(--color-bg-secondary);
  border-bottom: 1px solid var(--color-border);
}
.app-frame-bar span {
  width: 11px;
  height: 11px;
  border-radius: var(--radius-full);
  background: #cfd6e0;
  display: block;
}
.app-frame img { display: block; width: 100%; height: auto; }

/* Capability shorthand chips (outcome sections) — labels, not cards. */
.cap-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--space-6); }
.cap-chip {
  font-size: 0.8rem; font-weight: 600; color: var(--color-text-secondary);
  background: var(--color-bg-secondary); border-radius: var(--radius-full); padding: 6px 14px;
}

/* Capability matrix entries that have a page of their own are links; the ones
   without stay plain text, so the list still reads as a complete inventory. */
.cap-col ul a { color: inherit; text-decoration: none; }
.cap-col ul a:hover, .cap-col ul a:focus-visible { color: var(--color-accent); text-decoration: underline; }

/* Industry card titles link through to the industry page where one exists. */
.card h3 a { color: inherit; text-decoration: none; }
.card h3 a:hover, .card h3 a:focus-visible { color: var(--color-accent); }

/* A chip that names a real module is a link to it. Styled to look identical to
   a plain chip until hover, so the section still reads as a set of labels. */
a.cap-chip { text-decoration: none; transition: color var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out); }
a.cap-chip:hover, a.cap-chip:focus-visible { color: var(--color-accent); background: var(--color-accent-bg); }

.flow-title a { color: inherit; text-decoration: none; }
.flow-title a:hover, .flow-title a:focus-visible { color: var(--color-accent); }

/* "The problem" — scattered tools resolving into one platform. */
.problem-flow { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; }
.problem-flow .old-chip { font-size: 0.9rem; color: var(--color-text-secondary); text-decoration: line-through; opacity: 0.65; padding: 6px 10px; }
.problem-flow .flow-arrow { color: var(--color-text-secondary); }
.problem-flow .solved { font-size: 0.9rem; font-weight: 700; color: #fff; background: var(--color-accent); border-radius: var(--radius-full); padding: 8px 18px; }

/* Compact "explore all capabilities" matrix (Features page footer) — labels, no cards, no checks. */
.cap-matrix { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-10); }
@media (max-width: 860px) { .cap-matrix { grid-template-columns: 1fr; gap: var(--space-8); } }
.cap-col h3 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-accent); margin: 0 0 var(--space-4); }
.cap-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.cap-col li { font-weight: 600; color: var(--color-text); }

/* ===========================================================================
   ProductPreview — a cropped, gently-animated product viewport.
   Shows the EXPERIENCE, not the whole interface: the real screenshot is larger
   than the visible frame and positioned to expose only the relevant region
   (sidebar/nav cropped out), with a subconscious pan/zoom loop, gradient edge
   masks that dissolve secondary UI into the page, and an optional floating
   cross-module card. All motion is disabled under prefers-reduced-motion.
=========================================================================== */
.product-preview { position: relative; }
.pp-frame {
  border-radius: 15px; overflow: hidden; border: 1px solid var(--color-border);
  box-shadow: 0 34px 64px -34px rgba(15,23,42,.42), 0 12px 26px -14px rgba(15,23,42,.14);
  background: #fff;
}
.pp-bar { display: flex; align-items: center; gap: 7px; height: 36px; padding: 0 15px; background: var(--color-bg-secondary); border-bottom: 1px solid var(--color-border); }
.pp-bar i { width: 11px; height: 11px; border-radius: 50%; background: #cfd6e0; display: block; }
.pp-stage { position: relative; aspect-ratio: var(--pp-ratio, 4 / 3); overflow: hidden; background: #eef1f6; }
.pp-shot {
  position: absolute; width: var(--pp-w, 165%); height: auto;
  left: var(--pp-l, -27%); top: var(--pp-t, -16%);
  transform-origin: 60% 30%; will-change: transform; backface-visibility: hidden;
  animation: pp-drift var(--pp-dur, 13s) ease-in-out infinite alternate;
}
@keyframes pp-drift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.045) translate3d(-1.4%, -2.8%, 0); }
}
/* Edge masks — dissolve secondary interface into the section background. */
.pp-mask {
  position: absolute; inset: 0; pointer-events: none;
  /* Spotlight, not a haze: the central ~60% stays fully clear; only the outer
     edges and lower portion dissolve, and each fade reaches solid ONLY at the
     very edge so the falloff is gradual rather than a flat white overlay. */
  /* Per-side fade starts are variables so each section tunes its own falloff:
     a KPI grid fades all four edges; a wide table keeps left/right sharp and
     fades top/bottom; a card layout fades toward its whitespace. */
  background:
    linear-gradient(to bottom, transparent var(--pp-mb, 68%), var(--pp-fade, #f8fafc) 100%),
    linear-gradient(to top,    transparent var(--pp-mt, 93%), var(--pp-fade, #f8fafc) 100%),
    linear-gradient(to left,   transparent var(--pp-ml, 77%), var(--pp-fade, #f8fafc) 100%),
    linear-gradient(to right,  transparent var(--pp-mr, 79%), var(--pp-fade, #f8fafc) 100%);
}
/* Floating cross-module card — real EHSTEC card styling, isolated. */
.pp-float {
  position: absolute; left: 6%; bottom: 8%; display: flex; align-items: center; gap: 10px;
  background: #fff; border: 1px solid var(--color-border); border-radius: 11px; padding: 9px 12px;
  box-shadow: 0 16px 34px -16px rgba(15,23,42,.28); max-width: 78%;
  animation: pp-bob 6s ease-in-out infinite alternate;
}
/* Placement variants — drop the card into the frame's quietest region. */
.pp-float--tr { left: auto; right: 4%; bottom: auto; top: 48%; max-width: 44%; }
.pp-float--br { left: auto; right: 4%; top: auto; bottom: 8%; max-width: 54%; }
@keyframes pp-bob { from { transform: translateY(0); } to { transform: translateY(-6px); } }
.pp-float-icon { width: 28px; height: 28px; border-radius: 8px; flex: none; display: flex; align-items: center; justify-content: center; }
.pp-float-icon svg { width: 15px; height: 15px; }
.pp-float-icon--warning { background: #fef3c7; color: #b45309; }
.pp-float-icon--danger  { background: #fee2e2; color: #dc2626; }
.pp-float-icon--brand   { background: var(--color-accent-bg); color: var(--color-accent); }
.pp-float b { display: block; font-size: .78rem; color: var(--color-text); line-height: 1.25; }
.pp-float small { display: block; font-size: .69rem; color: var(--color-text-secondary); margin-top: 2px; }
.pp-float-tag { margin-left: auto; font-size: .64rem; font-weight: 700; color: #b45309; background: #fef3c7; border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
/* Entrance: reveal supplies opacity+translateY; add a gentle scale settle. */
.reveal .product-preview { transform: scale(.985); transition: transform var(--duration-slow) var(--ease-out); }
.reveal.is-visible .product-preview { transform: scale(1); }
@media (prefers-reduced-motion: reduce) {
  .pp-shot, .pp-float { animation: none; }
  .reveal .product-preview { transform: none; }
}
/* On phones the floating overlay would dominate the small frame and wrap into a
   wall of text — drop it and let the cropped viewport carry the story. */
@media (max-width: 639px) {
  .pp-float { display: none; }
}

/* ===========================================================================
   Mega-menu navigation (EHSTEC 2.0 IA)
   Desktop: Product/Solutions/Resources open dropdown panels on hover/focus/click.
   Mobile: the same groups become tap-to-expand accordions in the mobile menu.
=========================================================================== */
.nav-item { position: relative; display: flex; align-items: center; }
.nav-trigger {
  background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: 0.9375rem; font-weight: 500; color: var(--color-text-secondary);
  display: inline-flex; align-items: center; padding: 0;
  transition: color var(--duration-fast) var(--ease-out);
}
.nav-trigger:hover, .nav-item.is-open .nav-trigger { color: var(--color-text); }
/* CSS caret — no icon dependency */
.nav-caret {
  width: 0; height: 0; margin-left: 6px; display: inline-block;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor; opacity: .55;
  transition: transform .2s var(--ease-out), opacity .2s var(--ease-out);
}
.nav-item:hover .nav-caret, .nav-item:focus-within .nav-caret,
.nav-item.is-open .nav-caret { transform: rotate(180deg); opacity: 1; }

.mega {
  position: absolute; top: 100%; left: 0; margin-top: 14px;
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px -24px rgba(15,23,42,.30), 0 8px 20px -12px rgba(15,23,42,.12);
  padding: var(--space-4); z-index: 60;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(6px);
  transition: opacity .18s var(--ease-out), transform .18s var(--ease-out), visibility .18s;
}
/* Invisible hover-bridge so the pointer can travel from trigger to panel. */
.mega::before { content: ""; position: absolute; top: -14px; left: 0; right: 0; height: 14px; }
.nav-item:hover .mega, .nav-item:focus-within .mega, .nav-item.is-open .mega {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0);
}
.mega-wide { width: min(600px, 92vw); }
.mega-inner { display: grid; gap: 2px; }
.mega-2col { grid-template-columns: 1fr 1fr; gap: 2px 10px; }
.mega-groups { grid-template-columns: 1fr 1fr; gap: 12px 28px; align-items: start; }
.mega-link { display: block; padding: 9px 12px; border-radius: 10px; transition: background var(--duration-fast) var(--ease-out); }
.mega-link:hover { background: var(--color-bg-secondary); }
.mega-link-title { display: block; font-size: .92rem; font-weight: 600; color: var(--color-text); }
/* "By workflow" group at the foot of the Product mega — capability pages that
   cut across modules, kept visually distinct from the module grid above. */
.mega-cap {
  border-top: 1px solid var(--color-border);
  padding: var(--space-4) var(--space-5) var(--space-2);
}

.mega-cap .mega-heading {
  margin: 0 0 var(--space-2);
}

.mega-cap-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.mega-cap-links a {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text-secondary);
  text-decoration: none;
}

.mega-cap-links a:hover,
.mega-cap-links a:focus-visible {
  color: var(--color-accent);
}

/* The features hub lists a fourth column of workflow pages. /pricing keeps the
   three-column module layout, so this is opt-in rather than global. */
@media (min-width: 1100px) {
  .cap-matrix-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Hub link at the head of a mega-menu — the parent page for everything in the
   panel below it. Styled as a quiet banner rather than a card so it reads as a
   heading with a destination, not as another sibling module. */
.mega-hub {
  display: block;
  padding: var(--space-4) var(--space-5);
  margin: 0 0 var(--space-2);
  border-bottom: 1px solid var(--color-border);
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-out);
}

.mega-hub:hover,
.mega-hub:focus-visible {
  background: var(--color-bg-secondary);
}

.mega-hub .mega-link-title {
  color: var(--color-accent);
}

.mega-link-desc { display: block; font-size: .78rem; color: var(--color-text-secondary); margin-top: 1px; line-height: 1.35; }
.mega-link-sm { padding: 7px 12px; }
.mega-heading { font-size: .7rem; text-transform: uppercase; letter-spacing: .09em; color: var(--color-text-secondary); font-weight: 700; padding: 4px 12px; margin: 0 0 2px; }

/* Mobile accordion (inside .mobile-menu, < 900px) */
.m-acc { border-bottom: 1px solid var(--color-border); }
.m-acc-trigger {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  background: none; border: none; cursor: pointer; font-family: inherit;
  padding: var(--space-3) 0; font-size: 1rem; font-weight: 600; color: var(--color-text);
}
.m-acc-trigger .nav-caret { opacity: .6; }
.m-acc.is-open .nav-caret { transform: rotate(180deg); }
.m-acc-panel { display: none; padding: 0 0 var(--space-2) var(--space-4); }
.m-acc.is-open .m-acc-panel { display: block; }
.m-acc-panel a { display: block; padding: var(--space-2) 0; color: var(--color-text-secondary); border-bottom: none; font-weight: 500; }
.m-acc-heading { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--color-text-secondary); font-weight: 700; margin: var(--space-2) 0 2px; }
.m-simple { display: block; padding: var(--space-3) 0; font-weight: 500; color: var(--color-text-secondary); border-bottom: 1px solid var(--color-border); }
.m-simple:last-child { border-bottom: none; }

/* ===========================================================================
   Connected-workflow visual — homepage "Everything connects" section.
   Three vertical chains (Inspections / Workforce / Equipment), each running
   from a trigger to a green "resolved/ready" outcome — the platform's
   differentiator made visible.
=========================================================================== */
.connect-flows { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
@media (max-width: 860px) { .connect-flows { grid-template-columns: 1fr; max-width: 440px; margin-inline: auto; } }
.flow-col {
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: 24px 20px;
}
.flow-title { font-size: .95rem; font-weight: 700; text-align: center; color: var(--color-text); margin: 0 0 18px; }
.flow-chain { display: flex; flex-direction: column; align-items: stretch; }
.flow-step {
  text-align: center; background: var(--color-bg-secondary); border: 1px solid var(--color-border);
  border-radius: 10px; padding: 12px 14px; font-size: .9rem; font-weight: 600; color: var(--color-text);
}
.flow-connector { width: 2px; height: 18px; background: var(--color-border); margin: 6px auto; position: relative; }
.flow-connector::after {
  content: ""; position: absolute; bottom: -2px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid var(--color-border);
}
/* Outcome step — resolved / ready (readable dark green on the success tint). */
.flow-step.is-end { background: var(--color-success-bg); border-color: #86efac; color: #15803d; }

/* ===========================================================================
   EHSTEC AI page
=========================================================================== */
/* AI badge (zap + label), accent-tinted */
.ai-badge { display: inline-flex; align-items: center; gap: 7px; font-size: .78rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-accent);
  background: var(--color-accent-bg); padding: 6px 12px; border-radius: 999px; }
.ai-badge svg { width: 15px; height: 15px; }
.ai-badge-lg { font-size: .82rem; padding: 8px 15px; }

/* Dark hero */
.ai-hero { padding-block: clamp(56px, 8vw, 104px); overflow: hidden; }
.ai-hero-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
@media (max-width: 880px) { .ai-hero-grid { grid-template-columns: 1fr; } }
.ai-hero h1 { font-size: clamp(2.1rem, 4.4vw, 3.2rem); font-weight: 800; letter-spacing: -.02em; }
.ai-hero .text-lead { color: var(--color-dark-text-secondary); max-width: 48ch; }
.ai-hero-cta { display: flex; flex-wrap: wrap; gap: 12px; }
.ai-hero-trust { display: inline-flex; align-items: center; gap: 8px; font-size: .9rem; color: var(--color-dark-text-secondary); }
.ai-hero-trust svg { width: 16px; height: 16px; color: var(--color-success); }
.btn-outline-light { border: 1px solid rgba(248,250,252,.28); color: var(--color-dark-text); background: transparent; }
.btn-outline-light:hover { background: rgba(248,250,252,.08); border-color: rgba(248,250,252,.5); }
.ai-badge-onDark { color: #a9c1ff; background: rgba(99,140,255,.14); }

/* AI Summary card (composed) */
.ai-card { padding: 22px 22px 18px; max-width: 460px; margin-inline: auto; }
.ai-card-title { font-size: 1.05rem; font-weight: 700; color: var(--color-text); margin: 12px 0 4px; }
.ai-insights { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.ai-insights li { display: flex; align-items: flex-start; gap: 11px; font-size: .95rem; color: var(--color-text); line-height: 1.4; }
.ai-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; margin-top: 7px;
  background: var(--color-accent); box-shadow: 0 0 0 4px var(--color-accent-bg); }
.ai-card-foot { display: flex; align-items: center; gap: 8px; margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--color-border); font-size: .8rem; color: var(--color-text-secondary); }
.ai-card-foot svg { width: 15px; height: 15px; color: var(--color-success); flex: none; }

/* Forms AI prompt → draft (composed) */
.ai-prompt-wrap { max-width: 460px; margin-inline: auto; }
.ai-prompt { display: flex; align-items: center; gap: 10px; background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: 12px; padding: 8px 8px 8px 16px; box-shadow: var(--shadow-md, 0 8px 20px -12px rgba(15,23,42,.15)); }
.ai-prompt-text { flex: 1; font-size: .95rem; color: var(--color-text); }
.ai-prompt-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--color-accent); color: #fff;
  font-size: .85rem; font-weight: 600; padding: 8px 14px; border-radius: 9px; white-space: nowrap; }
.ai-prompt-btn svg { width: 15px; height: 15px; }
.ai-prompt-arrow { width: 2px; height: 26px; background: var(--color-border); margin: 6px auto; position: relative; }
.ai-prompt-arrow::after { content: ""; position: absolute; bottom: -2px; left: 50%; transform: translateX(-50%);
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--color-border); }
.ai-draft { padding: 18px 20px; }
.ai-draft-title { font-size: 1rem; font-weight: 700; color: var(--color-text); margin-bottom: 10px; }
.ai-draft-section { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--color-text-secondary); margin: 14px 0 8px; }
.ai-draft-q { display: flex; align-items: center; gap: 10px; font-size: .9rem; color: var(--color-text); padding: 5px 0; }
.ai-q-dot { flex: none; width: 14px; height: 14px; border-radius: 4px; border: 1.5px solid var(--color-border); }

/* Benefit + trust card grids */
.ai-benefits { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
@media (max-width: 900px) { .ai-benefits { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .ai-benefits { grid-template-columns: 1fr; } }
.ai-benefit { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 22px 20px; }
.ai-benefit-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: 11px; background: var(--color-accent-bg); color: var(--color-accent); margin-bottom: 14px; }
.ai-benefit-icon svg { width: 20px; height: 20px; }
.ai-benefit h3 { font-size: 1rem; font-weight: 700; margin-bottom: 6px; color: var(--color-text); }
.ai-benefit p { font-size: .9rem; color: var(--color-text-secondary); margin: 0; line-height: 1.5; }

.ai-trust { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 760px) { .ai-trust { grid-template-columns: 1fr; } }
.ai-trust-card { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 24px 22px; }
.ai-trust-icon { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px;
  border-radius: 12px; background: var(--color-success-bg); color: var(--color-success); margin-bottom: 14px; }
.ai-trust-icon svg { width: 21px; height: 21px; }
.ai-trust-card h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: 7px; color: var(--color-text); }
.ai-trust-card p { font-size: .92rem; color: var(--color-text-secondary); margin: 0; line-height: 1.55; }

/* ===========================================================================
   product_flow — animated lifecycle visual for product pages
=========================================================================== */
.flow-card {
  background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  box-shadow: 0 30px 60px -30px rgba(15,23,42,.28), 0 10px 24px -14px rgba(15,23,42,.12);
  padding: 24px; max-width: 440px; margin-inline: auto;
}
.flow-card-head { display: flex; align-items: center; gap: 12px; padding-bottom: 18px; border-bottom: 1px solid var(--color-border); }
.flow-entity-icon { width: 44px; height: 44px; border-radius: 12px; background: var(--color-accent-bg); color: var(--color-accent);
  display: flex; align-items: center; justify-content: center; flex: none; }
.flow-entity-icon svg { width: 22px; height: 22px; }
.flow-entity-text b { display: block; font-size: 1rem; color: var(--color-text); }
.flow-entity-text small { display: block; font-size: .82rem; color: var(--color-text-secondary); }
.flow-status { padding: 24px 0; min-height: 128px; text-align: center; }
.flow-pill { display: inline-flex; align-items: center; gap: 9px; font-size: .95rem; font-weight: 700;
  padding: 9px 17px; border-radius: 999px; transition: background .45s ease, color .45s ease; }
.flow-pill-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.flow-pill.tone-danger  { background: var(--color-danger-bg);  color: #b91c1c; }
.flow-pill.tone-warning { background: #fbf0df;                 color: #b45309; }
.flow-pill.tone-info    { background: var(--color-accent-bg);  color: var(--color-accent); }
.flow-pill.tone-success { background: var(--color-success-bg); color: #15803d; }
.flow-caption { margin: 14px auto 0; max-width: 36ch; font-size: .92rem; color: var(--color-text-secondary); }
.flow-rail { display: flex; align-items: center; justify-content: space-between; position: relative; padding: 8px 4px 0; }
.flow-rail::before { content: ""; position: absolute; top: 21px; left: 8%; right: 8%; height: 2px; background: var(--color-border); z-index: 0; }
.flow-node { position: relative; z-index: 1; width: 26px; height: 26px; border-radius: 50%; background: var(--color-bg-secondary);
  border: 2px solid var(--color-border); color: var(--color-text-secondary); font-size: .74rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; transition: all .3s ease; }
.flow-node.is-active { background: var(--color-accent); border-color: var(--color-accent); color: #fff; transform: scale(1.12); }
.flow-node.is-done { background: var(--color-success); border-color: var(--color-success); color: #fff; }

/* ===========================================================================
   Product-page skeleton — pillars strip + related-module cross-links
=========================================================================== */
.prod-pillars { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
@media (max-width: 900px) { .prod-pillars { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .prod-pillars { grid-template-columns: 1fr; } }
.prod-pillar { display: flex; align-items: flex-start; gap: 12px; background: var(--color-bg);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 18px; }
.prod-pillar-icon { flex: none; width: 38px; height: 38px; border-radius: 10px; background: var(--color-accent-bg);
  color: var(--color-accent); display: flex; align-items: center; justify-content: center; }
.prod-pillar-icon svg { width: 19px; height: 19px; }
.prod-pillar-label { font-size: .95rem; font-weight: 700; color: var(--color-text); }
.prod-pillar-desc { font-size: .82rem; color: var(--color-text-secondary); margin-top: 2px; line-height: 1.4; }

.prod-related { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 760px) { .prod-related { grid-template-columns: 1fr; } }
.prod-related-card { display: block; background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: 20px; transition: border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out); }
.prod-related-card:hover { border-color: var(--color-accent); transform: translateY(-2px); }
.prod-related-label { display: flex; align-items: center; gap: 8px; font-size: 1rem; font-weight: 700; color: var(--color-text); }
.prod-related-label svg { width: 16px; height: 16px; color: var(--color-accent); }
.prod-related-desc { font-size: .88rem; color: var(--color-text-secondary); margin-top: 6px; line-height: 1.5; }

/* Stacked composed cards (e.g. asset-readiness list on a product page) */
.stack-visual { display: flex; flex-direction: column; gap: 12px; max-width: 400px; margin-inline: auto; }

/* ===========================================================================
   Distinct product-page hero visuals
=========================================================================== */
.hv-card { max-width: 430px; margin-inline: auto; padding: 22px; }
.hv-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hv-kicker { font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--color-text-secondary); }
.hv-kicker.mb { display: block; margin-bottom: 14px; }
.hv-foot { display: flex; align-items: center; gap: 8px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--color-border); font-size: .8rem; color: var(--color-text-secondary); }
.hv-foot svg { width: 15px; height: 15px; color: var(--color-success); flex: none; }
.ac-row-txt b { display: block; font-size: .92rem; color: var(--color-text); line-height: 1.2; }
.ac-row-txt small { display: block; font-size: .78rem; color: var(--color-text-secondary); margin-top: 1px; }

/* Corrective Actions — action record */
.ac-title { font-size: 1.1rem; font-weight: 700; color: var(--color-text); margin: 14px 0 4px; }
.ac-meta { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.ac-row { display: flex; align-items: center; gap: 11px; }
.ac-ico { width: 34px; height: 34px; border-radius: 9px; background: var(--color-accent-bg); color: var(--color-accent); display: flex; align-items: center; justify-content: center; flex: none; }
.ac-ico svg { width: 17px; height: 17px; }

/* Employees — readiness profile */
.rp-head { display: flex; align-items: center; gap: 11px; padding-bottom: 16px; border-bottom: 1px solid var(--color-border); }
.rp-status { margin: 16px 0; }
.rp-reqs { display: flex; flex-direction: column; gap: 10px; }
.rp-req { display: flex; align-items: center; gap: 10px; font-size: .92rem; color: var(--color-text); }
.rp-req > svg { width: 17px; height: 17px; color: var(--color-success); flex: none; }
.rp-req-name { flex: 1; }
.rp-req-ok { font-size: .75rem; font-weight: 700; color: #15803d; background: var(--color-success-bg); padding: 2px 9px; border-radius: 999px; }

/* Contractors — compliance board */
.cb-row { display: flex; align-items: center; gap: 11px; padding: 11px 0; border-bottom: 1px solid var(--color-border); }
.cb-row:last-child { border-bottom: none; }
.cb-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.cb-success { background: var(--color-success); } .cb-warning { background: #d97706; } .cb-danger { background: var(--color-danger); }
.cb-name { flex: 1; font-size: .95rem; font-weight: 600; color: var(--color-text); }
.cb-status { font-size: .82rem; color: var(--color-text-secondary); }
.cb-success-txt { color: #15803d; } .cb-warning-txt { color: #b45309; } .cb-danger-txt { color: #b91c1c; }

/* Documents — acknowledgement */
.da-head { display: flex; align-items: center; gap: 11px; }
.da-ico { width: 38px; height: 38px; border-radius: 10px; background: var(--color-accent-bg); color: var(--color-accent); display: flex; align-items: center; justify-content: center; flex: none; }
.da-ico svg { width: 19px; height: 19px; }
.da-ver { margin-left: auto; font-size: .72rem; font-weight: 700; color: #15803d; background: var(--color-success-bg); padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.da-ack { margin: 20px 0 4px; }
.da-ack-top { display: flex; justify-content: space-between; font-size: .85rem; color: var(--color-text-secondary); margin-bottom: 8px; }
.da-ack-top b { color: var(--color-text); }

/* Reporting — KPI dashboard */
.db-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.db-chart { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--color-border); }
.db-chart-label { font-size: .78rem; font-weight: 600; color: var(--color-text-secondary); margin-bottom: 10px; }

/* Flow chain as a solution-page hero: cap width + center so it matches the
   other hero cards instead of stretching full-container. (No effect inside the
   homepage .connect-flows grid, whose tracks are already narrower.) */
.flow-col { max-width: 460px; margin-inline: auto; }

/* ===========================================================================
   Resource library grid (courses, templates)
=========================================================================== */
.res-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 860px) { .res-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .res-grid { grid-template-columns: 1fr; } }
.res-card { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 22px; transition: border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out); }
.res-card:hover { border-color: var(--color-accent); transform: translateY(-2px); }
.res-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 11px; background: var(--color-accent-bg); color: var(--color-accent); margin-bottom: 14px; }
.res-icon svg { width: 20px; height: 20px; }
.res-cat { display: inline-block; font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--color-text-secondary); background: var(--color-bg-secondary); border-radius: 999px; padding: 3px 10px; margin-left: 8px; }
.res-title { font-size: 1.02rem; font-weight: 700; color: var(--color-text); margin: 12px 0 6px; }
.res-desc { font-size: .9rem; color: var(--color-text-secondary); margin: 0; line-height: 1.5; }
.res-groups > * + * { margin-top: 44px; }
.res-group-head { font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--color-accent); margin-bottom: 18px; }

/* ===========================================================================
   Security & Trust page
=========================================================================== */
/* Scan band — the strongest implemented controls, at a glance */
.sec-glance { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 28px;
  margin: 32px auto 0; max-width: 800px; padding: 18px 26px;
  background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 14px; }
.sec-glance span { display: inline-flex; align-items: center; gap: 8px; font-size: .92rem; font-weight: 600; color: var(--color-text); }
.sec-glance svg { width: 17px; height: 17px; color: var(--color-success); flex: none; }
/* Responsible AI: compact single row, subordinate to the fundamentals above */
.sec-ai { display: flex; align-items: center; gap: 18px; margin-top: 18px;
  background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 20px 24px; }
.sec-ai .ai-trust-icon { margin-bottom: 0; flex: none; }
.sec-ai-body { flex: 1; }
.sec-ai-body h3 { font-size: 1.02rem; font-weight: 700; margin-bottom: 4px; color: var(--color-text); }
.sec-ai-body p { font-size: .9rem; color: var(--color-text-secondary); margin: 0; line-height: 1.5; }
.sec-ai-link { flex: none; display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: .9rem; color: var(--color-accent); white-space: nowrap; }
.sec-ai-link svg { width: 15px; height: 15px; }
@media (max-width: 680px) { .sec-ai { flex-direction: column; align-items: flex-start; } }

/* ---------- Guides (knowledge centre) ----------
   A reading layout, not a product layout: one narrow column, generous leading,
   and headings that are quieter than a marketing H2 because the reader is here
   to read rather than to scan. */
.guide-head { padding-block: var(--space-10) var(--space-8); }
.guide-byline {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  margin-top: var(--space-6); font-size: 0.875rem; color: var(--color-text-secondary);
}
.guide-body { padding-bottom: var(--space-16); }
.guide-body > h2 {
  font-size: 1.5rem; margin-top: var(--space-12); margin-bottom: var(--space-4);
  scroll-margin-top: var(--space-8);
}
.guide-body > h3 { font-size: 1.125rem; margin-top: var(--space-8); margin-bottom: var(--space-3); }
.guide-body > p { margin-bottom: var(--space-4); line-height: 1.75; }
.guide-body > ul, .guide-body > ol { margin-bottom: var(--space-6); padding-left: var(--space-6); line-height: 1.7; }
.guide-body > ul li, .guide-body > ol li { margin-bottom: var(--space-2); }
.guide-body a { color: var(--color-accent); }

.guide-toc {
  background: var(--color-bg-secondary); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-6); margin-bottom: var(--space-10);
}
.guide-toc-head {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-text-secondary); margin: 0 0 var(--space-3); font-weight: 700;
}
.guide-toc ol { margin: 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.guide-toc a { color: var(--color-text); text-decoration: none; }
.guide-toc a:hover, .guide-toc a:focus-visible { color: var(--color-accent); text-decoration: underline; }

/* Where teaching stops and the product starts — deliberately obvious. */
.guide-callout {
  border-left: 3px solid var(--color-accent); background: var(--color-accent-bg);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: var(--space-5) var(--space-6); margin: var(--space-8) 0;
}
.guide-callout-title { font-weight: 700; margin: 0 0 var(--space-2); }
.guide-callout p { margin: 0 0 var(--space-3); color: var(--color-text-secondary); }
.guide-callout a { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; text-decoration: none; }
.guide-callout a:hover { text-decoration: underline; }
.guide-callout svg { width: 16px; height: 16px; }

.guide-refs { margin-top: var(--space-12); padding-top: var(--space-6); border-top: 1px solid var(--color-border); }
.guide-refs ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.guide-refs a { color: var(--color-accent); }

/* Comparison tables inside guides scroll rather than breaking the column. */
.guide-table { overflow-x: auto; margin: var(--space-6) 0; border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.guide-table table { border-collapse: collapse; width: 100%; font-size: 0.9rem; min-width: 560px; }
.guide-table th, .guide-table td { text-align: left; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border); vertical-align: top; }
.guide-table th { background: var(--color-bg-secondary); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-secondary); }
.guide-table tbody tr:last-child td { border-bottom: 0; }

.guide-formula {
  background: var(--color-bg-secondary); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); padding: var(--space-5) var(--space-6); margin: var(--space-6) 0;
  font-size: 1rem; line-height: 1.7;
}
.guide-formula strong { display: block; margin-bottom: var(--space-2); }

/* Resource hub cards. */
.res-cluster { margin-bottom: var(--space-12); }
.res-cluster-head { display: flex; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-5); }
.res-cluster-head h2 { font-size: 1.25rem; margin: 0; }
.guide-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--space-5); }
.guide-card {
  display: flex; flex-direction: column; gap: var(--space-2);
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-6); text-decoration: none;
  transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.guide-card:hover, .guide-card:focus-visible { border-color: var(--color-accent); box-shadow: var(--shadow-md); }
.guide-card h3 { font-size: 1.05rem; margin: 0; color: var(--color-text); }
.guide-card p { margin: 0; font-size: 0.9rem; color: var(--color-text-secondary); line-height: 1.6; }
.guide-card .guide-card-meta { font-size: 0.78rem; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }

/* ===== TRIR / DART calculator (/resources/trir-dart-calculator) ===== */
/* Reuses .form-field / .form-label / .form-input / .form-error so the calculator
   inherits the site's existing input styling and focus treatment rather than
   introducing a second form language. Only the calculator-specific layout,
   results block and privacy note are defined here. */

.calc {
  margin: var(--space-8) 0 var(--space-12);
  padding: var(--space-6);
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.calc-title { margin: 0 0 var(--space-5); font-size: 1.25rem; }
.calc-form .form-field { margin-bottom: var(--space-5); }
.calc-help {
  display: block;
  margin-top: var(--space-2);
  font-size: 0.8125rem;
  color: var(--color-text-secondary);
  line-height: 1.5;
}
/* Errors are text, never colour alone — .form-error supplies the colour and the
   message itself carries the meaning for anyone who cannot see it. */
.calc-error:empty { display: none; }
.calc-form .form-input.is-invalid { border-color: var(--color-danger); }

.calc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}
/* Comfortable touch targets on a phone; the field user checking a rate is a
   plausible reader. */
.calc-actions .btn { min-height: 44px; }

.calc-results {
  display: grid;
  gap: var(--space-5);
  margin-top: var(--space-8);
  padding: var(--space-6);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
@media (min-width: 640px) {
  .calc-results { grid-template-columns: 1fr 1fr; }
  .calc-result-note { grid-column: 1 / -1; }
}
.calc-result { display: flex; flex-direction: column; gap: var(--space-1); }
.calc-result-label {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.calc-result-value {
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.calc-result-work {
  font-size: 0.8125rem;
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.calc-result-note {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}
/* Three result figures rather than two (direct / indirect / total), so the row
   does not leave the third one orphaned on its own line. */
@media (min-width: 720px) {
  .calc-results--three { grid-template-columns: repeat(3, 1fr); }
}

/* ---- Incident cost estimator ----------------------------------------------
   The grouping IS the content. A reader has to be able to see at a glance which
   figures are things they know and which are things they are assuming, because
   the whole argument of the page is that the assumptions are yours and visible
   rather than buried in a multiplier. So the groups are drawn, not merely
   labelled, and the tag colour separates fact from assumption. */
.ice-group {
  margin: 0 0 var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
}
.ice-group:last-of-type { margin-bottom: 0; }
.ice-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  padding: 0 var(--space-2);
  margin-left: calc(var(--space-2) * -1);
  font-weight: 700;
  font-size: 1rem;
}
.ice-tag {
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
}
.ice-tag--fact {
  border-style: solid;
  color: var(--color-text);
}
/* Dashed = provisional. The one visual cue on the page that says "you chose this
   number", carried without a state colour. */
.ice-tag--assumption {
  border-style: dashed;
  border-color: var(--color-text-secondary);
  color: var(--color-text);
}
.ice-fields { margin-top: var(--space-4); }
/* Two columns once there is room: thirteen fields in a single column is a very
   long scroll, and a rate reads best beside the quantity it multiplies. */
@media (min-width: 640px) {
  .ice-fields {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 var(--space-5);
  }
}
.ice-fields .form-field { margin-bottom: var(--space-5); }
/* ---- L209 EHS Program Health Check ---------------------------------------
   Twenty-eight questions is a long page, so the work the styling has to do is
   structural: make an area feel like a unit, make an option feel like a whole
   clickable row rather than a small radio with text beside it, and make the
   result block read as a register rather than a scoreboard.

   The four band values are NOT a traffic light. "Not established" is a starting
   point, not a failure, and colouring it red would turn a self-assessment into a
   judgement — which is the thing this page spends three sections refusing to be.
   So bands are differentiated by weight and a left rule, with one accent reserved
   for Established. */
.hc { margin: var(--space-8) 0 var(--space-12); }
.hc-title { margin: 0 0 var(--space-5); font-size: 1.25rem; }

.hc-privacy {
  margin: var(--space-6) 0;
  padding: var(--space-5);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
  background: var(--color-bg-secondary);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
}
.hc-privacy p { margin: 0 0 var(--space-3); }
.hc-privacy p:last-child { margin-bottom: 0; }

.hc-area {
  margin: 0 0 var(--space-8);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
}
.hc-area-legend {
  padding: 0 var(--space-2);
  margin-left: calc(var(--space-2) * -1);
  font-weight: 700;
  font-size: 1.0625rem;
}
.hc-area-target {
  margin: var(--space-2) 0 var(--space-5);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}

.hc-q { margin: 0 0 var(--space-6); padding: 0; border: 0; }
.hc-q:last-child { margin-bottom: 0; }
.hc-q-text {
  padding: 0;
  margin: 0 0 var(--space-3);
  font-weight: 600;
  line-height: 1.5;
}
/* The whole row is the target, not just the radio: on a phone a 16px circle is a
   miss waiting to happen, and there are 112 of them on this page. */
.hc-opt {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3);
  margin-bottom: var(--space-2);
  font-size: 0.9375rem;
  line-height: 1.5;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  min-height: 44px;
}
.hc-opt:hover { border-color: var(--color-accent); }
.hc-opt input { margin-top: 0.2rem; flex: 0 0 auto; }
/* The row is a div with an explicit <label for>, rather than a wrapping label: the
   association is more robust and it matches every other form on the site. The label
   is stretched to fill the row so the whole row stays the click target — with 112
   options on this page, a 16px circle would be a miss waiting to happen. */
.hc-opt label { flex: 1 1 auto; cursor: pointer; }
.hc-opt:focus-within { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.hc-opt:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-accent-bg);
}

.hc-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin: var(--space-6) 0;
}
.hc-controls .btn { min-height: 44px; }
.hc-controls-hint, .hc-note {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}
.hc-note { margin: 0 0 var(--space-4); }

.hc-empty {
  margin: var(--space-6) 0;
  padding: var(--space-4);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
  background: var(--color-bg-secondary);
  border-radius: var(--radius-sm);
}

.hc-results {
  margin-top: var(--space-8);
  padding: var(--space-6);
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.hc-results-title { margin: 0 0 var(--space-3); font-size: 1.25rem; }
.hc-coverage {
  margin: 0 0 var(--space-6);
  font-size: 0.9375rem;
  color: var(--color-text-secondary);
}
.hc-h3 { margin: var(--space-8) 0 var(--space-3); font-size: 1.0625rem; }

.hc-bands { display: grid; gap: var(--space-3); }
.hc-band-row {
  display: grid;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-4);
  background: var(--color-bg);
  border-left: 3px solid var(--color-border);
  border-radius: var(--radius-sm);
}
@media (min-width: 720px) {
  .hc-band-row { grid-template-columns: 1fr auto; align-items: baseline; }
  .hc-band-target { grid-column: 1 / -1; }
}
.hc-band-area { font-weight: 600; }
.hc-band-value {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
/* Established is the only band that gets the accent. The other three are stages on
   the way, not states to be flagged. */
.hc-band-row:has([data-band="3"]) { border-left-color: var(--color-accent); }
.hc-band-row:has([data-band="3"]) .hc-band-value { color: var(--color-accent); font-weight: 700; }
.hc-band-row--none { opacity: 0.72; border-left-style: dashed; }
.hc-band-target {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}

.hc-focus-list { margin: 0; padding-left: var(--space-5); }
.hc-focus-item { margin-bottom: var(--space-6); }
.hc-focus-title { margin: 0 0 var(--space-2); font-size: 1rem; }
.hc-focus-band {
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--color-text-secondary);
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.hc-focus-target, .hc-focus-lead {
  margin: 0 0 var(--space-2);
  font-size: 0.9375rem;
  line-height: 1.6;
}
.hc-focus-links { margin: 0; padding-left: var(--space-5); font-size: 0.9375rem; }

.hc-action {
  margin: 0;
  padding: var(--space-5);
  font-size: 1.0625rem;
  line-height: 1.6;
  background: var(--color-bg);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
}

.hc-map { display: grid; gap: var(--space-5); }
@media (min-width: 640px) { .hc-map { grid-template-columns: 1fr 1fr; } }
.hc-map-title { margin: 0 0 var(--space-2); font-size: 0.9375rem; }
.hc-map-area ul { margin: 0; padding-left: var(--space-5); font-size: 0.9375rem; line-height: 1.7; }
.hc-map-gap {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
}

.calc-privacy {
  margin: var(--space-6) 0 0;
  padding: var(--space-4);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-text-secondary);
  background: var(--color-bg);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
}

/* ===== Printable resource artifacts (/resources/{slug}) ===================== */
/* Phase 10C. One vocabulary serves all five Wave 1 artifacts — a JHA template, a
   toolbox-talk sign-off sheet, an inspection checklist, a near-miss form and a
   corrective-action tracker — because they are the same object: a bordered block
   of labelled writing space that must survive a monochrome Letter printer.

   Deliberately NO form inputs. These artifacts are printed and filled by hand;
   an <input> on a static page implies state that nothing saves, and losing a
   half-completed safety form on refresh is worse than never offering the field.
   Blank ruled space is honest about what the page does. */

.resource-status {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2);
  margin: var(--space-5) 0 0; padding: var(--space-3) var(--space-4);
  background: var(--color-bg-secondary);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
  font-size: 0.875rem; line-height: 1.5;
}
.resource-status-key {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--color-text-secondary);
}
.resource-status-val { color: var(--color-text); }

.resource-print { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin: var(--space-8) 0 0; }
.resource-print .btn { min-height: 44px; }
.resource-print-hint { font-size: 0.8125rem; color: var(--color-text-secondary); }

/* ---- the artifact itself ---- */
.rform {
  margin: var(--space-6) 0 var(--space-10);
  padding: var(--space-6);
  background: var(--color-bg);
  border: 1px solid var(--color-text-secondary);
  border-radius: var(--radius-md);
}
.rform-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); }
.rform-title { margin: 0; font-size: 1.1rem; }
.rform-org { font-size: 0.8125rem; color: var(--color-text-secondary); }
.rform-section {
  margin-top: var(--space-6); padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.rform-section:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.rform-section-title {
  margin: 0 0 var(--space-4); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-secondary);
}
.rform-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4) var(--space-5); }
@media (min-width: 560px) { .rform-grid { grid-template-columns: 1fr 1fr; } }
.rform-field { display: flex; flex-direction: column; gap: var(--space-1); }
/* Grid rows stretch, so a field whose neighbour has a hint line would otherwise sit
   with its box higher than the one beside it. Pushing the box to the bottom of the
   stretched cell keeps every entry box on a row aligned, which is what makes a
   printed form look set rather than assembled. */
.rform-field .rform-write { margin-top: auto; }
.rform-full { grid-column: 1 / -1; }
.rform-label { font-size: 0.78rem; font-weight: 600; color: var(--color-text); }
.rform-req { color: var(--color-danger); margin-left: 2px; }
.rform-hint { font-size: 0.75rem; color: var(--color-text-secondary); line-height: 1.45; }
/* An entry BOX, not a ruled line. Two reasons: a box reads unambiguously as
   "write here" on paper, and in a PDF annotation app it is one tap target for one
   answer instead of several. Sized by --lines so a paragraph answer is one tall box
   rather than a stack. */
/* The entry box is a real <input> or <textarea>: type into it on screen and it
   prints with what you typed. Styled to look identical whichever it is, so the form
   reads as one object rather than a mix of controls. */
.rform-write {
  display: block; width: 100%;
  min-height: calc(var(--lines, 1) * 1.45rem);
  height: calc(var(--lines, 1) * 1.45rem);
  padding: 2px 6px;
  font: inherit; font-size: 0.9rem; line-height: 1.35;
  color: var(--color-text);
  border: 1px solid var(--color-text-secondary);
  border-radius: 2px;
  margin-top: var(--space-1);
  background: var(--color-bg);
  -webkit-appearance: none; appearance: none;
}
textarea.rform-write { resize: vertical; overflow: hidden; white-space: pre-wrap; word-break: break-word; }
.rform-write:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 1px; border-color: var(--color-accent); }
.rform-write::placeholder { color: var(--color-text-secondary); opacity: 0.7; }

/* Cell fields sit flush inside their table cell — the cell border IS the box. */
.rform-cell { padding: 0 !important; }
.rform-cell--tick { text-align: center; vertical-align: middle; padding: 4px !important; }
.rform-write--cell {
  border: 0; border-radius: 0; margin: 0;
  min-height: 2.4rem; height: calc(var(--lines, 1) * 1.35rem);
  font-size: 0.82rem; background: transparent;
}
.rform-write--cell:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* Tables scroll inside their own container — a five-column form must never make
   the page body scroll sideways on a phone. */
.rform-table { overflow-x: auto; margin: 0; border: 1px solid var(--color-border); border-radius: var(--radius-sm); }
.rform-table table { border-collapse: collapse; width: 100%; font-size: 0.82rem; min-width: 620px; }
.rform-table caption { caption-side: top; text-align: left; padding: var(--space-3) var(--space-4); font-size: 0.75rem; color: var(--color-text-secondary); line-height: 1.5; }
.rform-table th, .rform-table td {
  text-align: left; vertical-align: top;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
}
.rform-table thead th {
  background: var(--color-bg-secondary); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-text-secondary);
}
/* Blank rows need real height or they collapse to nothing on screen and print. */
.rform-table tbody td { height: 2.6rem; }
.rform-table tbody td.rform-tall { height: 3.4rem; }
.rform-table tbody th[scope="row"] { font-weight: 600; color: var(--color-text-secondary); font-variant-numeric: tabular-nums; }
.rform-narrow { width: 5.5rem; }
.rform-mid { width: 9rem; }

.rform-checks { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }
.rform-check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 0.82rem; }
/* A real checkbox. appearance:none so it looks the same everywhere, and the tick is
   drawn with BORDERS rather than a background image — browsers drop background
   graphics when printing, and a ticked box that prints blank is worse than no box. */
.rform-box {
  flex: 0 0 auto; position: relative;
  width: 0.95rem; height: 0.95rem; margin: 0;
  -webkit-appearance: none; appearance: none;
  border: 1px solid var(--color-text-secondary); border-radius: 2px;
  background: var(--color-bg); cursor: pointer;
}
.rform-box:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }
.rform-box:checked::after {
  content: ""; position: absolute;
  left: 0.28rem; top: 0.06rem; width: 0.26rem; height: 0.55rem;
  border: solid var(--color-text); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.rform-check { cursor: pointer; }

/* Print mirror of a textarea's value — see assets/js/site.js. Never visible on
   screen; in print it replaces the textarea, because an element wraps and grows at
   the sheet's width while a textarea is stuck at its rows count. */
.rform-printed { display: none; }

/* Inline header field ("Organization / site:"). */
.rform-org-field { display: inline-flex; align-items: baseline; gap: 6px; }
.rform-write--inline {
  display: inline-block; width: 12rem; min-height: 1.5rem; height: 1.5rem;
  margin-top: 0; vertical-align: baseline;
}
.rform-choice { font-size: 0.78rem; color: var(--color-text-secondary); white-space: nowrap; }

.rform-note {
  margin: var(--space-4) 0 0; padding: var(--space-3) var(--space-4);
  font-size: 0.82rem; line-height: 1.55; color: var(--color-text-secondary);
  background: var(--color-bg-secondary); border-radius: var(--radius-sm);
}

/* Printed only: identifies the sheet and where it came from. */
.rform-source { display: none; }

/* ===== Print ================================================================ */
/* Wave 1 ships printable HTML and no downloadable file, so this stylesheet IS
   the deliverable — not a nicety. Tested against Letter in Chrome and Safari. */
/* ===========================================================================
   /inspections — the six-act page. D-027.
   PAGE-SCOPED and deliberately small: the composed cards reuse the existing
   .pv-card, .hv- and .ac- vocabulary and Act IV reuses .pv-tile-grid, so only the
   things that genuinely did not exist are defined here.
=========================================================================== */

/* ---- Act I: typography dominant, photograph INSET (D-027) ----
   The hero headline stays the largest painted element. The photograph sits in
   the hero's visual slot at a capped width so it establishes the environment
   without becoming the page's identity — and so it is not automatically the
   LCP candidate. Final loading attributes are set from measured placement. */
.insp-act1 {
  position: relative;
  display: grid;
  gap: var(--space-5);
  max-width: 560px;
  margin-inline: auto;
}

.insp-photo {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-secondary);
  /* aspect-ratio reserves the box before the image arrives, so CLS stays 0
     even on a cold cache. The real <img> also carries width/height. */
  aspect-ratio: 4 / 3;
}

.insp-photo-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The slot shown until the licensed photograph exists. Deliberately reads as a
   placeholder: a stand-in stock image would invite judgement of a photograph
   nobody chose. */
.insp-photo-slot {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-5);
  border: 1.5px dashed var(--color-border);
  border-radius: var(--radius-lg);
  background:
    repeating-linear-gradient(135deg, var(--color-bg-secondary) 0 10px, transparent 10px 20px),
    var(--color-bg);
}

.insp-photo-tag {
  align-self: flex-start;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: 3px 10px;
}

.insp-photo-slot code {
  font-size: 0.72rem;
  color: var(--color-text-secondary);
  word-break: break-all;
}

/* The Act I product fragment overlaps the photograph on wide viewports — the
   bridge between the real world and the software. It stacks below on narrow,
   where overlap would crowd both. */
.insp-frag { max-width: 430px; margin-inline: auto; }

@media (min-width: 900px) {
  .insp-act1 { max-width: 620px; }
  .insp-act1 .insp-frag {
    margin-top: calc(var(--space-16) * -1);
    margin-inline: 0 0;
    margin-left: auto;
    width: min(100%, 370px);
  }
}

/* ---- Act III / Act V: provenance made visible ----
   The source block is shown rather than described. That is the difference
   between quoting the product and writing "created from inspection". */
.insp-chain-vis {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  max-width: 430px;
  margin-inline: auto;
}

.insp-source {
  width: 100%;
  padding: var(--space-4) var(--space-5);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-md);
}

.insp-chain-vis--done .insp-source { border-left-color: var(--color-success); }

.insp-source-k {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.insp-source-v {
  display: block;
  margin-top: 2px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-text);
}

.insp-arrow {
  display: inline-flex;
  color: var(--color-text-secondary);
  transform: rotate(90deg);
}

.insp-arrow svg { width: 18px; height: 18px; }

.insp-chain-vis .insp-frag { margin-inline: 0; width: 100%; max-width: none; }

.insp-frag-end { margin-left: auto; }

/* ---- Act IV: the manager's scale ---- */
.insp-mgmt {
  display: grid;
  gap: var(--space-10);
  align-items: center;
}

@media (min-width: 900px) {
  .insp-mgmt { grid-template-columns: 0.85fr 1.15fr; gap: var(--space-16); }
}

.insp-mgmt-copy { max-width: 42ch; }

.insp-mgmt-vis { display: grid; gap: var(--space-5); }

/* D-025 — the COUNTS are the data. The bar carries relative magnitude only and
   is never labelled as a share of anything, so nothing can be read as a
   percentage of the open-action population. The bar is aria-hidden; the count
   beside it is what assistive technology reads. */
.insp-aging {
  margin: 0;
  padding: var(--space-5) var(--space-6);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.insp-aging-cap {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-4);
}

.insp-aging-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}

.insp-aging-row {
  display: grid;
  grid-template-columns: 5.5rem 2rem 1fr;
  align-items: center;
  gap: var(--space-3);
}

.insp-aging-label { font-size: 0.85rem; color: var(--color-text-secondary); }

.insp-aging-count {
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-text);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.insp-aging-bar {
  display: block;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-bg-secondary);
  overflow: hidden;
}

.insp-aging-bar > span {
  display: block;
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}

/* At 320px the three tiles overflowed by 11px: grid items default to
   min-width:auto, so the longest label ("Completed this month") forced each 1fr
   track wider than its share. Scoped to this page because .pv-tile-grid is
   shared with pv_dashboard() and other pages are out of scope. Letting the
   tracks shrink lets the label wrap instead. */
.insp-mgmt-vis .pv-tile { min-width: 0; }
.insp-mgmt-vis .pv-tile-label { overflow-wrap: break-word; hyphens: none; }

@media (max-width: 360px) {
  /* Below the smallest common phone the fixed label/count columns stop paying
     for themselves; let the label take the width it needs and the bar follow. */
  .insp-aging { padding-inline: var(--space-4); }
  .insp-aging-row { grid-template-columns: 1fr auto; gap: var(--space-2); }
  .insp-aging-bar { grid-column: 1 / -1; }
}

/* ---- Act VI: the largest typographic moment on the page ---- */
.insp-close-h {
  font-size: clamp(1.9rem, 5vw, 3.4rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
  font-weight: 800;
  text-wrap: balance;
  max-width: 24ch;
  margin-inline: auto;
}

.insp-close-chain { max-width: 520px; margin-inline: auto; }

/* ===========================================================================
   /equipment — the recognition story. Five movements, zero new primitives.
   Layout only: every fragment reuses the existing pv-card / hv- / ac- vocabulary.
=========================================================================== */

/* Movement 1. The hero opens on an ABSENCE, so the card is centred and alone —
   nothing beside it to answer the question before the reader has felt it. */
.eq-open {
  display: flex;
  justify-content: center;
}

.eq-asset {
  max-width: 430px;
  width: 100%;
  text-align: left;
}

/* no_schedule is NEUTRAL in the product and neutral here. A red chip would turn a
   blind spot into an alarm and lose the recognition the movement depends on. */
.eq-ico-neutral {
  background: var(--color-bg-secondary);
  color: var(--color-text-secondary);
}

/* The real next-action label, rendered as the affordance it is in the product —
   deliberately not a marketing button, because clicking it here does nothing. */
.eq-foot {
  justify-content: flex-start;
}

.eq-next {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-accent);
  background: var(--color-accent-bg);
  border: 1px solid color-mix(in srgb, var(--color-accent) 24%, transparent);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
}

/* Movement 2. One beat, so it is a two-column aside rather than a full feature block. */
.eq-beat {
  display: grid;
  gap: var(--space-8);
  align-items: center;
}

@media (min-width: 880px) {
  .eq-beat { grid-template-columns: 1fr 430px; gap: var(--space-16); }
}

.eq-beat-copy { max-width: 46ch; }
.eq-beat-vis { display: flex; justify-content: center; }

/* Movement 5. Copy left, the register right. */
.eq-register {
  display: grid;
  gap: var(--space-10);
  align-items: center;
}

@media (min-width: 900px) {
  .eq-register { grid-template-columns: 0.85fr 1.15fr; gap: var(--space-16); }
}

.eq-register-copy { max-width: 42ch; }

/* Four tiles, so the shared 3-column grid needs a 2x2 here. Scoped, because
   .pv-tile-grid belongs to pv_dashboard() and other pages are out of scope. */
.eq-register-vis .pv-tile-grid { grid-template-columns: 1fr 1fr; }
.eq-register-vis .pv-tile { min-width: 0; }
.eq-register-vis .pv-tile-label { overflow-wrap: break-word; }
.eq-register-vis .pv-tile:nth-child(3n) { border-right: 1px solid var(--color-border); }
.eq-register-vis .pv-tile:nth-child(2n) { border-right: none; }
.eq-register-vis .pv-tile:nth-child(n+3) { border-bottom: none; }

@media (max-width: 420px) {
  .eq-register-vis .pv-tile-grid { grid-template-columns: 1fr; }
  .eq-register-vis .pv-tile { border-right: none; border-bottom: 1px solid var(--color-border); }
  .eq-register-vis .pv-tile:last-child { border-bottom: none; }
}

/* ===========================================================================
   /training — the reconciliation story. Six movements, zero new primitives and
   zero new tone variants: sev-neutral (added for Equipment, D-032) carries both
   neutral states here — Not Evaluated and No expiry.
   Layout only. Every fragment is a pv-card / hv- / ac- / pv_notification quotation.
=========================================================================== */

.tr-open { display: flex; justify-content: center; }
.tr-assign { max-width: 430px; width: 100%; text-align: left; }

/* A caption inside a card foot, marked as OUR note rather than product chrome:
   smaller, secondary, no icon. It must not read as a UI string. */
.tr-note { font-size: 0.8rem; color: var(--color-text-secondary); font-style: italic; }

/* The one danger-toned row icon on the page. Page-scoped, exactly as Equipment
   scoped eq-ico-neutral, rather than widening the shared .ac-ico vocabulary. */
.tr-ico-danger { background: var(--color-danger-bg); color: var(--color-danger); }

/* Movements 2, 3 and 6 are single beats: copy beside one card. */
.tr-beat { display: grid; gap: var(--space-8); align-items: center; }
@media (min-width: 880px) {
  .tr-beat { grid-template-columns: 1fr 420px; gap: var(--space-16); }
  .tr-beat-rev { grid-template-columns: 420px 1fr; }
  .tr-beat-rev .tr-beat-copy { order: 2; }
  .tr-beat-rev .tr-beat-vis { order: 1; }
}
.tr-beat-copy { max-width: 48ch; }
.tr-beat-vis { display: flex; justify-content: center; }
.tr-reasons, .tr-aud, .tr-remind { max-width: 420px; width: 100%; }

/* Reasons are metadata, so they wrap as a flat field of neutral chips — no
   ordering, no severity, no emphasis on any one of them. */
.tr-pill-wrap { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }

/* MOVEMENT 4. The two frames sit SIDE BY SIDE and are deliberately not resolved
   by the layout — neither is subordinate, because both readings are correct. */
.tr-recon { display: grid; gap: var(--space-6); }
@media (min-width: 760px) { .tr-recon { grid-template-columns: 1fr 1fr; gap: var(--space-8); } }
.tr-frame { display: flex; flex-direction: column; gap: var(--space-3); }
.tr-frame > .pv-card { flex: 1; }
.tr-frame-cap {
  font-size: 0.85rem; font-weight: 600; color: var(--color-text-secondary);
  text-align: center; margin: 0;
}

.tr-inverse { display: grid; gap: var(--space-8); align-items: center; }
@media (min-width: 880px) { .tr-inverse { grid-template-columns: 1fr 400px; gap: var(--space-12); } }
.tr-inverse-copy { max-width: 52ch; }
.tr-inverse-vis { display: flex; justify-content: center; }
.tr-inverse-vis > .pv-card { max-width: 400px; width: 100%; }
.tr-h3 { font-size: 1.35rem; font-weight: 700; line-height: 1.3; margin: 0; }

/* The calibration: two columns, because the severity split IS the information. */
.tr-calib { display: grid; gap: var(--space-8); }
@media (min-width: 760px) { .tr-calib { grid-template-columns: 1fr 1fr; gap: var(--space-10); } }
.tr-calib-col { display: flex; flex-direction: column; gap: var(--space-3); }
.tr-calib-head {
  font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-text-secondary); margin: 0 0 var(--space-1);
}
.tr-calib-col .pv-notification { max-width: none; }

.tr-foot-note {
  margin: var(--space-8) auto 0; max-width: 56ch; text-align: center;
  font-size: 0.95rem; color: var(--color-text-secondary);
}

/* ===========================================================================
   /training-courses — the course library catalog listing.
=========================================================================== */

.tc-stats { max-width: 420px; margin-inline: auto; }
.tc-stats.pv-tile-grid { grid-template-columns: 1fr 1fr; }
.tc-stats .pv-tile, .tc-stats.pv-tile-grid .pv-tile { min-width: 0; }
.tc-stats.pv-tile-grid .pv-tile:nth-child(2n) { border-right: none; }
.tc-stats.pv-tile-grid .pv-tile:nth-child(n+3) { border-bottom: none; }

/* The 2x2 stat grid cannot hold two columns at 320px — stack it. */
@media (max-width: 400px) {
  .tc-stats.pv-tile-grid { grid-template-columns: 1fr; }
  .tc-stats.pv-tile-grid .pv-tile { border-right: none; border-bottom: 1px solid var(--color-border); }
  .tc-stats.pv-tile-grid .pv-tile:last-child { border-bottom: none; }
}

.tc-cats { display: grid; gap: var(--space-8); }
@media (min-width: 720px)  { .tc-cats { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1100px) { .tc-cats { grid-template-columns: 1fr 1fr 1fr; } }

.tc-cat {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}

.tc-cat-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-2);
}

.tc-cat-name { font-size: 1.05rem; font-weight: 700; line-height: 1.35; margin: 0; }

.tc-cat-count {
  flex: none; font-size: 0.8rem; font-weight: 700; color: var(--color-accent);
  background: var(--color-accent-bg); border-radius: var(--radius-sm); padding: 2px 9px;
}

.tc-cat-note {
  font-size: 0.85rem; color: var(--color-text-secondary);
  margin: 0 0 var(--space-4); line-height: 1.5;
}

.tc-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }

.tc-list li {
  position: relative; padding-left: 18px;
  font-size: 0.9rem; line-height: 1.45; color: var(--color-text);
  overflow-wrap: break-word;
}

.tc-list li::before {
  content: ""; position: absolute; left: 4px; top: 0.6em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--color-accent);
}

.tc-disclaimer {
  margin: var(--space-10) auto 0; max-width: 72ch;
  font-size: 0.85rem; line-height: 1.6; color: var(--color-text-secondary);
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); padding: var(--space-5);
}

@media print {
  /* Chrome/Safari drop backgrounds by default; forms must still show their
     rules and boxes, so every printed border is an explicit black line. */
  :root {
    --color-bg: #fff; --color-bg-secondary: #fff;
    --color-text: #000; --color-text-secondary: #000;
    --color-border: #000; --color-accent: #000;
  }
  html, body { background: #fff !important; color: #000 !important; }

  /* Chrome, the print button, the trial CTA, the related block and the rest of the
     site furniture: none of it belongs on a clipboard. */
  .site-header, .site-footer, .breadcrumb-bar, .breadcrumb, .guide-toc,
  .cta, .no-print, .resource-print, .section-bg { display: none !important; }

  /* PRINT THE ARTIFACT, NOT THE ARTICLE.
     "Print this form" has to produce the form. Printing the whole page produced
     four to nine sheets for a one-page form, which is a defect and not a
     preference, so on a resource page everything in the body is suppressed except
     the artifact itself. The reader still gets the H1 (so the sheet is
     identifiable), the regulatory-status line (so it travels with the form), and
     .rform-source, which carries the URL, the date and the compliance limit on
     every printed copy.
     Scoped to .resource so guides and the calculator print in full as before. */
  .resource .guide-body > * { display: none !important; }
  .resource .guide-body > .rform { display: block !important; }
  /* TOOLBOX TALKS ARE THE EXCEPTION. The supervisor prints the talk to deliver it, so
     the content IS the artifact and the attendance table is the by-product. :not(.no-print)
     rather than a blanket override, so the print button and the commercial CTA stay off
     the sheet. */
  .resource--talk .guide-body > *:not(.no-print) { display: block !important; }
  /* AND SO ARE TOOLS. A calculator has no .rform, so the artifact-only rule above
     would print a blank sheet — the failure mode is silent, which is the worst kind.
     What a reader prints from an estimator is the method and the assumptions, so the
     content prints in full. The result block is live-rendered and prints with whatever
     is on screen, which is correct: you print it to take the number to a meeting. */
  .resource--tool .guide-body > *:not(.no-print) { display: block !important; }
  .resource .guide-head .text-lead,
  .resource .guide-head .guide-byline { display: none !important; }

  a { color: #000 !important; text-decoration: none !important; }
  /* A printed page cannot be clicked, so a reader needs the destination. Only
     for real destinations — not for in-page anchors. */
  .guide-body a[href^="http"]::after,
  .guide-body a[href^="/"]::after { content: " (" attr(href) ")"; font-size: 0.75em; }
  .rform a::after { content: none !important; }

  .container, .container-narrow { max-width: none !important; padding: 0 !important; }
  .guide-head { padding-block: 0 0.5rem !important; }
  .guide-body { padding-bottom: 0 !important; }
  body { font-size: 10.5pt; line-height: 1.4; }
  h1 { font-size: 16pt; }
  h2 { font-size: 12pt; }
  /* The resource heading block is identification, not a title page — it must not
     cost the artifact a sheet. Measured: this is what puts the near-miss form on
     one side of paper, which is the whole design of that resource. */
  .resource h1 { font-size: 13pt; margin: 0 0 0.05in; }
  .resource .resource-status {
    margin: 0 0 0.12in; padding: 0.04in 0; background: none;
    /* radius must go with the border: a rounded rect showing only its bottom edge
       prints as two little curled ends, which is what it was doing. */
    border: 0; border-bottom: 1px solid #000; border-radius: 0;
    font-size: 8pt; line-height: 1.35;
  }
  .resource .text-eyebrow { font-size: 7.5pt; }

  /* ---- PAGINATION MODEL, rewritten 2026-09-23 ----
     Measured defects it fixes: the tracker pushed a 205-character footer onto a
     near-empty second sheet; the checklist wasted sheet 1 at 27% full and sheet 5
     at 28%; the JHA template's sheet 2 was 30% full; and 4-10 drawn borders per
     page were crossing the bottom margin.

     Root cause of the waste: .rform and every .rform-section had
     break-inside: avoid. A section TALLER than a page cannot avoid breaking, so the
     browser shunted the whole thing to a fresh sheet and left the previous one
     half empty. Atomicity belongs on the things that must never split — a field, a
     tick row, a table row — and NOT on containers that are legitimately taller
     than a page.

     The outer .rform border is also dropped in print. On a multi-page block it
     produces exactly the artefact complained about: an edge drawn at the bottom of
     one sheet and reopened at the top of the next. In print the artifact IS the
     document and needs no frame around it; every field and cell carries its own. */
  .rform { border: 0; padding: 0; margin: 0; }
  /* ATOMIC BY DEFAULT. A small section — sign-off, close-out, review — must never
     split, and the owner reported exactly that: the JHA's sign-off heading stranded
     at the foot of sheet 1 with its fields on sheet 2.
     The earlier fix for the opposite fault (whole sections shunted to a fresh sheet,
     wasting 70% of the previous one) set break-inside:auto on EVERY section. That
     was over-applied: only sections carrying a table longer than a page need to
     flow, and those opt in with .rform-section--flow. */
  .rform-section { break-inside: avoid; page-break-inside: avoid; margin-top: 0.16in; padding-top: 0.1in; }
  .rform-section--flow { break-inside: auto; page-break-inside: auto; }
  /* These must never split. A half-drawn box is worse than a page break. */
  .rform-field, .rform-check, .rform-note { break-inside: avoid; page-break-inside: avoid; }
  .rform-section-title { break-after: avoid; page-break-after: avoid; }
  .rform-head { margin-bottom: 0.14in; break-after: avoid; page-break-after: avoid; }
  .rform-grid { gap: 0.12in 0.18in; }

  /* Entry boxes print as rectangles with whatever was typed inside them. Tall
     enough to write in with a pen and to tap in a PDF app: 1.32rem at 10.5pt is a
     shade over 4.5mm. */
  .rform-write {
    border: 1px solid #000; border-radius: 0;
    min-height: calc(var(--lines, 1) * 1.32rem);
    height: auto;                      /* grown textareas print their full content */
    margin-top: 2px; background: #fff !important;
    color: #000 !important; font-size: 9pt; padding: 1px 4px;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  textarea.rform-write { overflow: visible; resize: none; white-space: pre-wrap; word-break: break-word; }
  /* Swap the control for its mirror so the value wraps to the printed width. */
  textarea.rform-write + .rform-printed { display: block; }
  textarea.rform-write:has(+ .rform-printed) { display: none; }
  .rform-printed {
    border: 1px solid #000; background: #fff;
    min-height: calc(var(--lines, 1) * 1.32rem);
    margin-top: 2px; padding: 1px 4px;
    font-size: 9pt; line-height: 1.32; color: #000;
    white-space: pre-wrap; word-break: break-word;
    break-inside: avoid; page-break-inside: avoid;
  }
  .rform-printed--cell { border: 0; min-height: 2.1rem; font-size: 8pt; margin-top: 0; }
  .rform-write--inline { min-height: 1.25rem; height: auto; }
  .rform-printed--inline {
    display: inline-block; min-height: 1.25rem; margin-top: 0;
    vertical-align: baseline; font-size: 8.5pt;
  }
  .rform-org-field { display: inline-flex; }
  .rform-write--cell { border: 0; min-height: 2.1rem; font-size: 8pt; }
  .rform-cell { padding: 0 !important; }
  .rform-cell--tick { padding: 3px !important; }
  /* No focus ring or UI affordance survives onto paper. */
  .rform-write:focus, .rform-box:focus { outline: none !important; }

  .rform-box {
    border: 1px solid #000; background: #fff !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* The tick is border-drawn, so it prints. A background-image tick would not. */
  .rform-box:checked::after { border-color: #000; }
  .rform-label { font-size: 8.5pt; }
  .rform-hint { font-size: 7.5pt; }
  .rform-title { font-size: 11pt; }
  .rform-section-title { font-size: 7.5pt; }
  .rform-note { padding: 0.06in 0; background: none; font-size: 7.5pt; }

  /* The sheet's identity line must not be orphaned onto a page of its own — that
     was the tracker's near-empty second sheet. */
  .rform-source { break-before: avoid; page-break-before: avoid; break-inside: avoid; }

  /* Nothing may be drawn into the margin. Chrome will honour a break rather than
     clip a row that cannot fit. */
  .rform-table table { margin-bottom: 0; }
  .rform-table tbody tr { break-inside: avoid; page-break-inside: avoid; }

  /* A multi-page table repeats its header on every sheet. Without this a
     printed checklist's second page is unlabelled columns. */
  .rform-table { overflow: visible !important; border: 0; }
  .rform-table table { min-width: 0 !important; width: 100% !important; font-size: 8.5pt; }
  .rform-table thead { display: table-header-group; }
  /* NOTE: `break-after: avoid` on thead was tried here and Chrome ignores it, so a
     short table must instead sit in an ATOMIC section — see .rform-section--flow. A
     table header orphaned at the foot of a sheet is fixed by not letting its section
     split, not by asking the header nicely. */
  .rform-table caption { break-after: avoid; page-break-after: avoid; }
  .rform-table tfoot { display: table-footer-group; }
  .rform-table tr { page-break-inside: avoid; break-inside: avoid; }
  .rform-table th, .rform-table td { border: 1px solid #000 !important; }

  .rform-source {
    display: block; margin-top: 0.25in; padding-top: 0.1in;
    border-top: 1px solid #000; font-size: 8pt;
  }
  h2, h3 { page-break-after: avoid; break-after: avoid; }
  p, li { orphans: 3; widows: 3; }

  /* NAMED-PAGE landscape was tried and withdrawn. `page: landscape` + `@page
     landscape { size: landscape }` looked right for the eleven-column tracker, but
     measured against headless Chrome the sheet came out 612x792pt portrait anyway
     while the named-page change still forced a page break — a blank sheet for
     nothing. Wide tables are made to fit portrait instead.

     Landscape IS available, per resource, via DOCUMENT-LEVEL @page emitted through
     the $pageHeadExtra head hook — which works, and which the JHA template uses.
     @page takes no selector, so a stylesheet shared by 43 pages cannot express it;
     that is the whole reason the hook exists. See
     guides/job-hazard-analysis-template.php. */
  .rform-table-wide table { font-size: 7pt; }
  .rform-table-wide th, .rform-table-wide td { padding: 2px 3px; }
}
@page { margin: 0.5in; }

/* Eleven columns (the corrective-action tracker) needs more room than the
   620px default before the columns become unreadable slivers. */
.rform-table-wide table { min-width: 980px; }

/* The checklist table's content is the item text; the three tick columns are
   almost nothing. Without this the item wraps to three lines per row in print
   while 5% columns sit half empty. */
.rform-table-check th:nth-child(1), .rform-table-check td:nth-child(1) { width: 34%; }
.rform-table-check th:nth-child(2), .rform-table-check td:nth-child(2),
.rform-table-check th:nth-child(3), .rform-table-check td:nth-child(3),
.rform-table-check th:nth-child(4), .rform-table-check td:nth-child(4) { width: 6%; text-align: center; }
.rform-table-check th:nth-child(5), .rform-table-check td:nth-child(5) { width: 34%; }
.rform-table-check th:nth-child(6), .rform-table-check td:nth-child(6) { width: 20%; }
.rform-table-check td:nth-child(2) .rform-box,
.rform-table-check td:nth-child(3) .rform-box,
.rform-table-check td:nth-child(4) .rform-box { display: inline-block; }

/* ===== Library hub controls (/resources) =================================== */
/* Added 2026-09-23. The hub had 12 cards under 7 headings and read as clutter;
   format became a filter, topic became a card label, and the headings collapsed to
   two. Progressive by construction: .lib-controls ships with [hidden] and is
   revealed by JS, so a JavaScript-off reader sees the complete list and no dead
   controls. */

.lib-controls {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-5);
  padding-bottom: var(--space-5); border-bottom: 1px solid var(--color-border);
}
.lib-controls[hidden] { display: none; }

.lib-filters { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.lib-filter {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 40px; padding: 0 var(--space-4);
  font: inherit; font-size: 0.875rem; font-weight: 600; color: var(--color-text-secondary);
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-full); cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              background var(--duration-fast) var(--ease-out);
}
.lib-filter:hover { border-color: var(--color-accent); color: var(--color-text); }
.lib-filter:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }
/* Selected state is carried by background AND border AND weight, never colour
   alone, so it survives a monochrome or high-contrast rendering. */
.lib-filter.is-active {
  background: var(--color-accent); border-color: var(--color-accent); color: #fff;
}
.lib-filter-count {
  font-size: 0.75rem; font-weight: 700; font-variant-numeric: tabular-nums;
  padding: 1px 7px; border-radius: var(--radius-full);
  background: var(--color-bg-secondary); color: var(--color-text-secondary);
}
.lib-filter.is-active .lib-filter-count { background: rgba(255,255,255,.22); color: #fff; }

.lib-search { display: flex; flex-direction: column; gap: 2px; min-width: 240px; }
.lib-search-label {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--color-text-secondary);
}
.lib-search-input {
  min-height: 40px; padding: 0 var(--space-4);
  font: inherit; font-size: 0.9375rem; color: var(--color-text);
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.lib-search-input:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 1px; border-color: var(--color-accent); }

.lib-status { margin: 0 0 var(--space-5); font-size: 0.8125rem; color: var(--color-text-secondary); }
.lib-status:empty { display: none; }

.lib-card[hidden] { display: none; }
.lib-card-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-3); }
.lib-card-topic { font-size: 0.75rem; color: var(--color-text-secondary); }
/* The card heading is an h2 here (the grid is the page's only content section), so
   it needs the card's type scale rather than the document's. */
.lib-card-title { font-size: 1.05rem; font-weight: 700; margin: 0; color: var(--color-text); }

.lib-empty { margin: var(--space-6) 0 0; font-size: 0.9375rem; color: var(--color-text-secondary); }
.lib-empty[hidden] { display: none; }
.lib-reset {
  font: inherit; font-weight: 600; color: var(--color-accent);
  background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline;
}
.lib-reset:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 2px; }

@media print { .lib-controls, .lib-status, .lib-empty { display: none !important; } }

/* Risk-level cell in the JHA table: three tight tick boxes instead of "circle one",
   so the level can be set on screen and still prints. */
.rform-cell--risk { padding: 4px 6px !important; }
.rform-risk { display: flex; flex-direction: column; gap: 3px; }
.rform-check--tight { font-size: 0.78rem; gap: 5px; }
@media print {
  .rform-cell--risk { padding: 2px 3px !important; }
  .rform-check--tight { font-size: 7.5pt; gap: 3px; }
  .rform-risk { gap: 1px; }
}

/* ===== T01 hazard-assessment table column budget ==================== */
/* Landscape buys about 250pt of extra width. Spending it evenly would widen Step and
   Risk, which need no more room, so it goes where a supervisor actually has to think
   and write: Potential Hazards and Controls / Safe Work Procedure. */
.rform-table-jha th:nth-child(1), .rform-table-jha td:nth-child(1) { width: 3.5%; }   /* # */
.rform-table-jha th:nth-child(2), .rform-table-jha td:nth-child(2) { width: 17%; }    /* Task step */
.rform-table-jha th:nth-child(3), .rform-table-jha td:nth-child(3) { width: 25%; }    /* Potential hazards */
.rform-table-jha th:nth-child(4), .rform-table-jha td:nth-child(4) { width: 8.5%; }   /* Risk level */
.rform-table-jha th:nth-child(5), .rform-table-jha td:nth-child(5) { width: 32%; }    /* Controls */
.rform-table-jha th:nth-child(6), .rform-table-jha td:nth-child(6) { width: 14%; }    /* PPE */

/* Inline source citations on a toolbox-talk control. The number links to the Sources
   list, so a reader can check that a control actually follows from what it cites —
   which a Sources section at the bottom of the page does not establish. */
.tbt-cites { margin-left: 2px; }
.tbt-cite {
  display: inline-block; min-width: 1.15em; padding: 0 3px; margin-left: 2px;
  font-size: 0.68em; font-weight: 700; line-height: 1.5; text-align: center;
  color: var(--color-accent); background: var(--color-accent-bg);
  border-radius: 3px; text-decoration: none;
}
.tbt-cite:hover, .tbt-cite:focus-visible { text-decoration: underline; }
.tbt-note { font-size: 0.875rem; color: var(--color-text-secondary); }
@media print {
  .tbt-cite { color: #000; background: none; border: 1px solid #000; font-size: 6.5pt; }
}

/* ---------- Homepage product router — light "find your way in" cards ----------
 * Three offerings as comparable light cards on a soft-grey band. EHSTEC Safety is
 * the emphasized flagship (accent border, lift, ribbon, filled CTA); University and
 * LMS are balanced secondary cards. University carries a free tag. */
.router-section {
  background: var(--color-bg-secondary);
  border-block: 1px solid var(--color-border);
  padding-block: var(--space-16);
}
.router-section .text-eyebrow { color: var(--color-accent); }
.router-section h2 { color: var(--color-text); }
.router-section .text-lead { color: var(--color-text-secondary); }
.product-router {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
  max-width: 1080px;
  margin: var(--space-10) auto 0;
  text-align: left;
  align-items: stretch;
}
.router-card {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  position: relative;
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}
.router-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: #cbd5e1; }
.router-card .router-icon { color: var(--color-accent); margin-bottom: var(--space-5); display: inline-flex; width: 46px; height: 46px; border-radius: var(--radius-md); background: var(--color-accent-bg); align-items: center; justify-content: center; }
.router-card .router-icon svg { width: 24px; height: 24px; }
.router-card h3 { margin: 0 0 var(--space-1); font-size: 1.3rem; letter-spacing: -0.01em; color: var(--color-text); }
.router-card .router-for { color: var(--color-text-secondary); font-size: 0.9rem; margin: 0 0 var(--space-4); }
.router-card .router-headline { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; color: var(--color-text); margin: 0 0 var(--space-3); }
.router-card .router-headline small { font-size: 0.85rem; font-weight: 600; color: var(--color-text-secondary); letter-spacing: 0; }
.router-card .router-note { color: var(--color-text-secondary); font-size: 0.9rem; line-height: 1.55; margin: 0 0 var(--space-5); }
.router-mini { list-style: none; padding: 0; margin: 0 0 var(--space-5); display: flex; flex-direction: column; gap: 8px; }
.router-mini li { display: flex; gap: 8px; font-size: 0.9rem; color: var(--color-text-secondary); }
.router-mini svg { width: 16px; height: 16px; color: var(--color-success); flex-shrink: 0; margin-top: 3px; }
.router-card .router-cta-btn { margin: auto 0 0; }
.router-card .router-cta-btn a {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 0.95rem; text-decoration: none; color: var(--color-accent);
}
.router-card .router-cta-btn a svg { width: 16px; height: 16px; transition: transform var(--duration-base) var(--ease-out); }
.router-card:hover .router-cta-btn a svg { transform: translateX(4px); }
/* Flagship — EHSTEC Safety */
.router-card.is-flagship { border-color: var(--color-accent); box-shadow: 0 0 0 1px var(--color-accent), var(--shadow-md); transform: translateY(-6px); }
.router-card.is-flagship:hover { transform: translateY(-10px); box-shadow: 0 0 0 1px var(--color-accent), var(--shadow-lg); }
.router-card.is-flagship .router-cta-btn a { background: var(--color-accent); color: #fff; justify-content: center; width: 100%; padding: 11px 20px; border-radius: var(--radius-full); }
.router-card.is-flagship .router-cta-btn a:hover { background: var(--color-accent-hover); }
.router-card.is-flagship .router-cta-btn a svg { color: #fff; }
.router-ribbon {
  position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
  background: var(--color-accent); color: #fff; font-size: 0.68rem; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase; padding: 5px 14px;
  border-radius: var(--radius-full); box-shadow: var(--shadow-md); white-space: nowrap;
}
.router-tag {
  position: absolute; top: var(--space-6); right: var(--space-6);
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 10px; border-radius: var(--radius-full);
}
.router-tag.tag-free { background: var(--color-success-bg); color: #15803d; }
.router-tag.tag-flagship { background: var(--color-accent-bg); color: var(--color-accent); }
@media (max-width: 860px) {
  .product-router { grid-template-columns: 1fr; max-width: 460px; }
  .router-card.is-flagship { transform: none; }
  .router-card.is-flagship:hover { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  .router-card, .router-card .router-cta-btn a svg { transition: none; }
  .router-card:hover, .router-card.is-flagship:hover { transform: none; }
}

/* ---------- University — compact "training credentials & OSHA information" ----------
 * Replaces the lone disclaimer paragraph floating in a tall tinted band with an
 * intentional, readable info card that connects the legal/OSHA note to the
 * certificate context. Meaning is unchanged; no OSHA affiliation is implied. */
.tc-info {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  box-shadow: var(--shadow-sm);
}
.tc-info-icon { color: var(--color-accent); flex-shrink: 0; margin-top: 2px; }
.tc-info-icon svg { width: 22px; height: 22px; }
.tc-info-title { font-size: 1.05rem; font-weight: 700; margin: 0 0 var(--space-2); letter-spacing: -0.01em; color: var(--color-text); }
.tc-info-body { font-size: 0.9rem; line-height: 1.6; color: var(--color-text-secondary); margin: 0; }
@media (max-width: 560px) {
  .tc-info { flex-direction: column; gap: var(--space-3); padding: var(--space-5); }
}

/* ------------------------------------------------------------------ *
 * pv-placeholder — TEMPORARY stand-in for product screenshots that are
 * intentionally not shown. Branded, non-revealing, same footprint as a
 * screenshot so the surrounding layout is unchanged. See pv_placeholder().
 * ------------------------------------------------------------------ */
.pv-placeholder {
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  background: radial-gradient(130% 130% at 12% 0%, var(--color-accent-bg) 0%, var(--color-bg) 58%);
  aspect-ratio: 16 / 11;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  overflow: hidden;
}
.pv-ph-chip {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-md);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  color: var(--color-accent);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-sm);
}
.pv-ph-chip svg { width: 28px; height: 28px; }
.pv-ph-title {
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
  color: var(--color-text);
  margin-top: var(--space-2);
}
.pv-ph-sub {
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--color-text-secondary);
  max-width: 36ch;
}
.pv-ph-bars {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: var(--space-5);
}
.pv-ph-bars span {
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--color-border);
  opacity: 0.7;
}
.pv-ph-bars span:nth-child(1) { width: 82%; }
.pv-ph-bars span:nth-child(2) { width: 64%; }
.pv-ph-bars span:nth-child(3) { width: 46%; }

/* ===================================================================
 * V2 "Clean Editorial" — shared component library for content pages.
 * Scoped under .v2 so it never touches not-yet-migrated pages. Uses the
 * editorial design tokens from variables.css. (The homepage uses its own
 * .v2home scope; these two will be unified in a later pass.)
 * =================================================================== */
.v2{color:var(--color-text);line-height:1.6;letter-spacing:-.011em}
.v2 *{box-sizing:border-box}
.v2 h1,.v2 h2,.v2 h3,.v2 h4{margin:0;line-height:1.08;font-weight:700}
.v2 p{margin:0}
.v2 .serif{font-family:var(--serif);font-weight:560;letter-spacing:-.015em;font-optical-sizing:auto}
.v2 .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.v2 .grad{background:var(--gradh);-webkit-background-clip:text;background-clip:text;color:transparent}
.v2 .eyebrow{font-weight:700;font-size:13px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
/* Highlight = a marker band sized to the GLYPHS, not the line-box, so a phrase
   that wraps across lines (e.g. a large serif hero) hugs the text on every line
   instead of rendering as tall, offset, gappy boxes. box-decoration-break:clone
   gives each wrapped fragment its own band. */
.v2 .hl{background:none;padding:0;border-radius:0}
.v2 .kick{display:inline-flex;align-items:center;gap:8px;font-weight:700;font-size:13px;color:var(--blue-d);background:var(--color-accent-bg);border-radius:999px;padding:6px 14px}
.v2 .badge{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:5px 11px;font-size:11.5px;font-weight:700}
.v2 .badge-free{background:var(--green-bg);color:var(--green-d)}.v2 .badge-paid{background:var(--color-accent-bg);color:var(--blue-d)}
.v2 .vb{display:inline-flex;align-items:center;gap:9px;font-weight:650;font-size:15.5px;border-radius:11px;padding:13px 22px;cursor:pointer;border:1.5px solid transparent;transition:background .2s,transform .12s;text-decoration:none}
.v2 .vb:active{transform:translateY(1px)}
.v2 .vb-dark{background:var(--navy);color:#fff}.v2 .vb-dark:hover{background:#13294a}
.v2 .vb-primary{background:var(--blue);color:#fff}.v2 .vb-primary:hover{background:var(--blue-d)}
.v2 .vb-ghost{background:#fff;color:var(--ink);border-color:var(--line-2)}.v2 .vb-ghost:hover{background:var(--color-bg-secondary)}
.v2 .vb-lg{padding:16px 26px;font-size:16.5px}.v2 .vb-sm{padding:9px 15px;font-size:14px}
.v2 .page{max-width:1140px;margin:0 auto;padding:60px 28px}
.v2 .center{text-align:center;max-width:740px;margin-inline:auto}
.v2 .center h1{font-family:var(--serif);font-weight:540;font-size:clamp(34px,5vw,56px);letter-spacing:-.02em}
.v2 .center p{font-size:19px;color:var(--ink-2);margin-top:16px}
.v2 .sec-head{text-align:center;max-width:720px;margin:0 auto 10px}
.v2 .sec-head h2{font-family:var(--serif);font-weight:560;font-size:clamp(30px,4.2vw,46px);line-height:1.08;margin-top:12px}
.v2 .sec-head p{font-size:18.5px;color:var(--ink-2);margin-top:16px}
/* pricing table */
.v2 .ptable{max-width:1000px;margin:40px auto 0}
.v2 .pt{background:#fff;border:1px solid var(--line-2);border-radius:18px;overflow:hidden;box-shadow:var(--sh)}
.v2 .pt-head,.v2 .pt-row,.v2 .pt-cta{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr}
.v2 .pt-head>div{padding:22px 20px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}.v2 .pt-head>div:last-child{border-right:none}
.v2 .pt-head .corner{background:var(--color-bg-secondary)}
.v2 .pt-head .col .nm{font-weight:800;font-size:17px;display:flex;align-items:center;gap:9px}
.v2 .pt-head .col .emb{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;color:#fff}
.v2 .pt-head .col .tag{font-size:12px;margin-top:8px;font-weight:700;color:var(--ink-3)}
.v2 .pt-head .col.free{background:var(--green-bg)}.v2 .pt-head .col.free .tag{color:var(--green-d)}
.v2 .pt-row{border-bottom:1px solid var(--line)}.v2 .pt-row:last-child{border-bottom:none}
.v2 .pt-row>div{padding:15px 20px;border-right:1px solid var(--line);display:flex;align-items:center;justify-content:center}
.v2 .pt-row>div:first-child{justify-content:flex-start;font-weight:600;font-size:14.5px;color:var(--ink-2)}.v2 .pt-row>div:last-child{border-right:none}
.v2 .yes{color:var(--green-d)}.v2 .no{color:var(--ink-4)}
.v2 .pt-cta>div{padding:18px 20px;border-right:1px solid var(--line)}.v2 .pt-cta>div:first-child{background:var(--color-bg-secondary)}.v2 .pt-cta>div:last-child{border-right:none}
.v2 .pnote{text-align:center;color:var(--ink-3);font-size:13.5px;margin-top:20px;font-family:ui-monospace,Menlo,monospace}
/* V2 pricing — transparent tiers with an annual/monthly billing toggle */
.v2 .pbill-wrap{display:flex;justify-content:center;margin-top:30px}
.v2 .pbill{display:inline-flex;background:var(--color-bg-secondary);border:1px solid var(--line-2);border-radius:12px;padding:4px;gap:3px}
.v2 .pbill-opt{appearance:none;border:none;background:none;font:inherit;font-size:13.5px;font-weight:650;color:var(--ink-3);padding:9px 18px;border-radius:9px;cursor:pointer;transition:background .12s,color .12s}
.v2 .pbill-opt.is-on{background:#fff;color:var(--ink);box-shadow:0 1px 3px rgba(11,27,51,.12)}
.v2 .ptiers{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;max-width:1040px;margin:34px auto 0;align-items:stretch}
.v2 .ptier{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--line-2);border-radius:18px;padding:30px 26px;box-shadow:var(--sh-sm);transition:transform .15s,box-shadow .2s,border-color .15s}
.v2 .ptier:hover{transform:translateY(-3px);box-shadow:var(--sh);border-color:#cdd8ea}
.v2 .ptier.is-featured{border-color:var(--blue);box-shadow:0 22px 60px -26px rgba(36,87,245,.42)}
.v2 .ptier-badge{position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:var(--blue);color:#fff;font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;padding:5px 13px;border-radius:999px;white-space:nowrap}
.v2 .ptier-nm{display:flex;align-items:center;gap:10px;font-weight:800;font-size:18.5px;color:var(--ink)}
.v2 .ptier-emb{width:30px;height:30px;border-radius:8px;display:grid;place-items:center;color:#fff;flex:none}
.v2 .ptier-pricebox{margin-top:18px}
.v2 .ptier-amt{display:flex;align-items:baseline;gap:1px;font-family:var(--serif);color:var(--ink);line-height:1}
.v2 .ptier-amt .pcur{font-size:22px;font-weight:540;align-self:flex-start;margin-top:5px}
.v2 .ptier-amt .pnum{font-size:46px;font-weight:560;letter-spacing:-.02em}
.v2 .ptier-amt .pper{font-size:15px;font-weight:500;color:var(--ink-3);margin-left:4px;font-family:inherit}
.v2 .ptier-sub{font-size:12.5px;color:var(--ink-3);margin-top:8px;min-height:18px;line-height:1.4}
.v2 .ptier-pos{font-size:14px;color:var(--ink-3);margin-top:16px;line-height:1.5;min-height:42px}
.v2 .ptier-inc{font-size:11.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);margin:4px 0 14px;padding-top:20px;border-top:1px solid var(--line)}
.v2 .ptier-feats{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px}
.v2 .ptier-feats li{display:flex;gap:10px;font-size:14px;color:var(--ink-2);line-height:1.45}
.v2 .ptier-feats li svg{flex:none;margin-top:2px;color:var(--green-d)}
.v2 .ptier-cta{margin-top:auto;padding-top:24px}
/* product hero + feature list + cols + seats */
.v2 .phero{display:grid;grid-template-columns:1fr 1.05fr;gap:52px;align-items:center}
.v2 .phero h1{font-family:var(--serif);font-weight:540;font-size:clamp(32px,4.6vw,50px);letter-spacing:-.02em;margin-top:14px}
.v2 .phero p{font-size:19px;color:var(--ink-2);margin-top:16px}
.v2 .phero .cta{display:flex;gap:12px;margin-top:26px;flex-wrap:wrap}
.v2 .flist{display:grid;grid-template-columns:repeat(3,1fr);margin-top:48px;border-top:1px solid var(--line)}
.v2 .fitem{padding:26px 26px 26px 0;border-right:1px solid var(--line)}
.v2 .fitem:last-child{border-right:none;padding-right:0;padding-left:26px}.v2 .fitem:nth-child(2){padding-left:26px}
.v2 .fitem .ic{width:42px;height:42px;border-radius:11px;background:var(--color-accent-bg);color:var(--blue-d);display:grid;place-items:center;margin-bottom:14px}
.v2 .fitem h4{font-size:17px;margin-bottom:7px}.v2 .fitem p{font-size:14.5px;color:var(--ink-3)}
.v2 .cols{display:grid;grid-template-columns:1fr 1fr;gap:12px 40px;margin-top:30px}
.v2 .ck{display:flex;gap:11px;font-size:15.5px;padding:9px 0;border-bottom:1px solid var(--line)}.v2 .ck svg{flex:none;margin-top:3px;color:var(--green)}
.v2 .seats{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:30px}
.v2 .seat{border:1px solid var(--line);border-radius:14px;padding:22px;text-align:center;box-shadow:var(--sh-sm)}
.v2 .seat .amt{font-family:var(--serif);font-weight:560;font-size:30px;color:var(--ink)}.v2 .seat .nm{font-weight:700;margin-top:4px}.v2 .seat .d{font-size:13px;color:var(--ink-3);margin-top:7px}
/* concept card */
.v2 .card{background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--sh);overflow:hidden}
.v2 .card.mid{max-width:720px;margin:38px auto 0;text-align:left}
.v2 .card .hdr{display:flex;align-items:center;gap:11px;padding:15px 18px;border-bottom:1px solid var(--line)}
.v2 .card .hdr .ic{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;color:#fff;flex:none}
.v2 .card .hdr .ttl{font-weight:750;font-size:15.5px}.v2 .card .hdr .meta{font-size:12px;color:var(--ink-3)}
.v2 .rw{display:flex;align-items:center;gap:12px;padding:13px 18px;border-bottom:1px solid var(--line)}.v2 .rw:last-child{border-bottom:none}
.v2 .rw .dot{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;flex:none}
.v2 .rw .tx{flex:1}.v2 .rw .tx .a{font-weight:650;font-size:14.5px}.v2 .rw .tx .bb{font-size:12.5px;color:var(--ink-3)}
.v2 .chip-s{font-weight:700;font-size:11px;border-radius:7px;padding:4px 9px}
.v2 .chip-ok{background:var(--green-bg);color:var(--green-d)}.v2 .chip-rec{background:var(--color-accent-bg);color:var(--blue-d)}
.v2 .stages{display:flex;gap:4px;padding:14px 18px 6px}.v2 .stages .st{flex:1;height:6px;border-radius:4px;background:var(--line)}.v2 .stages .st.done{background:var(--green)}.v2 .stages .st.cur{background:var(--blue)}
.v2 .stl{display:flex;padding:0 18px 12px;border-bottom:1px solid var(--line)}.v2 .stl span{flex:1;font-size:10.5px;color:var(--ink-3);font-weight:600}.v2 .stl span.cur{color:var(--blue-d)}
.v2 .mini{display:flex;gap:10px;padding:14px 18px}.v2 .mini .m{flex:1;border:1px solid var(--line);border-radius:10px;padding:11px 12px;text-align:center}.v2 .mini .m .mv{font-family:var(--serif);font-weight:560;font-size:22px}.v2 .mini .m .ml{font-size:10.5px;color:var(--ink-3)}
/* platform/related tiles */
.v2 .rel{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:30px}
.v2 .relc{border:1px solid var(--line);border-radius:14px;padding:18px;background:#fff;box-shadow:var(--sh-sm);text-decoration:none;color:inherit;transition:transform .15s,box-shadow .2s}
.v2 .relc:hover{transform:translateY(-3px);box-shadow:var(--sh)}
.v2 .relc .ic{width:34px;height:34px;border-radius:9px;background:var(--green-bg);color:var(--green-d);display:grid;place-items:center;margin-bottom:12px}
.v2 .relc h4{font-size:15px}.v2 .relc p{font-size:12.5px;color:var(--ink-3);margin-top:5px}
.v2 .trust-band{background:var(--navy);color:#fff}
.v2 .trust-band-in{max-width:1140px;margin:0 auto;padding:56px 28px;display:grid;grid-template-columns:repeat(4,1fr);gap:28px;text-align:center}
.v2 .trust-band .n{font-family:var(--serif);font-weight:560;font-size:clamp(30px,4vw,46px)}.v2 .trust-band .n .g{background:linear-gradient(100deg,#6e9bff,#4fe0a0);-webkit-background-clip:text;background-clip:text;color:transparent}
.v2 .trust-band .l{color:#9fb0cf;font-size:14px;margin-top:6px}
@media(max-width:900px){
  .v2 .phero{grid-template-columns:1fr;gap:32px}
  .v2 .flist{grid-template-columns:1fr}.v2 .fitem{border-right:none!important;border-bottom:1px solid var(--line);padding:22px 0!important}
  .v2 .cols,.v2 .seats,.v2 .rel{grid-template-columns:1fr}
  .v2 .trust-band-in{grid-template-columns:1fr 1fr;gap:30px 20px}
  .v2 .pt{min-width:560px}.v2 .ptable{overflow-x:auto}
  .v2 .ptiers{grid-template-columns:1fr;max-width:460px;gap:26px}
}

/* V2 editorial — course library (training-courses, university) */
.v2 .lib-controls{max-width:1180px;margin:34px auto 0;padding:0;display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.v2 .lib-search{flex:1;min-width:260px;display:flex;flex-direction:row;align-items:center;gap:11px;background:#fff;border:1.5px solid var(--line-2);border-radius:12px;padding:10px 16px;color:var(--ink-3)}
.v2 .lib-search input{border:none;background:none;font:inherit;font-size:15px;outline:none;flex:1;color:var(--ink)}
/* Below ~640px the search box keeps a mobile-safe min-width (260px) so it
   never overflows a phone viewport; above it, widen so the full placeholder
   (e.g. "Search courses — "confined space", "fleet", "harassment"…") always
   has room to render instead of truncating against the filter chips. */
@media (min-width: 640px) { .v2 .lib-search{min-width:480px} }
.v2 .chips{display:flex;gap:8px;flex-wrap:wrap}
.v2 .chip{border:1.5px solid var(--line-2);background:#fff;border-radius:10px;padding:10px 16px;font-size:14px;font-weight:600;color:var(--ink-2);cursor:pointer}
.v2 .chip.on{background:var(--navy);color:#fff;border-color:var(--navy)}
.v2 .lib-grid{margin-top:28px;display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
.v2 .course{background:#fff;border:1px solid var(--line);border-radius:14px;overflow:hidden;box-shadow:var(--sh-sm);display:flex;flex-direction:column;text-decoration:none;color:inherit;transition:transform .15s,box-shadow .2s}
.v2 .course:hover{transform:translateY(-4px);box-shadow:var(--sh)}
.v2 .course .cov{aspect-ratio:16/9;position:relative;overflow:hidden;background:var(--color-bg-secondary)}
.v2 .course .cov img{width:100%;height:100%;object-fit:cover;display:block}
.v2 .course .cov .cat{position:absolute;top:10px;left:10px;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#fff;background:rgba(10,18,34,.55);border-radius:7px;padding:4px 9px;z-index:2}
.v2 .course .cov .free{position:absolute;top:10px;right:10px;font-size:10.5px;font-weight:800;color:var(--green-d);background:#fff;border-radius:999px;padding:4px 10px;box-shadow:var(--sh-sm);z-index:2}
.v2 .course .cov.c-osha{background:linear-gradient(140deg,#2b55d8,#2db4e6)}.v2 .course .cov.c-fleet{background:linear-gradient(140deg,#0f9d6b,#12b56a)}.v2 .course .cov.c-hr{background:linear-gradient(140deg,#7c5cff,#2457f5)}.v2 .course .cov.c-leadership{background:linear-gradient(140deg,#e88c2a,#f2b544)}
.v2 .course .bd{padding:14px 15px 16px;display:flex;flex-direction:column;gap:12px;flex:1}
.v2 .course .bd h3{font-size:15.5px;font-weight:700;line-height:1.28}
.v2 .course .bd .mt{margin-top:auto;display:flex;align-items:center;justify-content:space-between;color:var(--ink-3);font-size:12.5px}
.v2 .course .bd .start{font-weight:700;color:var(--blue-d)}
.v2 .lib-foot{text-align:center;margin-top:34px}
.v2 .lib-empty{grid-column:1/-1;text-align:center;color:var(--ink-3);padding:40px}
@media(max-width:900px){.v2 .lib-grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.v2 .lib-grid{grid-template-columns:1fr 1fr}}

/* V2 editorial — /resources library hub (keeps the data-lib-* filter contract) */
.v2 .lib-search-label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.v2 .chip.is-active{background:var(--navy);color:#fff;border-color:var(--navy)}
.v2 .chip .lib-filter-count{margin-left:7px;font-size:12px;font-weight:700;opacity:.7}
.v2 .lib-status{max-width:1180px;margin:16px auto 0;color:var(--ink-3);font-size:13.5px;min-height:1em}
.v2 .lib-reset{border:none;background:none;color:var(--blue-d);font:inherit;font-weight:700;cursor:pointer;text-decoration:underline}
.v2 .libgrid{margin-top:24px;display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.v2 .libc{display:flex;flex-direction:column;gap:10px;background:#fff;border:1px solid var(--line);border-radius:14px;padding:22px;text-decoration:none;color:inherit;box-shadow:var(--sh-sm);transition:transform .15s,box-shadow .2s}
.v2 .libc:hover{transform:translateY(-4px);box-shadow:var(--sh)}
.v2 .libc .lm{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.v2 .libc .lt{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--blue-d);background:var(--color-accent-bg);border-radius:7px;padding:4px 9px}
.v2 .libc .lto{font-size:12px;color:var(--ink-3)}
.v2 .libc h3{font-size:17px;font-weight:700;line-height:1.3;color:var(--ink)}
.v2 .libc p{font-size:14px;color:var(--ink-2);line-height:1.55}
@media(max-width:900px){.v2 .libgrid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.v2 .libgrid{grid-template-columns:1fr}}

/* V2 editorial — overrides for pv_* primitives embedded on reflowed product pages
   (/training keeps pv_pill / pv_notification / pv_avatar / pv_certificate because
   their exact class output is assertion-locked; these rules make them read as the
   editorial system rather than the legacy product-visual kit). */
.v2 .pv-pill{display:inline-flex;align-items:center;gap:5px;font-weight:700;font-size:11px;line-height:1;border-radius:7px;padding:5px 9px;letter-spacing:.01em;white-space:nowrap}
.v2 .pv-pill svg{width:12px;height:12px}
.v2 .pv-pill-success{background:var(--green-bg);color:var(--green-d)}
.v2 .pv-pill-danger{background:var(--color-danger-bg);color:var(--color-danger)}
.v2 .pv-pill-warning{background:#fdefd6;color:#a66a00}
.v2 .pv-pill-neutral{background:var(--line);color:var(--ink-3)}
.v2 .pv-notification{display:flex;gap:12px;align-items:flex-start;background:#fff;border:1px solid var(--line);border-radius:12px;padding:13px 15px;margin-bottom:10px}
.v2 .pv-notification-icon{flex:none;width:30px;height:30px;border-radius:8px;display:grid;place-items:center;padding:0}
.v2 .pv-notification-icon svg{width:15px;height:15px}
.v2 .pv-notification-title{font-weight:700;color:var(--ink);display:block;font-size:14.5px}
.v2 .pv-notification-sub{color:var(--ink-3);display:block;font-size:13px;margin-top:2px}
.v2 .pv-notification.sev-neutral .pv-notification-icon{background:var(--line);color:var(--ink-3)}
.v2 .pv-avatar{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;background:var(--color-accent-bg);color:var(--blue-d);font-size:11px;font-weight:800;margin-right:7px;vertical-align:middle}
.v2 .pv-certificate{background:#fff;border:1px solid var(--line);border-radius:16px;padding:30px;text-align:center;box-shadow:var(--sh-sm)}
.v2 .pv-certificate-icon{display:inline-grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--color-accent-bg);color:var(--blue-d);margin-bottom:14px}
.v2 .pv-certificate-title{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.v2 .pv-certificate-name{font-family:var(--serif);font-size:24px;color:var(--ink);margin-top:8px}
.v2 .pv-certificate-course{color:var(--ink-2);margin-top:4px}

/* V2 editorial — auto-generated-action block inside concept cards (.v2) */
.v2 .gen{border-top:1px solid var(--green-hl);background:var(--green-bg)}
.v2 .gen .gh{display:flex;align-items:center;gap:8px;padding:9px 16px;font-size:11.5px;font-weight:700;color:var(--green-d);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.04em}
.v2 .gen .gb{padding:0 16px 14px;display:flex;align-items:center;gap:12px}
.v2 .gen .gb .av{width:30px;height:30px;border-radius:50%;background:var(--gradh);color:#fff;display:grid;place-items:center;font-size:12px;font-weight:700;flex:none}
.v2 .gen .gb .t .a{font-weight:700;font-size:14.5px}
.v2 .gen .gb .t .m{font-size:12px;color:var(--ink-2)}

/* V2 editorial — /courses/{slug} course-detail pages */
.v2 .crumb{font-size:13px;color:var(--ink-3)}
.v2 .crumb a{color:var(--ink-3);text-decoration:none}
.v2 .crumb a:hover{color:var(--blue-d)}
.v2 .crumb span{margin:0 6px;color:var(--line-2)}
.v2 .cmeta{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center;margin-top:16px}
.v2 .cmeta-i{display:inline-flex;align-items:center;gap:6px;font-size:13.5px;color:var(--ink-2);font-weight:600}
.v2 .cmeta-free{font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--green-d);background:var(--green-bg);border-radius:999px;padding:4px 11px}
.v2 .ccover{aspect-ratio:16/9;border-radius:16px;overflow:hidden;box-shadow:var(--sh-lg);position:relative;display:flex;flex-direction:column;justify-content:flex-end;padding:22px;color:#fff}
.v2 .ccover img{width:100%;height:100%;object-fit:cover;display:block;border-radius:16px}
.v2 .ccover.c-osha{background:linear-gradient(140deg,#2b55d8,#2db4e6)}
.v2 .ccover.c-fleet{background:linear-gradient(140deg,#0f9d6b,#12b56a)}
.v2 .ccover.c-hr{background:linear-gradient(140deg,#7c5cff,#2457f5)}
.v2 .ccover.c-leadership{background:linear-gradient(140deg,#e88c2a,#f2b544)}
.v2 .ccover-cat{font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;opacity:.85}
.v2 .ccover-t{font-family:var(--serif);font-size:24px;margin-top:6px;line-height:1.15}
.v2 .crefs{list-style:none;padding:0;margin:0;max-width:760px;display:flex;flex-direction:column;gap:10px}
.v2 .crefs li{padding:14px 16px;background:#fff;border:1px solid var(--line);border-radius:12px;font-size:14.5px}
.v2 .crefs a{color:var(--blue-d);font-weight:600;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
.v2 .crefs a:hover{text-decoration:underline}
.v2 .cnote{max-width:760px;margin-top:18px;font-size:13.5px;color:var(--ink-3)}

/* ===== LMS Lite self-serve signup modal (site-wide, opened by [data-signup]) ===== */
.sg-overlay{position:fixed;inset:0;z-index:1000;background:rgba(11,27,51,.55);display:flex;align-items:center;justify-content:center;padding:20px;overflow-y:auto}
.sg-overlay[hidden]{display:none}
.sg-card{position:relative;background:#fff;border-radius:18px;box-shadow:0 30px 80px rgba(11,27,51,.3);width:100%;max-width:440px;padding:30px 30px 26px;animation:sgIn .22s ease}
@keyframes sgIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.sg-close{position:absolute;top:14px;right:14px;width:34px;height:34px;border:none;background:none;color:var(--color-text-muted,#6b7a93);border-radius:9px;cursor:pointer;display:grid;place-items:center}
.sg-close:hover{background:var(--color-bg-secondary,#f3f5f9);color:var(--color-text,#0d1726)}
.sg-head{text-align:center;margin-bottom:20px}
.sg-kick{font-size:11.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--green-d,#0a8c51)}
.sg-title{font-family:var(--font-serif,Georgia,serif);font-weight:560;font-size:28px;line-height:1.1;color:var(--ink,#0d1726);margin:8px 0 0}
.sg-sub{font-size:14px;color:var(--ink-3,#6b7a93);margin:8px 0 0;line-height:1.5}
.sg-roles{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:18px}
.sg-role{text-align:left;border:1.5px solid var(--line-2,#d3deed);background:#fff;border-radius:12px;padding:12px 14px;cursor:pointer;display:flex;flex-direction:column;gap:3px;transition:border-color .12s,background .12s}
.sg-role:hover{border-color:var(--blue,#2457f5)}
.sg-role.is-on{border-color:var(--blue,#2457f5);background:var(--color-accent-bg,#eef3ff)}
.sg-role-t{font-weight:700;font-size:14.5px;color:var(--ink,#0d1726)}
.sg-role-s{font-size:11.5px;color:var(--ink-3,#6b7a93);line-height:1.35}
.sg-form{display:flex;flex-direction:column;gap:13px}
.sg-field{display:flex;flex-direction:column;gap:5px}
.sg-field[hidden]{display:none}
.sg-field label{font-size:12.5px;font-weight:700;color:var(--ink-2,#44536a)}
.sg-field input{border:1.5px solid var(--line-2,#d3deed);border-radius:10px;padding:11px 13px;font:inherit;font-size:15px;color:var(--ink,#0d1726);outline:none}
.sg-field input:focus{border-color:var(--blue,#2457f5);box-shadow:0 0 0 3px rgba(36,87,245,.15)}
.sg-field.has-err input{border-color:var(--color-danger,#e5484d)}
.sg-err{font-size:12px;color:var(--color-danger,#e5484d)}
.sg-err:empty{display:none}
.sg-cf{display:flex;justify-content:center;margin:2px 0}
.sg-general{font-size:13px;color:var(--color-danger,#e5484d);text-align:center}
.sg-general:empty{display:none}
.sg-submit{margin-top:4px;display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--navy,#0b1b33);color:#fff;border:none;border-radius:12px;padding:14px 18px;font:inherit;font-weight:700;font-size:15px;cursor:pointer}
.sg-submit:hover{background:#13284a}
.sg-submit:disabled{opacity:.65;cursor:default}
.sg-consent{font-size:11.5px;color:var(--ink-3,#6b7a93);text-align:center;line-height:1.5;margin:2px 0 0}
.sg-consent a{color:var(--blue-d,#1a3fc0);text-decoration:underline}
@media(max-width:460px){.sg-card{padding:26px 20px 22px}.sg-roles{grid-template-columns:1fr}}

/* ===== utilities.css ===== */
/**
 * Small, single-purpose utility classes — spacing/visibility overrides that
 * don't warrant a named component. Reach for a component class first;
 * these are for the last-mile adjustment.
 */

.mt-0 { margin-top: 0; }
.mt-2 { margin-top: var(--space-2); }
.mt-4 { margin-top: var(--space-4); }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }
.mt-12 { margin-top: var(--space-12); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-6 { margin-bottom: var(--space-6); }
.mb-8 { margin-bottom: var(--space-8); }
.mb-12 { margin-bottom: var(--space-12); }

.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }

.section-intro {
  max-width: 620px;
  margin-bottom: var(--space-12);
}

.section-intro.text-center {
  margin-inline: auto;
}

.section-intro .text-eyebrow {
  display: block;
  margin-bottom: var(--space-3);
}

.section-intro h2 {
  margin-bottom: var(--space-4);
}

.hide-mobile {
  display: none;
}

@media (min-width: 768px) {
  .hide-mobile {
    display: initial;
  }
}

/* .hide-mobile's `display: initial` resolves to `inline`, which is fine for
 * a plain link — but a `.btn` needs `inline-flex` to keep its icon+label on
 * one line, and if the button is a flex item (e.g. inside .flex-between),
 * `inline` gets "blockified" to `block` per the CSS Display spec, breaking
 * the flex layout entirely and dropping the icon to its own line. Higher
 * specificity here (.btn.hide-mobile) wins over the plain rule above
 * regardless of source order. */
@media (min-width: 768px) {
  .btn.hide-mobile {
    display: inline-flex;
  }
}

.hide-desktop {
  display: initial;
}

@media (min-width: 768px) {
  .hide-desktop {
    display: none;
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link — keyboard accessibility, hidden until focused */
.skip-link {
  position: absolute;
  top: -48px;
  left: var(--space-4);
  z-index: 100;
  background: var(--color-accent);
  color: #fff;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  font-weight: 600;
  transition: top var(--duration-fast) var(--ease-out);
}

.skip-link:focus {
  top: var(--space-4);
}

/* ---------- Above-the-fold entrance (no JavaScript) ----------
 * Hero blocks must be readable the instant CSS applies, so they are never
 * opacity-gated: .reveal below starts at opacity 0 and only becomes visible
 * when site.js runs its IntersectionObserver, which would both delay LCP and
 * leave the hero blank if the script fails. This entrance animates transform
 * only, runs off a CSS keyframe rather than a class added by script, and
 * leaves the content fully opaque from first paint.
 */
.hero-enter {
  animation: hero-enter var(--duration-slow) var(--ease-out) both;
}

.hero-enter-delay {
  animation-delay: 120ms;
}

@keyframes hero-enter {
  from { transform: translateY(16px); }
  to   { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-enter {
    animation: none;
  }
}

/* ---------- Reveal entrance (opt-in; never gates visibility) ----------
 * Content is VISIBLE BY DEFAULT — with JavaScript disabled, for crawlers and link
 * previews, under prefers-reduced-motion, and before any scroll. The hidden-then-
 * reveal state applies ONLY when the synchronous <head> guard added `html.reveal-on`
 * (JS running AND motion allowed). site.js then plays the entrance on load (not gated
 * on scroll position) with an absolute failsafe, so nothing is ever left hidden. */
.reveal {
  opacity: 1;
  transform: none;
}

html.reveal-on .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--duration-slow) var(--ease-out), transform var(--duration-slow) var(--ease-out);
  will-change: opacity, transform;
}

html.reveal-on .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Belt-and-suspenders: even if reveal-on were set, reduced-motion stays fully visible. */
@media (prefers-reduced-motion: reduce) {
  html.reveal-on .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
