/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * theme.css: L1 component stylesheet for the Clinical design (ADR-00002).
 *
 * The single source of the look, together with tokens.css. Every rule here is
 * authored against the L0 custom properties (--color-*, --type-*, --space-*,
 * --r-*, --shadow-*); no colour, size, or font is hard-coded. Because all
 * design lives here, the per-format templates carry only semantic class names
 * and the engine's own loops: no Tailwind, no inline styles, no drift.
 *
 * Load order in every adapter: tokens.css, then theme.css.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

/* ============================================================
   1. RESET + DOCUMENT
   ============================================================ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

/* The browser's own [hidden] rule is a bare attribute selector, so any class
   that sets `display` beats it. Components here set display:grid and display:flex
   all over, which would silently defeat every hidden toggle in js/. Restate it
   with !important once, centrally, so `el.hidden = true` always means hidden. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--type-family_sans);
  font-weight: var(--type-weight-normal);
  font-size: var(--type-scale-base);
  line-height: var(--type-leading-normal);
  letter-spacing: -0.011em;
  color: var(--color-text-primary);
  background: var(--color-bg-page);
  /* clip, not hidden: `overflow-x: hidden` on a scroll container silently breaks
     position:sticky in Safari and older Chromium, which the molecule scene needs. */
  overflow-x: clip;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }
ul, ol { list-style: none; }
h1, h2, h3, h4, h5, h6 { color: var(--color-text-primary); }

h1, h2 {
  font-weight: var(--type-weight-bold);
  letter-spacing: -0.03em;
  line-height: var(--type-leading-tight);
}
h3, h4, h5, h6 {
  font-weight: var(--type-weight-semibold);
  letter-spacing: -0.02em;
  line-height: var(--type-leading-snug);
}
.font-mono { font-family: var(--type-family_mono); }

/* ============================================================
   2. LAYOUT PRIMITIVES  (semantic, replace Tailwind utilities)
   ============================================================ */
.container { width: 100%; max-width: 80rem; margin-inline: auto; padding-inline: 1.5rem; }
.container--narrow { max-width: 48rem; }
.container--wide  { max-width: 90rem; }

.section { padding-block: 5rem; }
.section--tight { padding-block: 3rem; }
.section--flush { padding-block: 0; }

.stack > * + * { margin-top: var(--stack-gap, 1rem); }
.stack--sm { --stack-gap: 0.5rem; }
.stack--lg { --stack-gap: 1.5rem; }
.stack--xl { --stack-gap: 2.5rem; }

.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cluster-gap, 0.75rem); }
.cluster--between { justify-content: space-between; }
.cluster--center { justify-content: center; }

.grid { display: grid; gap: 1.5rem; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--auto { grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); }
/* Auto-fitting variant: an N-item set with no exact divisor spreads to fill the
   row rather than leaving a blank trailing cell. */
.grid--fit { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
@media (max-width: 1024px) { .grid--4 { grid-template-columns: repeat(2, 1fr); } .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; } }

.center-text { text-align: center; }
.measure { max-width: 42rem; }
.measure-wide { max-width: 56rem; }
.mx-auto { margin-inline: auto; }

/* ============================================================
   3. TYPOGRAPHY ROLES
   ============================================================ */
.eyebrow {
  display: inline-block;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-brand-primary);
}
.display { font-size: var(--type-scale-5xl); line-height: 1.05; letter-spacing: -0.035em; font-weight: var(--type-weight-bold); }
.h1 { font-size: var(--type-scale-4xl); }
.h2 { font-size: var(--type-scale-3xl); }
.h3 { font-size: var(--type-scale-2xl); }
.h4 { font-size: var(--type-scale-xl); font-weight: var(--type-weight-semibold); }
.lead { font-size: var(--type-scale-lg); color: var(--color-text-secondary); line-height: 1.55; }
.meta { font-size: var(--type-scale-sm); color: var(--color-text-tertiary); }
.section-label {
  font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold);
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--color-text-secondary);
}
.section-desc { color: var(--color-text-secondary); }

@media (max-width: 768px) {
  .display { font-size: var(--type-scale-4xl); }
  .h1 { font-size: var(--type-scale-3xl); }
  .h2 { font-size: var(--type-scale-2xl); }
}

.text-muted { color: var(--color-text-secondary); }
.text-brand { color: var(--color-brand-primary); }
.text-mono  { font-family: var(--type-family_mono); }

/* ============================================================
   4. BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.875rem 2rem;
  font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold);
  letter-spacing: -0.01em;
  border: 1px solid transparent; border-radius: var(--r-sm);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn svg { width: 1rem; height: 1rem; }
.btn--primary { background: var(--color-brand-primary); color: #fff; border-color: var(--color-brand-primary); }
.btn--primary:hover { background: var(--color-brand-accent_interactive); border-color: var(--color-brand-accent_interactive); }
.btn--secondary { background: transparent; color: var(--color-text-primary); border-color: var(--color-border-medium); }
.btn--secondary:hover { border-color: var(--color-brand-primary); color: var(--color-brand-primary); }
.btn--sm { padding: 0.5rem 1rem; font-size: var(--type-scale-xs); }

/* On a dark / hero background */
.btn--on-dark { background: #fff; color: var(--color-brand-primary); border-color: #fff; }
.btn--on-dark:hover { background: var(--color-brand-primary); color: #fff; border-color: var(--color-brand-primary); }
.btn--ghost-dark { background: transparent; color: #fff; border-color: rgba(255,255,255,0.4); }
.btn--ghost-dark:hover { background: rgba(255,255,255,0.12); border-color: #fff; }

/* The secondary button is an outline in ink on light backgrounds, which
   disappears on a dark band. Restate it for dark surroundings. */
.tone-dark .btn--secondary, .page-hero .btn--secondary, .hero .btn--secondary, .portal .btn--secondary {
  color: #fff; border-color: rgba(255, 255, 255, 0.45); background: transparent;
}
.tone-dark .btn--secondary:hover, .page-hero .btn--secondary:hover,
.hero .btn--secondary:hover, .portal .btn--secondary:hover {
  color: #fff; background: rgba(255, 255, 255, 0.14); border-color: #fff;
}
.tone-dark .text-link { color: var(--color-brand-accent_spark); }

.text-link { color: var(--color-brand-primary); font-weight: var(--type-weight-semibold); font-size: var(--type-scale-sm); transition: color var(--dur) var(--ease); }
.text-link:hover { color: var(--color-brand-accent_interactive); }

/* ============================================================
   5. SITE NAV  (transparent over hero, frosts on scroll)
   ============================================================ */
.site-nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  background: transparent;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.site-nav__inner { display: flex; align-items: center; justify-content: space-between; height: 4rem; }
.site-nav.is-scrolled {
  background: color-mix(in srgb, var(--color-bg-page) 92%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 1px 0 var(--color-border-subtle);
}
.site-nav__brand { display: inline-flex; align-items: center; height: 2.25rem; }
.site-nav__brand svg, .site-nav__brand img { height: 2rem; width: auto; }
/* The wordmark is referenced with <img>, so its internal currentColor resolves
   against the SVG document, not this page. On a dark hero that renders it almost
   black. Invert it to white while the nav is over dark artwork, and let it go
   back to its own ink once the bar frosts over the page background. */
.site-nav.is-dark .site-nav__brand img { filter: brightness(0) invert(1); }
/* The rule above covers a dark section scrolling under the bar. Dark MODE is a
   separate axis: the bar is dark there too, so the mark needs inverting again.
   The footer reuses .site-nav__brand for the same mark, so one selector serves
   both places. */
:root[data-theme="dark"] .site-nav__brand img { filter: brightness(0) invert(1); }
.site-nav.is-frost .site-nav__brand img,
.site-nav.is-solid .site-nav__brand img { filter: none; }
/* The two rules above clear the filter for a nav sitting on a light page, and in
   dark mode nav.js still applies is-frost/is-solid on scroll. At equal
   specificity they would win on source order and leave a dark mark on the dark
   bar, so dark mode has to restate the inversion for those states. */
:root[data-theme="dark"] .site-nav.is-frost .site-nav__brand img,
:root[data-theme="dark"] .site-nav.is-solid .site-nav__brand img { filter: brightness(0) invert(1); }
.site-nav__brand img { transition: filter var(--dur) var(--ease); }
.site-nav__links { display: flex; align-items: center; gap: 0.25rem; }
@media (max-width: 1023px) { .site-nav__links { display: none; } }

.nav-link {
  position: relative; padding: 0.5rem 1rem;
  font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); letter-spacing: -0.01em;
  color: #fff; transition: color var(--dur) var(--ease);
}
.nav-link:hover { color: var(--color-brand-primary); }

/* Colour states set by nav.js (not inline styles), so :hover can win */
.site-nav.is-dark   .nav-link { color: #fff; }
.site-nav.is-frost  .nav-link { color: var(--color-brand-secondary); }
.site-nav.is-solid  .nav-link { color: var(--color-text-primary); }
.site-nav.is-dark   .nav-link:hover,
.site-nav.is-frost  .nav-link:hover,
.site-nav.is-solid  .nav-link:hover { color: var(--color-brand-primary); }

/* Dropdown */
.dropdown { position: relative; }
.dropdown__panel {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  padding-top: 0.5rem; min-width: 14rem;
  background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-sm); box-shadow: var(--shadow-md);
  display: none; pointer-events: none;
}
.dropdown:hover .dropdown__panel, .dropdown__panel.is-open { display: block; pointer-events: auto; }
/* Escape has to win over :hover. Without this the panel stays visible while the
   pointer rests on it, so dismissing by keyboard appears to do nothing. The
   flag is cleared on mouseleave, so hover works normally again afterwards. */
.dropdown.is-dismissed:hover .dropdown__panel { display: none; }
.dropdown__panel a {
  display: block; padding: 0.75rem 1rem;
  font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium);
  color: var(--color-text-primary); transition: background var(--dur), color var(--dur);
}
.dropdown__panel a:hover { background: var(--color-bg-subtle); color: var(--color-brand-primary); }

/* Portal / ghost CTA in the nav */
.btn-portal {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.4375rem 1rem;
  font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); letter-spacing: -0.01em;
  color: #fff; background: transparent;
  border: 1px solid rgba(255,255,255,0.45); border-radius: var(--r-sm);
  transition: color var(--dur), border-color var(--dur), background var(--dur);
}
.btn-portal svg { width: 0.8125rem; height: 0.8125rem; }
.site-nav.is-frost .btn-portal { color: var(--color-brand-secondary); border-color: var(--color-brand-secondary); }
.site-nav.is-solid .btn-portal { color: var(--color-brand-primary); border-color: var(--color-brand-primary); }
.btn-portal:hover { color: #fff; background: var(--color-brand-primary); border-color: var(--color-brand-primary); }

/* Hamburger */
.nav-toggle { display: none; padding: 0.5rem; }
@media (max-width: 1023px) { .nav-toggle { display: inline-flex; } }
.hamburger { width: 24px; height: 18px; position: relative; }
.hamburger span { position: absolute; left: 0; width: 100%; height: 2px; background: currentColor; border-radius: 1px; transition: transform 0.3s var(--ease), opacity 0.3s var(--ease); }
.hamburger span:nth-child(1) { top: 0; }
.hamburger span:nth-child(2) { top: 8px; }
.hamburger span:nth-child(3) { top: 16px; }
.hamburger.is-active span:nth-child(1) { top: 8px; transform: rotate(45deg); }
.hamburger.is-active span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.hamburger.is-active span:nth-child(3) { top: 8px; transform: rotate(-45deg); }

/* ============================================================
   6. MOBILE DRAWER
   ============================================================ */
.drawer {
  position: fixed; inset: 0; z-index: 100;
  background: var(--color-brand-secondary);
  opacity: 0; visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s var(--ease);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.drawer.is-open { opacity: 1; visibility: visible; }
@media (min-width: 1024px) { .drawer { display: none !important; } }
.drawer__inner { min-height: 100vh; display: flex; flex-direction: column; }
.drawer__head { display: flex; justify-content: flex-end; padding: 1.5rem; }
.drawer__close { color: rgba(255,255,255,0.6); padding: 0.5rem; transition: color var(--dur); }
.drawer__close:hover { color: #fff; }
.drawer__body { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 2rem; padding: 2rem 2.5rem 3rem; }
.drawer__group { display: flex; flex-direction: column; gap: 0.25rem; }
.drawer__label {
  font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold);
  text-transform: uppercase; letter-spacing: 0.1em; color: rgba(255,255,255,0.35);
  padding-bottom: 0.75rem; border-bottom: 1px solid rgba(255,255,255,0.08);
}
.drawer__link { display: block; font-size: var(--type-scale-lg); font-weight: var(--type-weight-medium); color: rgba(255,255,255,0.85); padding: 0.625rem 0; transition: color var(--dur), transform var(--dur); }
.drawer__link:hover { color: #fff; transform: translateX(4px); }
.drawer__divider { height: 1px; background: rgba(255,255,255,0.08); }
.drawer__cta { display: inline-flex; align-items: center; gap: 0.5rem; align-self: flex-start; font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold); color: #fff; padding: 0.75rem 1.5rem; border: 1px solid rgba(255,255,255,0.25); border-radius: var(--r-sm); transition: background var(--dur), border-color var(--dur); }
.drawer__cta:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.4); }

/* ============================================================
   7. HERO
   ============================================================ */
.hero {
  position: relative; min-height: 100vh;
  display: flex; align-items: center;
  overflow: hidden; color: #fff;
  background:
    radial-gradient(120% 90% at 78% 18%, color-mix(in srgb, var(--color-brand-primary) 42%, transparent) 0%, transparent 58%),
    radial-gradient(90% 70% at 12% 88%, color-mix(in srgb, var(--color-brand-accent_spark) 20%, transparent) 0%, transparent 60%),
    linear-gradient(155deg, var(--color-brand-secondary) 0%, var(--color-brand-secondary_2) 45%, var(--color-brand-dark) 100%);
}
/* A faint engineering grid. It gives the flat gradient something to sit on and
   reads as instrumentation rather than decoration. */
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
  background-size: 76px 76px;
  mask-image: radial-gradient(120% 80% at 50% 40%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 80% at 50% 40%, #000 20%, transparent 78%);
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media video, .hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero__bg { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; display: block; }
.hero__video { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; }
.hero__overlay { position: absolute; inset: 0; z-index: 1; background: radial-gradient(120% 100% at 30% 20%, transparent 0%, rgba(11,21,32,0.35) 70%); }

/* Status pill */
.hero__badge { display: inline-flex; align-items: center; gap: 0.5rem; align-self: flex-start; padding: 0.4rem 0.9rem; font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.9); background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.22); border-radius: var(--r-pill); }
.hero__badge-dot { width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: var(--color-brand-accent_spark); box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand-accent_spark) 70%, transparent); animation: badge-pulse 2.4s var(--ease) infinite; }
@keyframes badge-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand-accent_spark) 60%, transparent); } 70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }

/* Scroll cue */
.hero__scroll { position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%); z-index: 2; }
.hero__scroll-track { display: block; width: 1.35rem; height: 2.15rem; border: 2px solid rgba(255,255,255,0.35); border-radius: var(--r-pill); padding-top: 0.35rem; }
.hero__scroll-dot { display: block; width: 0.28rem; height: 0.45rem; margin: 0 auto; border-radius: var(--r-pill); background: rgba(255,255,255,0.75); animation: scroll-bob 1.7s var(--ease) infinite; }
@keyframes scroll-bob { 0%,100% { transform: translateY(0); opacity: 0.4; } 50% { transform: translateY(6px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .hero__badge-dot, .hero__scroll-dot { animation: none; } }
.hero .container { position: relative; z-index: 2; padding-block: 8rem 5rem; }
.hero h1 { color: #fff; }
.hero__kicker { color: var(--color-brand-accent_spark); }
.hero__title {
  font-size: clamp(2.6rem, 6.2vw, 4.4rem);
  line-height: 1.02; letter-spacing: -0.038em; max-width: 17ch;
  text-wrap: balance;
}
.hero__lead { color: rgba(255,255,255,0.76); font-size: var(--type-scale-lg); max-width: 48ch; line-height: 1.6; }

/* Figures pinned under the hero copy. Cheap credibility, and it fills the
   dead space a pure gradient leaves at the bottom of a 100vh block. */
.hero__stats {
  display: flex; flex-wrap: wrap; gap: 2.5rem;
  margin-top: 3.5rem; padding-top: 2rem;
  border-top: 1px solid rgba(255,255,255,0.14);
}
.hero__stat-value {
  font-family: var(--type-family_mono); font-size: var(--type-scale-2xl);
  font-weight: var(--type-weight-bold); color: #fff; line-height: 1;
}
/* On the dark hero the stat figures must be light, not brand-green (which is
   near-invisible on navy). The accent spark reads as an on-brand highlight. */
.hero__stats .stat { color: var(--color-brand-accent_spark); }
.hero__stat-label {
  margin-top: 0.375rem; font-size: var(--type-scale-xs);
  text-transform: uppercase; letter-spacing: 0.1em; color: rgba(255,255,255,0.55);
}

/* ---- Globe ---- */
.globe-frame { display: grid; place-items: center; position: relative; }
.globe { width: 100%; max-width: 34rem; display: block; cursor: grab; }
.globe-labels { position: absolute; inset: 0; pointer-events: none; }
.globe-label {
  position: absolute; left: 0; top: 0; white-space: nowrap;
  font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold);
  color: var(--color-text-primary); background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle); border-radius: var(--r-pill);
  padding: 0.15rem 0.6rem; box-shadow: var(--shadow-sm);
  transition: opacity 0.4s var(--ease);
}

/* Scroll scene: molecule.js adds this when it drives the section. The section
   grows tall and its container sticks, so the crossfade plays while the page
   scrolls, with no fixed positioning anywhere. */
.molecular.is-scroll-scene { min-height: 250vh; }
.molecular.is-scroll-scene > .container { position: sticky; top: 4.5rem; }

/* ---- Molecular viewer ----
   The narrative cards are stacked one on top of another (the source design) and
   crossfade in place as the pinned section scrolls (js/molecule.js). */
.molecular__stage { display: grid; place-items: center; }
.molecule { width: 100%; max-width: 30rem; display: block; }
.molecular__cards { position: relative; z-index: 2; }
.narrative-card-stack { position: relative; min-height: 15rem; }
.narrative-card {
  position: absolute; inset: 0;
  padding: 1.75rem;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-left: 3px solid var(--color-brand-primary);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  will-change: opacity, transform;
  /* Stacked cards crossfade in place. Opacity alone still paints the hidden
     cards, so their text bleeds through the visible one; visibility takes them
     out of the paint and out of the accessibility tree. */
  visibility: hidden;
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility 0s linear .28s;
}
.narrative-card.is-active {
  visibility: visible;
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility 0s;
}
.narrative-card > * + * { margin-top: 0.5rem; }
/* Before JS runs (or with it off) show cards in flow so nothing is blank. */
html:not(.js) .narrative-card-stack .narrative-card { position: relative; inset: auto; opacity: 1; visibility: visible; }
html:not(.js) .narrative-card + .narrative-card { margin-top: 1rem; }
@media (max-width: 1024px) {
  .narrative-card-stack { min-height: 0; }
  .narrative-card { position: relative; inset: auto; opacity: 1 !important; transform: none !important; visibility: visible !important; }
  .narrative-card + .narrative-card { margin-top: 1rem; }
}

/* Regulatory ribbon: a continuous marquee of credentials. Two identical tracks
   sit side by side and translate left by exactly one track width, so the loop is
   seamless. Pauses on hover. Holds still under prefers-reduced-motion. */
.ribbon { background: var(--color-brand-secondary); color: var(--color-text-on_dark_soft); padding-block: 0.875rem; overflow: hidden; }
.ribbon__viewport { display: flex; width: max-content; animation: ribbon-scroll 32s linear infinite; }
.ribbon:hover .ribbon__viewport { animation-play-state: paused; }
.ribbon__track { display: flex; align-items: center; gap: 2.5rem; padding-right: 2.5rem; white-space: nowrap; font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); letter-spacing: 0.01em; }
.ribbon__track span { display: inline-flex; align-items: center; gap: 2.5rem; }
.ribbon__track span::after { content: '\2022'; color: var(--color-brand-accent_spark); opacity: 0.75; }
@keyframes ribbon-scroll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ribbon__viewport { animation: none; } }

/* Interactive development pipeline: one row per programme, a phase-progress bar,
   and a detail panel that expands on hover/focus. Mirrors the source data table. */
.pipeline-table { border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); overflow: hidden; background: var(--color-bg-surface); }
.pipeline-row { display: grid; grid-template-columns: 6.5rem 1fr 6rem 6.5rem 1.4fr; gap: 1rem; align-items: center; padding: 1.15rem 1.5rem; border-bottom: 1px solid var(--color-border-subtle); transition: background var(--dur); }
.pipeline-row:last-of-type { border-bottom: none; }
.pipeline-row:hover, .pipeline-row:focus-within { background: color-mix(in srgb, var(--color-brand-primary) 4%, transparent); }
.pipeline-row__id { font-family: var(--type-family_mono); font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold); color: var(--color-brand-secondary); }
.pipeline-row__target { font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); }
.pipeline-row__phase { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); color: var(--color-text-secondary); }
.pipeline-row__status { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--type-scale-xs); color: var(--color-text-secondary); }
.pipeline-row__status .dot { width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: var(--color-border-medium); }
.pipeline-row__status.is-active .dot { background: var(--color-brand-primary); }
.pipeline-row__status.is-enrolling .dot { background: var(--color-status-info); }
.phase-bar { height: 0.4rem; border-radius: var(--r-pill); background: var(--color-bg-sunken); overflow: hidden; }
.phase-bar__fill { height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--color-brand-primary), var(--color-brand-accent_interactive)); transition: width 0.9s var(--ease); }
.pipeline-row__detail { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; grid-column: 1 / -1; max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.35s var(--ease), opacity 0.25s var(--ease), margin 0.35s var(--ease); }
.pipeline-row:hover .pipeline-row__detail, .pipeline-row:focus-within .pipeline-row__detail { max-height: 12rem; opacity: 1; margin-top: 1rem; }
.pipeline-row__detail dt { font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); margin-bottom: 0.25rem; }
.pipeline-row__detail dd { font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
@media (max-width: 860px) {
  .pipeline-row { grid-template-columns: 1fr 1fr; gap: 0.5rem 1rem; }
  .pipeline-row__bar-cell { grid-column: 1 / -1; }
  .pipeline-row__detail { grid-template-columns: 1fr; }
}

/* Strategic partnering: narrative + bullet points on the left, a 2x2 metric
   grid on the right (the source layout, not leadership photos). */
.partnering__points { display: flex; flex-direction: column; gap: 0.75rem; }
.partnering__point { display: flex; align-items: center; gap: 0.75rem; font-size: var(--type-scale-base); color: var(--color-text-primary); }
.partnering__dot { flex: none; width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: var(--color-brand-primary); }
.partner-metric-card { text-align: center; padding: 1.75rem 1.25rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); transition: border-color var(--dur), box-shadow var(--dur); }
.partner-metric-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.partner-metric-card__label { margin-top: 0.5rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }

/* KPI dashboard extensions: progress bar + status legend under a wide metric */
.metric-card--wide { text-align: left; }
.progress-track { height: 0.5rem; margin-top: 1.1rem; border-radius: var(--r-pill); background: var(--color-bg-sunken); overflow: hidden; }
.progress-fill { height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--color-brand-primary), var(--color-brand-accent_interactive)); transition: width 1.2s var(--ease); }
.kpi-legend { display: flex; flex-wrap: wrap; gap: 1.25rem; margin-top: 1.1rem; }
.kpi-legend span { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
.kpi-legend .dot { width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: var(--color-border-medium); }
.kpi-legend .dot--active { background: var(--color-brand-primary); }
.kpi-legend .dot--enrolling { background: var(--color-status-info); }

/* Feature blocks (strategic initiatives) */
.feature-card { padding: 2rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-top: 3px solid var(--color-brand-primary); border-radius: var(--r-md); transition: border-color var(--dur), box-shadow var(--dur); }
.feature-card:hover { box-shadow: var(--shadow-md); }

/* Featured briefing: dark banner card with a decorative brand panel */
.featured-briefing { display: grid; grid-template-columns: 3fr 2fr; border-radius: var(--r-lg); overflow: hidden; background: linear-gradient(160deg, var(--color-brand-secondary), var(--color-brand-secondary_2)); color: rgba(255,255,255,0.8); box-shadow: var(--shadow-lg); }
.featured-briefing__body { padding: 2.5rem; }
.featured-briefing__body h3 { color: #fff; }
.featured-briefing__date { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); color: rgba(255,255,255,0.55); }
.featured-briefing__excerpt { color: rgba(255,255,255,0.75); }
.featured-briefing__art { background: radial-gradient(120% 100% at 70% 30%, color-mix(in srgb, var(--color-brand-primary) 55%, transparent) 0%, transparent 65%), linear-gradient(200deg, var(--color-brand-dark), var(--color-brand-secondary)); position: relative; min-height: 14rem; }
.featured-briefing__art::before { content: ''; position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px); background-size: 44px 44px; }
.badge--spark { background: color-mix(in srgb, var(--color-brand-accent_spark) 18%, transparent); color: var(--color-brand-accent_spark); }
@media (max-width: 860px) { .featured-briefing { grid-template-columns: 1fr; } .featured-briefing__art { min-height: 8rem; } }

/* Intelligence feed rows */
.feed-grid { margin-top: 1.25rem; }
.feed-row { grid-template-columns: 7.5rem 9rem 1fr auto; }
.feed-row__title { font-weight: var(--type-weight-medium); }
@media (max-width: 768px) { .feed-row { grid-template-columns: 1fr auto; } .feed-row .mono-id { grid-column: 1 / -1; } }

/* News & insights cards */
.post-card { display: flex; flex-direction: column; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); overflow: hidden; transition: border-color var(--dur), box-shadow var(--dur), transform var(--dur); }
.post-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-md); transform: translateY(-3px); }
.post-card__band { height: 0.4rem; background: linear-gradient(90deg, var(--color-brand-primary), var(--color-brand-accent_spark)); }
.post-card__body { padding: 1.5rem; display: flex; flex-direction: column; gap: 0.625rem; flex: 1; }
.post-card__tag { align-self: flex-start; font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-brand-primary); }
.post-card__title { font-size: var(--type-scale-lg); font-weight: var(--type-weight-semibold); line-height: 1.3; }
.post-card__excerpt { font-size: var(--type-scale-sm); color: var(--color-text-secondary); flex: 1; }
.post-card__meta { font-size: var(--type-scale-xs); color: var(--color-text-tertiary); font-family: var(--type-family_mono); }

/* ============================================================
   8. CARDS  (dashboard / news / capability / metric)
   ============================================================ */
.card { background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); transition: border-color var(--dur), box-shadow var(--dur); }
.card:hover { border-color: var(--color-border-medium); }
.card--pad { padding: 1.5rem; }
.card--lift:hover { box-shadow: var(--shadow-md); }

/* Numbers get a dedicated treatment: monospaced, tabular figures so digits
   align, tight tracking, and a size that carries a section on its own. This is
   the single most repeated element in a data-heavy pharma site, so it earns it. */
.stat { font-family: var(--type-family_mono); font-weight: var(--type-weight-bold); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; line-height: 0.95; color: var(--color-brand-primary); }
.stat--xl { font-size: clamp(2.5rem, 4.5vw, 3.75rem); }
.stat--lg { font-size: clamp(2rem, 3.2vw, 2.75rem); }

.metric-card { background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); padding: 1.75rem 1.5rem; transition: border-color var(--dur), box-shadow var(--dur); }
.metric-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.metric-card__eyebrow { font-size: var(--type-scale-xs); font-weight: var(--type-weight-medium); text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-text-tertiary); margin-bottom: 0.875rem; }
.metric-card__value { font-family: var(--type-family_mono); font-weight: var(--type-weight-bold); font-variant-numeric: tabular-nums; font-size: clamp(2.25rem, 3.5vw, 3rem); color: var(--color-brand-primary); line-height: 0.95; letter-spacing: -0.02em; }
.metric-card__label { margin-top: 0.625rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }

/* Capability card: the icon sits on the same baseline as the heading, in a row,
   not floating in dead space above it. This is the layout the source used and
   the one that reads as intentional. */
.capability-card { display: flex; gap: 1rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); padding: 1.5rem; transition: border-color var(--dur), box-shadow var(--dur), transform var(--dur); }
.capability-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.capability-card__icon { flex: none; width: 2.75rem; height: 2.75rem; display: grid; place-items: center; border-radius: var(--r-sm); background: color-mix(in srgb, var(--color-brand-primary) 9%, transparent); color: var(--color-brand-primary); }
.capability-card__icon svg { width: 1.35rem; height: 1.35rem; }
.capability-card__body { flex: 1; }
.capability-card__body h3 { font-size: var(--type-scale-base); margin-bottom: 0.25rem; }
.capability-card__body p { font-size: var(--type-scale-sm); color: var(--color-text-secondary); line-height: 1.5; }

/* ============================================================
   9. PIPELINE FLOW  (horizontal stage diagram)
   ============================================================ */
.pipeline { display: flex; align-items: stretch; gap: 0; }
.pipeline__stage { flex: 1; position: relative; text-align: center; padding: 1.5rem 1rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); }
.pipeline__stage:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
.pipeline__stage:last-child  { border-radius: 0 var(--r-md) var(--r-md) 0; }
.pipeline__stage:not(:last-child)::after { content: ''; position: absolute; top: 50%; right: -1.5rem; width: 1.5rem; height: 2px; background: var(--color-border-medium); transform: translateY(-50%); z-index: 1; }
.pipeline__phase { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-brand-primary); }
.pipeline__name { margin-top: 0.5rem; font-weight: var(--type-weight-semibold); }
.pipeline__meta { margin-top: 0.25rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
@media (max-width: 768px) {
  .pipeline { flex-direction: column; }
  .pipeline__stage:first-child { border-radius: var(--r-md) var(--r-md) 0 0; }
  .pipeline__stage:last-child  { border-radius: 0 0 var(--r-md) var(--r-md); }
  .pipeline__stage:not(:last-child)::after { top: auto; bottom: -1.5rem; right: 50%; width: 2px; height: 1.5rem; transform: translateX(50%); }
}

/* ============================================================
   10. CATALOG  (filter pills, search, data grid, product cards)
   ============================================================ */
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.filter-pill {
  display: inline-flex; align-items: center; padding: 0.5rem 1.25rem;
  font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); letter-spacing: -0.01em;
  color: var(--color-text-secondary); background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle); border-radius: var(--r-pill);
  transition: border-color var(--dur), color var(--dur), background var(--dur);
}
.filter-pill:hover { border-color: var(--color-border-medium); color: var(--color-text-primary); }
.filter-pill.is-active { background: var(--color-brand-primary); color: #fff; border-color: var(--color-brand-primary); }

.search { position: relative; }
.search__icon { position: absolute; left: 1rem; top: 50%; transform: translateY(-50%); width: 1rem; height: 1rem; color: var(--color-text-tertiary); pointer-events: none; }
.search-input {
  width: 100%; padding: 0.75rem 1rem 0.75rem 2.75rem;
  font-size: var(--type-scale-sm); color: var(--color-text-primary);
  background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-sm);
  transition: border-color var(--dur);
}
.search-input::placeholder { color: var(--color-text-tertiary); }
.search-input:focus { outline: none; border-color: var(--color-brand-primary); }

/* Institutional data grid */
.data-grid { border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); overflow: hidden; background: var(--color-bg-surface); }
.data-grid__header, .data-grid__row { display: grid; grid-template-columns: var(--grid-cols, 2fr 1fr 1fr 1fr auto); align-items: center; gap: 1rem; }
.data-grid__header { padding: 0.75rem 1.25rem; font-size: 0.6875rem; font-weight: var(--type-weight-semibold); text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-text-secondary); border-bottom: 2px solid var(--color-border-subtle); }
.data-grid__row { padding: 1rem 1.25rem; font-size: var(--type-scale-sm); border-bottom: 1px solid var(--color-border-subtle); transition: background var(--dur); }
.data-grid__row:last-child { border-bottom: none; }
.data-grid__row:hover { background: color-mix(in srgb, var(--color-brand-primary) 3%, transparent); }
.data-grid__row:hover .row-arrow { transform: translateX(4px); }
.row-arrow { transition: transform var(--dur); color: var(--color-text-tertiary); }
.mono-id { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); color: var(--color-text-secondary); }
@media (max-width: 768px) {
  .data-grid__header { display: none; }
  .data-grid__row { grid-template-columns: 1fr; gap: 0.25rem; }
}

/* Product catalog cards */
.product-card { background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); padding: 1.5rem; transition: border-color var(--dur), box-shadow var(--dur); }
.product-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.product-card__generic { font-weight: var(--type-weight-semibold); font-size: var(--type-scale-lg); }
.product-card__proprietary { font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
.product-card__row { display: flex; justify-content: space-between; gap: 1rem; padding-block: 0.375rem; font-size: var(--type-scale-sm); border-top: 1px solid var(--color-border-subtle); }
.product-card__row dt { color: var(--color-text-tertiary); }
.product-card__row dd { color: var(--color-text-primary); text-align: right; }

/* Catalog detail */
.spec-table { width: 100%; border-collapse: collapse; }
.spec-table th, .spec-table td { text-align: left; padding: 0.875rem 1rem; border-bottom: 1px solid var(--color-border-subtle); font-size: var(--type-scale-sm); }
.spec-table th { color: var(--color-text-secondary); font-weight: var(--type-weight-medium); width: 40%; }
.spec-table td { font-family: var(--type-family_mono); color: var(--color-text-primary); }

/* ============================================================
   11. LEADERSHIP + FACILITIES + PARTNERS
   ============================================================ */
.person-card { text-align: left; }
.person-card__avatar { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--r-md); background: var(--color-bg-sunken); }
.person-card__name { margin-top: 1rem; font-weight: var(--type-weight-semibold); }
.person-card__title { font-size: var(--type-scale-sm); color: var(--color-brand-primary); }
.person-card__bio { margin-top: 0.5rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }

.facility-card { display: flex; flex-direction: column; gap: 0.5rem; padding: 1.75rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); }
.facility-card__name { font-weight: var(--type-weight-semibold); font-size: var(--type-scale-lg); }
.facility-card__loc { font-size: var(--type-scale-sm); color: var(--color-text-tertiary); }
.facility-card__specs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }

.partner-wall { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 1px; background: var(--color-border-subtle); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); overflow: hidden; }
.partner-wall__cell { display: grid; place-items: center; min-height: 6rem; padding: 1.5rem; background: var(--color-bg-surface); }
.partner-wall__cell span { font-weight: var(--type-weight-semibold); color: var(--color-text-secondary); letter-spacing: -0.01em; }

/* ============================================================
   12. CONTACT FORM
   ============================================================ */
.field { display: flex; flex-direction: column; gap: 0.375rem; }
.field label { font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); color: var(--color-text-secondary); }
.field input, .field textarea, .field select {
  padding: 0.75rem 1rem; font: inherit; font-size: var(--type-scale-sm);
  color: var(--color-text-primary); background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle); border-radius: var(--r-sm);
  transition: border-color var(--dur);
}
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--color-brand-primary); }

/* The contact form sits on the dark band: its labels and fields must be light
   and legible, not dark-on-dark. */
.tone-dark .field label { color: rgba(255, 255, 255, 0.82); }
.tone-dark .field input, .tone-dark .field textarea, .tone-dark .field select {
  color: #fff; background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.18);
}
.tone-dark .field input::placeholder, .tone-dark .field textarea::placeholder { color: rgba(255, 255, 255, 0.4); }
.tone-dark .field select option { color: var(--color-text-primary); }
.tone-dark .field input:focus, .tone-dark .field textarea:focus, .tone-dark .field select:focus { border-color: var(--color-brand-accent_spark); background: rgba(255, 255, 255, 0.09); }

/* ============================================================
   13. BADGES + SECTION TONES
   ============================================================ */
.badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.625rem; font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); border-radius: var(--r-sm); }
.badge--primary { background: color-mix(in srgb, var(--color-brand-primary) 10%, transparent); color: var(--color-brand-primary); }
.badge--secondary { background: color-mix(in srgb, var(--color-brand-secondary) 8%, transparent); color: var(--color-brand-secondary); }
.badge--info { background: color-mix(in srgb, var(--color-status-info) 10%, transparent); color: var(--color-status-info); }
.badge__dot { width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: currentColor; }

/* In dark mode a tint of the brand colour over a dark surface is unreadable.
   Lift the surface and use a light foreground instead. */
:root[data-theme="dark"] .badge--primary,
:root[data-theme="dark"] .badge--secondary {
  background: rgba(255, 255, 255, 0.10);
  color: var(--color-text-primary);
}
:root[data-theme="dark"] .badge--info { background: rgba(255, 255, 255, 0.10); color: var(--color-status-info); }
:root[data-theme="dark"] .capability-card__icon,
:root[data-theme="dark"] .resource-card__icon,
:root[data-theme="dark"] .portal-logo { background: rgba(255, 255, 255, 0.08); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge--primary,
  :root:not([data-theme="light"]) .badge--secondary {
    background: rgba(255, 255, 255, 0.10);
    color: var(--color-text-primary);
  }
  :root:not([data-theme="light"]) .capability-card__icon,
  :root:not([data-theme="light"]) .resource-card__icon,
  :root:not([data-theme="light"]) .portal-logo { background: rgba(255, 255, 255, 0.08); }
}

/* Section rhythm. The clinical palette is intentionally pale, so neighbouring
   bands can read as the same colour. Delineate every tinted band with hairline
   top and bottom borders and lean on the sunken tint for the ones that need to
   stand apart. The result is a clear light / tinted / dark cadence down the page. */
.tone-subtle  { background: var(--color-bg-subtle); border-block: 1px solid var(--color-border-subtle); }
.tone-sunken  { background: var(--color-bg-sunken); border-block: 1px solid var(--color-border-subtle); }
.tone-surface { background: var(--color-bg-surface); }
.tone-dark { background: linear-gradient(160deg, var(--color-brand-secondary), var(--color-brand-secondary_2)); color: rgba(255,255,255,0.78); }
.tone-dark h1, .tone-dark h2, .tone-dark h3, .tone-dark h4 { color: #fff; }
.tone-dark .section-label { color: rgba(255,255,255,0.6); }
.tone-dark .section-desc, .tone-dark .lead { color: rgba(255,255,255,0.78); }
/* The eyebrow is brand-primary, a deep green that all but disappears on the
   navy band. Use the spark accent, matching what the page hero already does. */
.tone-dark .eyebrow { color: var(--color-brand-accent_spark); }

/* Interior page hero: taller, with the same engineering-grid texture as the home
   hero so interior pages feel part of the same site, plus an eyebrow slot. */
.page-hero { position: relative; overflow: hidden; background: linear-gradient(160deg, var(--color-brand-secondary), var(--color-brand-dark)); color: #fff; padding-block: 9rem 4.5rem; }
.page-hero::before { content: ''; position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px); background-size: 64px 64px; mask-image: radial-gradient(120% 90% at 20% 30%, #000 10%, transparent 75%); -webkit-mask-image: radial-gradient(120% 90% at 20% 30%, #000 10%, transparent 75%); }
.page-hero .container { position: relative; z-index: 1; }
.page-hero .eyebrow { color: var(--color-brand-accent_spark); }
.page-hero h1 { color: #fff; font-size: clamp(2.25rem, 4.5vw, 3.25rem); }
.page-hero p { color: rgba(255,255,255,0.75); }

/* Horizontal value chain / stage flow */
.flow { display: flex; align-items: stretch; gap: 0; }
.flow__stage { flex: 1; position: relative; text-align: center; padding: 1.75rem 1.25rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); }
.flow__stage:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
.flow__stage:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }
.flow__stage:not(:last-child)::after { content: ''; position: absolute; top: 50%; right: -0.75rem; width: 1.5rem; height: 1.5rem; transform: translateY(-50%) rotate(45deg); background: var(--color-bg-surface); border-top: 1px solid var(--color-border-subtle); border-right: 1px solid var(--color-border-subtle); z-index: 1; }
.flow__num { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); font-weight: var(--type-weight-semibold); color: var(--color-brand-primary); }
.flow__name { margin-top: 0.5rem; font-weight: var(--type-weight-semibold); }
.flow__desc { margin-top: 0.375rem; font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
@media (max-width: 768px) { .flow { flex-direction: column; } .flow__stage:first-child { border-radius: var(--r-md) var(--r-md) 0 0; } .flow__stage:last-child { border-radius: 0 0 var(--r-md) var(--r-md); } .flow__stage:not(:last-child)::after { display: none; } }

/* Job / open-position rows */
.job-row { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding: 1.35rem 1.5rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); transition: border-color var(--dur), box-shadow var(--dur); }
.job-row:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.job-row__title { font-weight: var(--type-weight-semibold); }
.job-row__meta { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-top: 0.35rem; font-size: var(--type-scale-sm); color: var(--color-text-tertiary); }
.job-row__meta span { display: inline-flex; align-items: center; gap: 0.35rem; }
@media (max-width: 640px) { .job-row { flex-direction: column; align-items: flex-start; } }

/* Value / pillar cards on a dark band keep their own surface */
.value-card { padding: 1.75rem; border-radius: var(--r-md); background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); }
.value-card__num { font-family: var(--type-family_mono); font-size: var(--type-scale-sm); color: var(--color-brand-primary); font-weight: var(--type-weight-semibold); }
.value-card h3 { margin: 0.5rem 0 0.4rem; font-size: var(--type-scale-lg); }
.value-card p { font-size: var(--type-scale-sm); color: var(--color-text-secondary); }
.tone-dark .value-card { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.10); }
.tone-dark .value-card p { color: rgba(255,255,255,0.7); }
.tone-dark .value-card h3 { color: #fff; }

/* Resource / download cards */
.resource-card { display: flex; gap: 1rem; align-items: flex-start; padding: 1.5rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-md); transition: border-color var(--dur), box-shadow var(--dur); }
.resource-card:hover { border-color: var(--color-brand-primary); box-shadow: var(--shadow-sm); }
.resource-card__icon { flex: none; width: 2.5rem; height: 2.5rem; display: grid; place-items: center; border-radius: var(--r-sm); background: color-mix(in srgb, var(--color-brand-primary) 9%, transparent); color: var(--color-brand-primary); }
.resource-card h3 { font-size: var(--type-scale-base); }
.resource-card p { font-size: var(--type-scale-sm); color: var(--color-text-secondary); margin-top: 0.2rem; }

/* FAQ accordion.
   The section is <details>/<summary>, so open and closed are browser state, not
   script state: it works with JavaScript blocked and it is keyboard operable for
   free. Everything below is presentation on top of that,
   including the marker reset, because the native triangle is not styleable. */
.faq { --stack-gap: 0.75rem; max-width: 52rem; }
.faq-item {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-md);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.faq-item:hover { border-color: var(--color-border-medium); }
.faq-item[open] { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.faq-item__q {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: 1.15rem 1.35rem; cursor: pointer; list-style: none;
  font-size: var(--type-scale-base); font-weight: var(--type-weight-semibold);
  color: var(--color-text-primary); border-radius: var(--r-md);
}
.faq-item__q::-webkit-details-marker { display: none; }
.faq-item__q:hover { color: var(--color-brand-primary); }
/* The focus ring is inset so it never sits half outside a rounded card. */
.faq-item__q:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: -2px; }
.faq-item__chevron {
  flex: none; width: 1.15rem; height: 1.15rem; color: var(--color-text-tertiary);
  transition: transform var(--dur) var(--ease), color var(--dur);
}
.faq-item[open] .faq-item__chevron { transform: rotate(180deg); color: var(--color-brand-primary); }
.faq-item__a { padding: 0 1.35rem 1.35rem; }
.faq-item__a p {
  max-width: 60ch; font-size: var(--type-scale-sm);
  line-height: var(--type-leading-normal); color: var(--color-text-secondary);
}
.tone-dark .faq-item { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.10); }
.tone-dark .faq-item[open] { border-color: rgba(255,255,255,0.22); }
.tone-dark .faq-item__q { color: #fff; }
.tone-dark .faq-item__q:hover, .tone-dark .faq-item[open] .faq-item__chevron { color: var(--color-brand-accent_spark); }
.tone-dark .faq-item__a p { color: rgba(255,255,255,0.72); }

/* Testimonial / quote cards.
   The theme ships no photographs of people, so attribution is a monogram and a
   quote mark. Cards are a flex column with the attribution pushed to the bottom,
   so a row of quotes of different lengths still aligns on its footer. */
.quote-card {
  display: flex; flex-direction: column; gap: 1rem; padding: 1.75rem;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle); border-radius: var(--r-md);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.quote-card:hover { border-color: var(--color-border-medium); box-shadow: var(--shadow-sm); }
.quote-card__mark {
  font-size: var(--type-scale-4xl); line-height: 0.7; height: 1.25rem;
  font-weight: var(--type-weight-bold);
  color: color-mix(in srgb, var(--color-brand-primary) 32%, transparent);
}
.quote-card__quote { font-size: var(--type-scale-base); line-height: 1.6; color: var(--color-text-primary); }
.quote-card__by {
  display: flex; align-items: center; gap: 0.75rem; margin-top: auto;
  padding-top: 1rem; border-top: 1px solid var(--color-border-subtle);
}
.quote-card__avatar {
  flex: none; width: 2.5rem; height: 2.5rem; display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--color-brand-primary) 10%, transparent);
  color: var(--color-brand-primary);
  font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold);
}
.quote-card__who { display: flex; flex-direction: column; }
.quote-card__name { font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold); }
.quote-card__role { font-size: var(--type-scale-xs); color: var(--color-text-secondary); }
.quote-card__org { font-size: var(--type-scale-xs); color: var(--color-text-tertiary); }
.tone-dark .quote-card { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.10); }
.tone-dark .quote-card__quote { color: #fff; }
.tone-dark .quote-card__by { border-top-color: rgba(255,255,255,0.12); }
.tone-dark .quote-card__avatar { background: rgba(255,255,255,0.10); color: var(--color-brand-accent_spark); }
.tone-dark .quote-card__role { color: rgba(255,255,255,0.72); }
.tone-dark .quote-card__org { color: rgba(255,255,255,0.55); }

/* CTA band */
.cta-band { text-align: center; }
.cta-band .container { max-width: 44rem; }
.cta-inner { align-items: center; }
.btn--block { width: 100%; justify-content: center; }

/* Portal login */
.portal { min-height: 78vh; display: grid; place-items: center; padding: 7rem 1.5rem 4rem; background: linear-gradient(160deg, var(--color-brand-secondary), var(--color-brand-dark)); }
.portal-card { width: 100%; max-width: 26rem; background: var(--color-bg-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--r-lg); padding: 2.5rem; box-shadow: var(--shadow-xl); }
.portal-logo { width: 3rem; height: 3rem; display: grid; place-items: center; border-radius: var(--r-md); background: color-mix(in srgb, var(--color-brand-primary) 10%, transparent); color: var(--color-brand-primary); margin-bottom: 1.25rem; }
.portal-card h1 { font-size: var(--type-scale-2xl); }
.portal-sub { color: var(--color-text-secondary); font-size: var(--type-scale-sm); margin-top: 0.35rem; margin-bottom: 1.5rem; }
.portal-security { display: flex; align-items: center; gap: 0.4rem; justify-content: center; margin-top: 1.25rem; font-size: var(--type-scale-xs); color: var(--color-text-tertiary); }

/* ============================================================
   14. FOOTER
   ============================================================ */
.site-footer { padding-block: 4rem; border-top: 1px solid var(--color-border-subtle); background: var(--color-bg-page); }
.site-footer__grid { display: grid; grid-template-columns: 2fr repeat(3, 1fr); gap: 3rem; margin-bottom: 3rem; }
@media (max-width: 1024px) { .site-footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px)  { .site-footer__grid { grid-template-columns: 1fr; } }
.site-footer h4 { font-size: var(--type-scale-sm); font-weight: var(--type-weight-semibold); margin-bottom: 1rem; }
.footer-link { display: inline-block; font-size: var(--type-scale-sm); color: var(--color-text-secondary); transition: color var(--dur); }
.footer-link:hover { color: var(--color-brand-primary); }
.footer-links li + li { margin-top: 0.75rem; }
.footer-social { display: inline-grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 1px solid var(--color-border-subtle); border-radius: var(--r-sm); color: var(--color-text-secondary); transition: border-color var(--dur), color var(--dur); }
.footer-social svg { width: 1rem; height: 1rem; }
.footer-social:hover { border-color: var(--color-brand-primary); color: var(--color-brand-primary); }
.site-footer__base { padding-top: 2rem; border-top: 1px solid var(--color-border-subtle); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem; align-items: center; }
.site-footer__base p, .site-footer__base a { font-size: var(--type-scale-xs); color: var(--color-text-tertiary); }
.disclaimer { font-size: var(--type-scale-xs); color: var(--color-text-tertiary); }

/* ============================================================
   15. THEME TOGGLE
   ============================================================ */
.theme-toggle { display: inline-grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: var(--r-sm); color: currentColor; transition: background var(--dur); }
.theme-toggle:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ============================================================
   16. LOADING SCREEN
   ============================================================ */
.loading-screen { position: fixed; inset: 0; z-index: 9999; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; background: var(--color-bg-page); transition: opacity 0.4s var(--ease); }
.loading-screen__brand { font-size: var(--type-scale-sm); font-weight: var(--type-weight-medium); letter-spacing: 0.2em; text-transform: uppercase; color: var(--color-brand-primary); }
.loading-bar { width: 200px; height: 2px; background: var(--color-border-subtle); border-radius: 1px; overflow: hidden; }
.loading-bar__fill { width: 0; height: 100%; background: var(--color-brand-primary); animation: loadFill 1.5s var(--ease) forwards; }
@keyframes loadFill { to { width: 100%; } }

/* ============================================================
   17. ROLE + UTILITY LAYER
   ------------------------------------------------------------
   Deliberately small and named for the role it plays, not for the
   value it emits. This layer exists so the canonical markup (and
   therefore every adapter's templates) can carry NO inline styles:
   the values live here, the markup only names the role. Adding a
   value to a template is the failure mode this layer prevents.
   ============================================================ */

/* Section heading block: eyebrow + h2 + optional lead, above a grid. */
.section-head { margin-bottom: 3rem; }
.section-head--center { text-align: center; }
.section-head--tight { margin-bottom: 2rem; }

/* Text roles */
.text-sm { font-size: var(--type-scale-sm); }
.text-xs { font-size: var(--type-scale-xs); }
.fw-semibold { font-weight: var(--type-weight-semibold); }
.text-spark { color: var(--color-brand-accent_spark); }
.text-strong { color: var(--color-text-primary); }

/* Text tints for use on a dark ground (hero, tone-dark, page-hero) */
.on-dark        { color: var(--color-text-on_dark); }
.on-dark-soft   { color: var(--color-text-on_dark_soft); }
.on-dark-faint  { color: rgba(255, 255, 255, 0.6); }

/* Layout modifiers */
.grid--wide { gap: 4rem; }
.items-start { align-items: start; }
.items-center { align-items: center; }
.items-end { align-items: flex-end; }
.self-start { align-self: flex-start; }

/* Component-scoped placements (keep template markup value-free) */
.hero__body { max-width: 52rem; }
.site-footer__blurb { margin-top: 1rem; max-width: 28rem; font-size: var(--type-scale-sm); }
.site-footer__socials { margin-top: 1.5rem; }
.site-footer__contact-line { font-size: var(--type-scale-sm); }
.site-footer__contact-line--gap { margin-bottom: 0.75rem; }
.catalog-toolbar { margin-bottom: 1.25rem; gap: 1rem; }
.catalog-count { margin-bottom: 0.75rem; }
.catalog-note { margin-top: 1rem; }
.search--inline { min-width: 16rem; }
.data-grid--catalog { --grid-cols: 2fr 1fr 1fr 1fr auto; }
.data-grid__row--empty { grid-template-columns: 1fr; text-align: center; color: var(--color-text-tertiary); }
.spec-block { margin-bottom: 1rem; }

/* ============================================================
   18. REVEAL / SCROLLBAR / A11Y / RTL
   ============================================================ */
/* .reveal is deliberately inert until JS confirms it can run. If scripting is
   blocked or a module throws, every section must still be fully visible: a
   theme that hides its own content behind an animation is broken, not subtle.
   head.html stamps html.js before paint, so there is no flash. */
.reveal { opacity: 1; transform: none; }
html.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); }
html.js .reveal.is-visible { opacity: 1; transform: none; }

::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--color-border-medium); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-text-tertiary); }

*:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: 2px; }
.skip-link { position: absolute; left: -999px; top: 0; z-index: 200; padding: 0.75rem 1rem; background: var(--color-brand-primary); color: #fff; border-radius: 0 0 var(--r-sm) 0; }
.skip-link:focus { left: 0; }

[dir="rtl"] .pipeline { direction: rtl; }
[dir="rtl"] .ribbon__track { direction: rtl; }

@media (prefers-reduced-motion: reduce) {
  /* The card stack is absolutely positioned for the crossfade. With motion off
     there is no crossfade, so put the cards back in flow and show all of them. */
  .molecular.is-scroll-scene { min-height: 0; }
  .molecular.is-scroll-scene > .container { position: static; }
  .narrative-card-stack { min-height: 0; }
  .narrative-card { position: relative !important; inset: auto !important; opacity: 1 !important; transform: none !important; visibility: visible !important; }
  .narrative-card + .narrative-card { margin-top: 1rem; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  html.js .reveal { opacity: 1; transform: none; }
  .loading-bar__fill { width: 100%; animation: none; }
}

/* ============================================================
   19. ARTICLE (news / briefing detail)
   ============================================================ */
.article-meta { font-family: var(--type-family_mono); font-size: var(--type-scale-xs); color: rgba(255,255,255,0.6); }
.article-body > * + * { margin-top: 1.25rem; }
.article-body p { color: var(--color-text-secondary); font-size: var(--type-scale-lg); line-height: 1.7; }
.article-body .lead { color: var(--color-text-primary); font-weight: var(--type-weight-medium); }
/* Markdown cannot add a class, so an article written as prose in Hugo, Jekyll or
   JBake gets the lead treatment on its opening paragraph and the pull-quote
   treatment on a plain blockquote. That is what lets those formats carry real
   markdown article files instead of pre-rendered HTML. */
.article-body > p:first-child { color: var(--color-text-primary); font-weight: var(--type-weight-medium); }
.article-body > blockquote {
  margin: 2rem 0;
  padding-left: 1.5rem;
  border-left: 3px solid var(--color-brand-primary);
  font-size: var(--type-scale-xl);
  line-height: var(--type-leading-snug);
  color: var(--color-text-primary);
}
.article-body > blockquote p { font-size: inherit; color: inherit; }
.pull-quote {
  margin-block: 2rem; padding: 1.5rem 1.75rem;
  border-left: 3px solid var(--color-brand-primary);
  background: var(--color-bg-subtle); border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: var(--type-scale-xl); line-height: 1.4; font-weight: var(--type-weight-medium);
  color: var(--color-text-primary);
}

/* ============================================================
   20. PRINT
   Buyers of a pharma site print specs, catalogs and briefings. Drop the
   furniture, flatten the dark bands, and show link targets.
   ============================================================ */
@media print {
  .site-nav, .drawer, .hero__bg, .hero__overlay, .hero__video, .hero__scroll,
  .theme-toggle, .nav-toggle, .btn-portal, .ribbon, .globe-frame, .molecular__stage,
  .webgl-fallback, .featured-briefing__art,
  .site-footer__socials, .filter-bar, .search, [data-catalog-empty] { display: none !important; }
  /* Buttons styled for a dark band keep white text, which prints as an invisible
     label on white paper. Give every button print-safe ink and an outline. */
  .btn, .btn--secondary, .btn--ghost-dark, .btn--on-dark {
    color: #000 !important; background: transparent !important;
    border: 1px solid #000 !important;
  }
  html, body { background: #fff !important; color: #000 !important; }
  .hero, .page-hero, .tone-dark { background: #fff !important; color: #000 !important; padding-block: 0 1rem !important; min-height: 0 !important; }
  .hero h1, .page-hero h1, .tone-dark h1, .tone-dark h2, .tone-dark h3,
  .hero__lead, .page-hero p, .tone-dark p, .article-meta { color: #000 !important; }
  .section { padding-block: 1rem !important; }
  .card, .metric-card, .capability-card, .facility-card, .data-grid, .pipeline-table,
  .value-card, .feature-card, .post-card, .resource-card, .job-row, .faq-item, .quote-card {
    border-color: #bbb !important; box-shadow: none !important; break-inside: avoid;
  }
  /* A printed FAQ should carry its answers. Engines hide a closed panel in two
     different ways, so ask for both, and drop the chevron either way. */
  .faq-item::details-content { content-visibility: visible !important; }
  .faq-item__a { display: block !important; }
  .faq-item__chevron { display: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; color: #555; }
  .reveal, html.js .reveal { opacity: 1 !important; transform: none !important; }
  @page { margin: 16mm; }
}


/* ============================================================
   21. WEBGL FALLBACK
   Shown in place of a 3D canvas when the browser cannot create a
   WebGL context. Sized like the canvas it replaces so the section
   keeps its rhythm instead of collapsing.
   ============================================================ */
.webgl-fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 16rem;
  padding: var(--space-6);
  border-radius: var(--r-lg);
  background: var(--color-bg-subtle);
  border: 1px solid var(--color-border-subtle);
}

.webgl-fallback__poster {
  width: 100%;
  max-width: 34rem;
  height: auto;
  border-radius: var(--r-md);
}

.webgl-fallback__note {
  margin: 0;
  max-width: 32rem;
  text-align: center;
  font-size: var(--type-scale-xs);
  line-height: var(--type-leading-snug);
  color: var(--color-text-tertiary);
}

.webgl-fallback--bare { min-height: 12rem; }

.tone-dark .webgl-fallback,
:root[data-theme="dark"] .webgl-fallback {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.10);
}

.tone-dark .webgl-fallback__note { color: rgba(255, 255, 255, 0.55); }


/* ============================================================
   22. CONTRAST AND FOCUS ON DARK GROUNDS
   ============================================================ */

/* The programme code is brand-secondary, which IS the dark background colour, so
   in dark mode it was navy on navy. */
:root[data-theme="dark"] .pipeline-row__id { color: var(--color-brand-accent_spark); }

/* The default focus ring is brand-primary, a deep green that all but disappears
   on the dark navigation bar and on any dark band. Keyboard users need the ring
   more than anyone, so restate it in white wherever the ground is dark. */
.site-nav *:focus-visible,
.drawer *:focus-visible,
.tone-dark *:focus-visible,
.page-hero *:focus-visible,
.hero *:focus-visible,
.portal *:focus-visible,
:root[data-theme="dark"] *:focus-visible {
  outline: 2px solid #FFFFFF;
  outline-offset: 2px;
}

/* The brand link wraps an image, so without this the ring hugs the text box and
   reads as absent. */
.site-nav__brand:focus-visible { outline-offset: 4px; border-radius: var(--r-sm); }

/* ============================================================
   23. FORM RESULT
   Replaces a demo form once submitted. A static template has no
   backend, so saying so plainly beats both an error page and a
   button that appears to do nothing.
   ============================================================ */
.form-result {
  padding: var(--space-6);
  border: 1px solid var(--color-brand-primary);
  border-left-width: 3px;
  border-radius: var(--r-md);
  background: var(--color-bg-subtle);
  color: var(--color-text-primary);
  font-size: var(--type-scale-base);
  line-height: var(--type-leading-normal);
}

.form-result--error {
  border-color: var(--color-status-danger);
  background: var(--color-status-danger_bg);
}

.tone-dark .form-result,
.portal .form-result,
:root[data-theme="dark"] .form-result {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.24);
  color: #fff;
}


/* ============================================================
   24. DARK MODE FIELD BORDERS
   The rules above cover a form on a dark BAND (.tone-dark). Dark
   MODE is a separate axis: a form on an ordinary section still
   sits on a dark ground, and the tokenised border is too close to
   it for the field edge to be visible.
   ============================================================ */
:root[data-theme="dark"] .field input,
:root[data-theme="dark"] .field textarea,
:root[data-theme="dark"] .field select {
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.04);
}
:root[data-theme="dark"] .field input:focus,
:root[data-theme="dark"] .field textarea:focus,
:root[data-theme="dark"] .field select:focus {
  border-color: var(--color-brand-accent_spark);
  background: rgba(255, 255, 255, 0.08);
}
:root[data-theme="dark"] .field input::placeholder,
:root[data-theme="dark"] .field textarea::placeholder { color: rgba(255, 255, 255, 0.42); }

/* A pill that is not selected must look unselected even while the pointer still
   rests on it, so hover can never be mistaken for the active state. */
.filter-pill:not(.is-active):hover {
  background: var(--color-bg-subtle);
  border-color: var(--color-border-medium);
}
:root[data-theme="dark"] .filter-pill:not(.is-active) {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.14);
}
:root[data-theme="dark"] .filter-pill:not(.is-active):hover {
  background: rgba(255, 255, 255, 0.09);
}

/* ============================================================
   25. PUBLIC DOCUMENTATION (/docs)
   The buyer guides, rendered from the same markdown that ships in
   the package. Long-form prose with a sticky contents rail.
   ============================================================ */
.docs-layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: var(--space-12);
  align-items: start;
}

.docs-nav { position: sticky; top: 6rem; }
.docs-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }

.docs-nav__link {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--color-border-subtle);
  font-size: var(--type-scale-sm);
  color: var(--color-text-secondary);
  text-decoration: none;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.docs-nav__link:hover { color: var(--color-text-primary); border-left-color: var(--color-border-strong); }
.docs-nav__link.is-current {
  color: var(--color-brand-primary);
  border-left-color: var(--color-brand-primary);
  font-weight: var(--type-weight-semibold);
}

.docs-body > * + * { margin-top: var(--space-4); }
.docs-body h2 {
  margin-top: var(--space-12);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border-subtle);
  font-size: var(--type-scale-2xl);
}
.docs-body h3 { margin-top: var(--space-8); font-size: var(--type-scale-lg); }
.docs-body p, .docs-body li { color: var(--color-text-secondary); line-height: var(--type-leading-normal); }
.docs-body ul, .docs-body ol { padding-left: 1.25rem; display: grid; gap: var(--space-2); }
.docs-body code {
  font-family: var(--type-family_mono);
  font-size: 0.875em;
  padding: 0.1em 0.35em;
  border-radius: var(--r-sm);
  background: var(--color-bg-subtle);
  color: var(--color-text-primary);
}
.docs-body pre {
  overflow-x: auto;
  padding: var(--space-4);
  border-radius: var(--r-md);
  background: var(--color-brand-secondary);
  border: 1px solid var(--color-border-subtle);
}
.docs-body pre code {
  background: none;
  padding: 0;
  color: rgba(255, 255, 255, 0.9);
  font-size: var(--type-scale-sm);
  line-height: 1.6;
}
/* Tables carry most of the reference material, so they must scroll rather than
   force the page sideways on a phone. */
.docs-body table { display: block; overflow-x: auto; width: 100%; border-collapse: collapse; }
.docs-body th, .docs-body td {
  padding: var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: var(--type-scale-sm);
  vertical-align: top;
}
.docs-body th { color: var(--color-text-primary); font-weight: var(--type-weight-semibold); white-space: nowrap; }
.docs-body blockquote {
  margin: 0;
  padding-left: var(--space-4);
  border-left: 3px solid var(--color-brand-accent_spark);
  color: var(--color-text-primary);
}
.docs-body hr { border: 0; border-top: 1px solid var(--color-border-subtle); margin: var(--space-8) 0; }

@media (max-width: 60rem) {
  .docs-layout { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
  .docs-nav { position: static; }
  .docs-nav ul { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .docs-nav__link { border-left: 0; border-bottom: 2px solid var(--color-border-subtle); }
}

:root[data-theme="dark"] .docs-body pre { background: rgba(0, 0, 0, 0.35); }
:root[data-theme="dark"] .docs-body code { background: rgba(255, 255, 255, 0.08); }


/* ===== ported interactive-app components (css/apps/*) ===== */
/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * audit-ledger.css styles the Immutable Audit Interface. Authored entirely
 * against the L0 design tokens (--color-*, --type-*, --r-*, --dur, --ease);
 * brand colours are never hard-coded. The component is designed for a dark
 * section (tone-dark), so neutral surfaces and text use white-alpha overlays
 * that read on the dark ground while status pills draw their hue from tokens.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.audit-ledger { display: block; }

/* ---- Container ---- */
.audit-container {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: var(--r-md);
  overflow: hidden;
}

/* ---- Toolbar ---- */
.audit-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}

.audit-toolbar__meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.audit-toolbar__title {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
}

.audit-toolbar__sync {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  color: rgba(255, 255, 255, 0.32);
  white-space: nowrap;
}

/* ---- Live indicator ---- */
.audit-live {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.audit-live__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--r-pill);
  background: var(--color-brand-accent_spark);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand-accent_spark) 70%, transparent);
  animation: audit-live-pulse 2.2s var(--ease) infinite;
}

.audit-live__label {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  color: var(--color-brand-accent_spark);
}

.audit-live.is-static .audit-live__dot { animation: none; }

@keyframes audit-live-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand-accent_spark) 60%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

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

/* ---- Scroll + grid ---- */
.audit-scroll { overflow-x: auto; }

.audit-grid {
  display: grid;
  grid-template-columns: 130px 150px 1fr 116px 130px 1fr;
  align-items: center;
  gap: 1rem;
  min-width: 820px;
  padding: 0 1.25rem;
}

.audit-grid--head {
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.48);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}

.audit-row {
  padding-top: 0.95rem;
  padding-bottom: 0.95rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.85);
  transition: background var(--dur) var(--ease);
}

.audit-row:last-child { border-bottom: none; }
.audit-row:hover { background: rgba(255, 255, 255, 0.04); }

/* ---- Cells ---- */
.audit-cell {
  font-size: var(--type-scale-sm);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.audit-cell--mono {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
}

.audit-cell--id { font-weight: var(--type-weight-medium); }
.audit-cell--time { color: rgba(255, 255, 255, 0.55); }

/* ---- Hash ---- */
.hash-value {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.38);
}

.hash-value.is-pending {
  color: color-mix(in srgb, var(--color-brand-accent_spark) 55%, white);
  font-style: italic;
}

/* ---- Status pills (token-driven hues) ---- */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  border-radius: var(--r-pill);
  white-space: nowrap;
}

.status-pill__glyph { font-size: 0.75em; line-height: 1; }

/* green: released / approved / effective */
.status-pill.is-ok {
  background: color-mix(in srgb, var(--color-brand-primary) 30%, transparent);
  color: color-mix(in srgb, var(--color-brand-accent_spark) 78%, white);
}

/* amber/lime: resolved */
.status-pill.is-warn {
  background: color-mix(in srgb, var(--color-brand-accent_spark) 18%, transparent);
  color: color-mix(in srgb, var(--color-brand-accent_spark) 62%, white);
}

/* blue: under review */
.status-pill.is-info {
  background: color-mix(in srgb, var(--color-status-info) 22%, transparent);
  color: color-mix(in srgb, var(--color-status-info) 55%, white);
}

/* fallback */
.status-pill.is-neutral {
  background: rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.70);
}

/* ---- Responsive: stack cells into labelled rows on narrow screens ---- */
@media (max-width: 640px) {
  .audit-toolbar { flex-wrap: wrap; }
  .audit-toolbar__sync { display: none; }
}

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * command-center.css - styles for the Manufacturing Command Center simulator.
 *
 * Brand colours are sourced from theme tokens (var(--color-*)). The terminal
 * panel chrome and the telemetry/phase status palette are exposed as component
 * scoped custom properties on [data-command-center] so a buyer can retheme the
 * console in one place without touching the rest of the theme.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

[data-command-center] {
  /* --- brand-sourced (theme tokens) --- */
  --cc-panel-bg: var(--color-brand-secondary);
  --cc-active-bg: var(--color-brand-primary);
  --cc-accent: var(--color-brand-accent_spark);

  /* --- terminal chrome (component knobs) --- */
  --cc-panel-header: color-mix(in srgb, var(--color-brand-secondary) 84%, black);
  --cc-panel-line: color-mix(in srgb, var(--color-brand-secondary) 55%, white 12%);
  --cc-ink-dim: #64748b;
  --cc-ink-mute: #94a3b8;
  --cc-ink-faint: #475569;
  --cc-grid: color-mix(in srgb, var(--color-brand-secondary) 45%, white 14%);
  --cc-dots: #334155;

  /* --- telemetry status palette --- */
  --cc-s-verified: #22c55e;
  --cc-s-loaded: #06b6d4;
  --cc-s-active: #22c55e;
  --cc-s-compliant: #10b981;
  --cc-s-locked: #f59e0b;
  --cc-s-ready: #22c55e;
  --cc-s-validated: #06b6d4;

  /* --- predictive-timeline phase bars --- */
  --cc-phase-1: #10b981;
  --cc-phase-2: #06b6d4;
  --cc-phase-3: #8b5cf6;
  --cc-phase-4: #f59e0b;
}

/* ============================================
   SELECTORS
   ============================================ */
.cc-field {
  margin-bottom: 1.5rem;
}
.cc-field__label {
  display: block;
  margin-bottom: 0.75rem;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-secondary);
}
.cc-selector-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.cc-btn {
  padding: 0.625rem 1.25rem;
  font-family: var(--type-family_sans);
  font-size: var(--type-scale-sm);
  font-weight: var(--type-weight-semibold);
  letter-spacing: -0.01em;
  background: var(--color-bg-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.cc-btn:hover {
  border-color: var(--color-border-medium);
}
.cc-btn.is-active {
  background: var(--cc-active-bg);
  color: var(--color-text-on_dark);
  border-color: var(--cc-active-bg);
}

/* ============================================
   COMMAND CENTER PANEL
   ============================================ */
.cc-command-center {
  background: var(--cc-panel-bg);
  border: 1px solid var(--cc-panel-line);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-lg, var(--shadow-md));
}
.cc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--cc-panel-line);
  background: var(--cc-panel-header);
}
.cc-title {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  color: var(--cc-ink-dim);
  letter-spacing: 0.08em;
  text-transform: lowercase;
}
.cc-status {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  color: var(--cc-accent);
  letter-spacing: 0.04em;
}
.cc-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 340px;
}
.cc-footer {
  border-top: 1px solid var(--cc-panel-line);
  padding: 0.75rem 1.5rem;
  font-family: var(--type-family_sans);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-normal);
  color: var(--cc-ink-faint);
  line-height: 1.6;
  letter-spacing: 0.01em;
}

/* --- Left pane: predictive timeline --- */
.cc-timeline-pane {
  padding: 1.5rem;
  position: relative;
}
.cc-pane-label {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--cc-ink-faint);
  margin-bottom: 1rem;
}
.cc-chart-svg {
  width: 100%;
  height: auto;
  display: block;
}
.cc-chart-svg .cc-grid-line {
  stroke: var(--cc-grid);
  stroke-width: 0.5;
}
.cc-chart-svg .cc-axis-label {
  font-family: var(--type-family_mono);
  font-size: 9px;
  fill: var(--cc-ink-faint);
}
.cc-chart-svg .cc-phase-bar {
  rx: 3;
  ry: 3;
}
.cc-chart-svg .cc-phase-label {
  font-family: var(--type-family_sans);
  font-size: 9px;
  font-weight: var(--type-weight-semibold);
  fill: var(--color-text-on_dark);
}
.cc-chart-svg .cc-month-marker {
  stroke: var(--cc-accent);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
  opacity: 0;
}
.cc-chart-svg .cc-marker-label {
  font-family: var(--type-family_mono);
  font-size: 8px;
  font-weight: var(--type-weight-bold);
  fill: var(--cc-accent);
  opacity: 0;
}

/* --- Right pane: validation telemetry --- */
.cc-telemetry-pane {
  padding: 1.5rem;
  border-left: 1px solid var(--cc-panel-line);
}
.cc-telemetry-row {
  display: flex;
  align-items: baseline;
  gap: 0;
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-sm);
  line-height: 2.2;
  opacity: 0;
}
.cc-telemetry-time {
  color: var(--cc-ink-faint);
  white-space: nowrap;
  min-width: 5.5em;
}
.cc-telemetry-label {
  color: var(--cc-ink-mute);
  white-space: nowrap;
}
.cc-telemetry-dots {
  color: var(--cc-dots);
  white-space: nowrap;
  flex-shrink: 0;
}
.cc-telemetry-status {
  white-space: nowrap;
  font-weight: var(--type-weight-semibold);
  margin-left: 0.5em;
}
.cc-telemetry-status.s-verified { color: var(--cc-s-verified); }
.cc-telemetry-status.s-loaded { color: var(--cc-s-loaded); }
.cc-telemetry-status.s-active { color: var(--cc-s-active); }
.cc-telemetry-status.s-compliant { color: var(--cc-s-compliant); }
.cc-telemetry-status.s-locked { color: var(--cc-s-locked); }
.cc-telemetry-status.s-ready { color: var(--cc-s-ready); }
.cc-telemetry-status.s-validated { color: var(--cc-s-validated); }

/* --- Placeholder --- */
.cc-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--cc-ink-faint);
  font-family: var(--type-family_sans);
  font-size: var(--type-scale-sm);
  padding: 2rem;
  min-height: 280px;
}
.cc-placeholder svg {
  color: var(--cc-dots);
  margin-bottom: 0.75rem;
}

/* ============================================
   RESPONSIVE
   ============================================ */
@media (max-width: 768px) {
  .cc-body {
    grid-template-columns: 1fr;
  }
  .cc-telemetry-pane {
    border-left: none;
    border-top: 1px solid var(--cc-panel-line);
  }
  .cc-telemetry-row {
    font-size: var(--type-scale-xs);
  }
}
@media (max-width: 640px) {
  .cc-btn {
    padding: 0.5rem 1rem;
    font-size: var(--type-scale-xs);
  }
  .cc-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * dfi-dashboard.css styles the DFI Framework Dashboard: a sticky framework
 * selector that re-renders four data-driven report sections (KPI cells,
 * traffic-light indicators, rating gauges, and framework tag chips). Authored
 * entirely against the L0 design tokens (--color-*, --type-*, --r-*, --shadow-*,
 * --dur, --ease); no brand colour is hard-coded.
 *
 * Traffic-light semantics (green / amber / red) are derived from tokens: green
 * from the accent spark, red from the danger token, and amber as a token-mix of
 * the two, so the whole palette stays theme-driven with zero raw brand hex.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.dfi-dashboard {
  /* Component-scoped semantic tones, all derived from design tokens */
  --dfi-green: var(--color-brand-accent_spark);
  --dfi-red: var(--color-status-danger);
  --dfi-amber: color-mix(in srgb, var(--color-brand-accent_spark) 52%, var(--color-status-danger));
  --dfi-info: var(--color-status-info);
  display: block;
}

.dfi-dashboard__inner { display: block; }

/* ---- Intro hero ---- */
.dfi-hero {
  padding: 3rem 0 1rem;
  max-width: 52rem;
}
.dfi-hero__eyebrow {
  display: block;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-text-tertiary);
}
.dfi-hero__heading {
  margin-top: 0.5rem;
  font-size: var(--type-scale-3xl);
  font-weight: var(--type-weight-bold);
  line-height: 1.1;
  color: var(--color-text-primary);
}
.dfi-hero__lead {
  margin-top: 0.75rem;
  font-size: var(--type-scale-base);
  color: var(--color-text-secondary);
  line-height: var(--type-leading-normal);
}

/* ---- Sticky framework selector ----
   An underline tablist, not a segmented control. The previous version wrapped
   the buttons in a bordered, rounded, shadowed card, which reads as a floating
   widget that happens to sit above some content. Tabs have to look joined to the
   panel they switch: a single rule spans the row, each tab sits on that rule, and
   the active one overlaps it with a coloured underline. */
.dfi-selector-bar {
  position: sticky;
  top: 0;
  z-index: 40;
  margin-bottom: 1.75rem;
  background: color-mix(in srgb, var(--color-bg-page) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--color-border-medium);
}
.dfi-selector {
  display: flex;
  gap: 1.75rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.dfi-selector::-webkit-scrollbar { display: none; }

.dfi-selector__btn {
  flex: 0 0 auto;
  padding: 0.875rem 0;
  font-family: var(--type-family_sans);
  font-size: var(--type-scale-sm);
  font-weight: var(--type-weight-medium);
  color: var(--color-text-secondary);
  background: transparent;
  border: none;
  border-radius: 0;
  /* Overlap the bar's rule so the active underline replaces it rather than
     stacking a second line underneath. */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.dfi-selector__btn.is-active {
  color: var(--color-brand-primary);
  font-weight: var(--type-weight-semibold);
  border-bottom-color: var(--color-brand-primary);
}

.dfi-selector__btn:hover { color: var(--color-text-primary); }

/* ---- Report sections ---- */
.dfi-section { padding: 2.5rem 0; }
.dfi-section.is-alt {
  background: var(--color-bg-subtle);
  /* Escape the container so the band spans the viewport, then put the padding
     back so its content stays aligned with everything else. The old rule relied
     on a --dfi-bleed variable that was never set, so the tint stopped at the
     container edge and the page looked striped down the middle. Body carries
     overflow-x: clip, so the 50vw arithmetic cannot raise a scrollbar. */
  margin-inline: calc(50% - 50vw);
  padding-inline: calc(50vw - 50%);
}
.dfi-section__inner {
  transition: opacity 0.2s var(--ease);
}
.dfi-section__inner.is-fading { opacity: 0; }

/* ---- Section header ---- */
.dfi-sec-head { margin-bottom: 1.75rem; max-width: 54rem; }
.dfi-sec-head__eyebrow {
  display: block;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-text-tertiary);
}
.dfi-sec-head__title {
  margin-top: 0.5rem;
  font-size: var(--type-scale-2xl);
  font-weight: var(--type-weight-bold);
  color: var(--color-text-primary);
}
.dfi-sec-head__desc {
  margin-top: 0.5rem;
  font-size: var(--type-scale-sm);
  color: var(--color-text-secondary);
  line-height: var(--type-leading-normal);
}

/* ---- Card grid ---- */
.dfi-grid { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px) {
  .dfi-grid--2, .dfi-grid--3, .dfi-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .dfi-grid--3 { grid-template-columns: repeat(3, 1fr); }
  .dfi-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

/* ---- KPI cell ---- */
.dfi-kpi {
  display: flex;
  flex-direction: column;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-md);
  padding: 1.5rem;
  box-shadow: var(--shadow-xs);
}
.dfi-kpi__value {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-3xl);
  font-weight: var(--type-weight-bold);
  line-height: 1;
  color: var(--color-brand-primary);
}
.dfi-kpi__unit {
  font-size: var(--type-scale-base);
  font-weight: var(--type-weight-semibold);
  margin-left: 0.1em;
}
.dfi-kpi__label {
  margin-top: 0.5rem;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-secondary);
}

.dfi-note {
  margin-top: 0.75rem;
  font-size: var(--type-scale-xs);
  color: var(--color-text-tertiary);
  line-height: var(--type-leading-snug);
}

/* ---- Traffic-light status line ---- */
.dfi-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.75rem;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
}
.dfi-status__text.is-green { color: var(--dfi-green); }
.dfi-status__text.is-amber { color: var(--dfi-amber); }
.dfi-status__text.is-red { color: var(--dfi-red); }
.dfi-status__text.is-info { color: var(--dfi-info); }
.dfi-status__text.is-neutral { color: var(--color-text-secondary); }

/* ---- Traffic-light dot ---- */
.dfi-dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--r-pill);
  flex: 0 0 auto;
}
.dfi-dot.is-green { background: var(--dfi-green); }
.dfi-dot.is-amber { background: var(--dfi-amber); }
.dfi-dot.is-red { background: var(--dfi-red); }
.dfi-dot.is-info { background: var(--dfi-info); }
.dfi-dot.is-neutral { background: var(--color-border-strong); }

/* ---- Segmented pipeline bar ---- */
.dfi-bar-track {
  display: flex;
  height: 0.5rem;
  margin-top: 0.75rem;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--color-border-subtle);
}
.dfi-bar-seg { transition: width 0.6s var(--ease); }
.dfi-bar-seg.is-green { background: var(--dfi-green); }
.dfi-bar-seg.is-amber { background: var(--dfi-amber); }
.dfi-bar-seg.is-red { background: var(--dfi-red); }
.dfi-bar-seg.is-info { background: var(--dfi-info); }
.dfi-bar-seg.is-neutral { background: var(--color-border-medium); }
/* named brand fills used by pipeline bars */
.dfi-bar-seg.is-primary { background: var(--color-brand-primary); }
.dfi-bar-seg.is-spark { background: var(--color-brand-accent_spark); }

/* ---- Rating gauge (0..max) ---- */
.dfi-gauge {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
}
.dfi-gauge__bar {
  flex: 1;
  height: 0.375rem;
  background: var(--color-border-subtle);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.dfi-gauge__fill {
  height: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--color-brand-primary), var(--color-brand-accent_interactive));
  transition: width 0.8s var(--ease);
}
.dfi-gauge__score {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-bold);
  color: var(--color-brand-primary);
  min-width: 2.75rem;
  text-align: right;
}

/* ---- Framework tag chips ---- */
.dfi-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.75rem;
}
.dfi-tag {
  display: inline-block;
  font-family: var(--type-family_mono);
  font-size: 0.625rem;
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.1rem 0.4rem;
  border-radius: var(--r-sm);
  background: var(--color-bg-sunken);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border-subtle);
}

/* ---- Scorecard / checklist list ---- */
.dfi-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
}
.dfi-list__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: var(--type-scale-xs);
  color: var(--color-text-secondary);
}
.dfi-list__name { min-width: 0; }
.dfi-list__state {
  font-family: var(--type-family_mono);
  font-weight: var(--type-weight-medium);
  white-space: nowrap;
}
.dfi-list__state.is-green { color: var(--dfi-green); }
.dfi-list__state.is-amber { color: var(--dfi-amber); }
.dfi-list__state.is-red { color: var(--dfi-red); }
.dfi-list__state.is-info { color: var(--dfi-info); }
.dfi-list__state.is-neutral { color: var(--color-text-tertiary); }

/* ---- SDG accent card ---- */
.dfi-sdg {
  display: flex;
  flex-direction: column;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-left: 4px solid var(--color-brand-primary);
  border-radius: var(--r-md);
  padding: 1.5rem;
  box-shadow: var(--shadow-xs);
}
.dfi-sdg.accent-primary { border-left-color: var(--color-brand-primary); }
.dfi-sdg.accent-spark { border-left-color: var(--color-brand-accent_spark); }
.dfi-sdg.accent-info { border-left-color: var(--color-status-info); }
.dfi-sdg.accent-amber { border-left-color: var(--dfi-amber); }
.dfi-sdg.accent-secondary { border-left-color: var(--color-brand-secondary); }

.dfi-sdg__eyebrow {
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dfi-sdg.accent-primary .dfi-sdg__eyebrow { color: var(--color-brand-primary); }
.dfi-sdg.accent-spark .dfi-sdg__eyebrow { color: var(--color-brand-accent_spark); }
.dfi-sdg.accent-info .dfi-sdg__eyebrow { color: var(--color-status-info); }
.dfi-sdg.accent-amber .dfi-sdg__eyebrow { color: var(--dfi-amber); }
.dfi-sdg.accent-secondary .dfi-sdg__eyebrow { color: var(--color-brand-secondary); }

.dfi-sdg__title {
  margin: 0.5rem 0 0.75rem;
  font-size: var(--type-scale-lg);
  font-weight: var(--type-weight-bold);
  color: var(--color-text-primary);
}
.dfi-sdg__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-size: var(--type-scale-sm);
  color: var(--color-text-secondary);
  line-height: var(--type-leading-snug);
}

/* ---- Reduced motion: no fades or bar animation ---- */
@media (prefers-reduced-motion: reduce) {
  .dfi-section__inner,
  .dfi-bar-seg,
  .dfi-gauge__fill,
  .dfi-selector__btn { transition: none; }
}


/* The active tab is brand-primary, a deep green that sinks into the dark page.
   Dark mode needs the lighter accent for both the label and the underline. */
:root[data-theme="dark"] .dfi-selector__btn.is-active {
  color: var(--color-brand-accent_spark);
  border-bottom-color: var(--color-brand-accent_spark);
}
:root[data-theme="dark"] .dfi-selector__btn:hover { color: var(--color-text-primary); }


/* The track is border-subtle and the neutral fill is border-medium. In dark mode
   those are #1E2C42 and #26374F, near enough identical that a part-filled bar
   reads as empty and the number it illustrates is lost. Separate them with white
   overlays, which cannot drift when the palette is reskinned. */
:root[data-theme="dark"] .dfi-bar-track { background: rgba(255, 255, 255, 0.09); }
:root[data-theme="dark"] .dfi-bar-seg.is-neutral { background: rgba(255, 255, 255, 0.48); }

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * gantt.css styles the development pipeline Gantt chart. Authored entirely
 * against the L0 design tokens; brand colours are never hard-coded. Accents
 * resolve through a single --gantt-accent custom property set per [data-accent],
 * so a skin that overrides the brand tokens restyles the chart with no CSS edit.
 *
 * The layout is one CSS grid: a fixed label column plus --gantt-cols equal
 * phase columns, shared by the axis and every row so the bars line up with the
 * headers by construction rather than by arithmetic.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.gantt { display: block; }

/* ---- Accent resolution ------------------------------------------------- */
.gantt [data-accent="primary"]   { --gantt-accent: var(--color-brand-primary); }
.gantt [data-accent="secondary"] { --gantt-accent: var(--color-brand-secondary); }
.gantt [data-accent="spark"]     { --gantt-accent: var(--color-brand-accent_spark); }
.gantt [data-accent="info"]      { --gantt-accent: var(--color-status-info); }
/* Amber is derived, not a token: the same spark/danger mix dfi-dashboard uses. */
.gantt [data-accent="amber"]     { --gantt-accent: color-mix(in srgb, var(--color-brand-accent_spark) 52%, var(--color-status-danger)); }

/* ---- Scroller ---------------------------------------------------------- */
.gantt__scroll {
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
}

.gantt-grid {
  position: relative;
  min-width: 46rem;
  --gantt-label: 13rem;
}

/* ---- Phase axis -------------------------------------------------------- */
.gantt-axis {
  display: grid;
  grid-template-columns: var(--gantt-label) minmax(0, 1fr);
  border-bottom: 1px solid var(--color-border-medium);
  margin-bottom: var(--space-2);
}

.gantt-axis__corner { min-width: 0; }

.gantt-axis__track {
  display: grid;
  grid-template-columns: repeat(var(--gantt-cols), minmax(0, 1fr));
}

.gantt-axis__phase {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0 var(--space-2) var(--space-3);
  border-left: 1px solid var(--color-border-subtle);
  min-width: 0;
}

.gantt-axis__index {
  font-family: var(--type-family_mono);
  font-size: 0.625rem;
  font-weight: var(--type-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
}

.gantt-axis__name {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: var(--type-leading-snug);
  color: var(--color-text-secondary);
}

/* ---- Rows -------------------------------------------------------------- */
.gantt-row {
  display: grid;
  grid-template-columns: var(--gantt-label) minmax(0, 1fr);
  align-items: center;
  border-bottom: 1px solid var(--color-border-subtle);
  transition: background var(--dur) var(--ease);
}

.gantt-row:last-of-type { border-bottom: 0; }
.gantt-row.is-active    { background: var(--color-bg-subtle); }

.gantt-row__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-2);
  min-width: 0;
}

.gantt-row__name {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-sm);
  font-weight: var(--type-weight-bold);
  letter-spacing: 0.04em;
  color: var(--color-text-primary);
}

.gantt-row__indication {
  font-size: var(--type-scale-xs);
  line-height: var(--type-leading-snug);
  color: var(--color-text-tertiary);
}

/* ---- Lane and bars ----------------------------------------------------- */
.gantt-row__lane {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--gantt-cols), minmax(0, 1fr));
  align-items: center;
  min-height: 3rem;
  min-width: 0;
}

/* Column guides occupy the first row of the lane grid; the bar overlays them. */
.gantt-row__cell {
  grid-row: 1;
  height: 100%;
  border-left: 1px solid var(--color-border-subtle);
}

.gantt-bar {
  grid-row: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  height: 1.75rem;
  margin: 0 2px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  cursor: pointer;
  opacity: 0;
  transform: scaleX(0.5);
  transform-origin: left center;
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}

.gantt-bar.is-visible { opacity: 1; transform: scaleX(1); }

.gantt-bar__fill {
  position: absolute;
  inset: 0;
  border-radius: var(--r-pill);
  background: var(--gantt-accent);
  opacity: 0.92;
  transition: opacity var(--dur) var(--ease);
}

.gantt-bar.is-active .gantt-bar__fill { opacity: 1; }

.gantt-bar__phase {
  position: relative;
  font-family: var(--type-family_mono);
  font-size: 0.625rem;
  font-weight: var(--type-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--color-text-on_dark);
  /* The label sits on whichever accent the programme carries, and the lighter
     accents (spark, amber) do not give white text enough contrast on their own.
     A scrim guarantees legibility across all five without darkening the bar. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

.gantt-bar:focus-visible {
  outline: 2px solid var(--color-brand-primary);
  outline-offset: 3px;
  z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
  .gantt-bar, .gantt-bar__fill, .gantt-row { transition: none; }
}

/* ---- Tooltip ----------------------------------------------------------- */
.gantt-tip {
  position: absolute;
  z-index: 5;
  width: min(20rem, 80vw);
  padding: var(--space-4);
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-top: 3px solid var(--gantt-accent, var(--color-border-medium));
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

.gantt-tip.is-shown { opacity: 1; }

.gantt-tip__status {
  display: inline-block;
  font-family: var(--type-family_mono);
  font-size: 0.625rem;
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--gantt-accent, var(--color-text-secondary));
  margin-bottom: var(--space-1);
}

.gantt-tip__name {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-lg);
  font-weight: var(--type-weight-bold);
  line-height: var(--type-leading-tight);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-1);
}

.gantt-tip__indication {
  font-size: var(--type-scale-sm);
  line-height: var(--type-leading-snug);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-3);
}

.gantt-tip__rows {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-1) var(--space-3);
  margin: 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-subtle);
}

.gantt-tip__term {
  font-family: var(--type-family_mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  white-space: nowrap;
}

.gantt-tip__value {
  font-size: var(--type-scale-xs);
  line-height: var(--type-leading-snug);
  color: var(--color-text-primary);
  margin: 0;
}

/* ---- Legend ------------------------------------------------------------ */
.gantt-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  margin: var(--space-6) 0 0;
  padding: 0;
}

.gantt-legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.gantt-legend__swatch {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: var(--r-pill);
  background: var(--gantt-accent);
}

.gantt-legend__label {
  font-size: var(--type-scale-xs);
  color: var(--color-text-secondary);
}

.gantt__hint {
  font-size: var(--type-scale-xs);
  color: var(--color-text-tertiary);
  margin: var(--space-4) 0 0;
}

@media (max-width: 48rem) {
  .gantt-grid { --gantt-label: 9.5rem; }
}

/* ---- Dark sections ----------------------------------------------------- */
/* On a dark band the tokenised surface would be a light card and the subtle
   borders vanish. Use white overlays so the chart reads as part of the band. */
.tone-dark .gantt-axis        { border-bottom-color: rgba(255, 255, 255, 0.18); }
.tone-dark .gantt-axis__phase,
.tone-dark .gantt-row__cell   { border-left-color: rgba(255, 255, 255, 0.08); }
.tone-dark .gantt-row         { border-bottom-color: rgba(255, 255, 255, 0.08); }
.tone-dark .gantt-row.is-active { background: rgba(255, 255, 255, 0.05); }

.tone-dark .gantt-axis__name  { color: rgba(255, 255, 255, 0.72); }
.tone-dark .gantt-axis__index,
.tone-dark .gantt-row__indication,
.tone-dark .gantt__hint       { color: rgba(255, 255, 255, 0.52); }
.tone-dark .gantt-row__name   { color: #fff; }
.tone-dark .gantt-legend__label { color: rgba(255, 255, 255, 0.72); }

.tone-dark .gantt-tip {
  background: var(--color-bg-page);
  border-color: rgba(255, 255, 255, 0.14);
}

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * igg.css - styles for the interactive 3D IgG antibody viewer (js/apps/igg.js).
 * All colours, radii and type come from theme tokens so the component follows
 * the active skin. No brand colours are hardcoded.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.igg__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  align-items: center;
}

@media (min-width: 900px) {
  .igg__grid {
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
  }
}

/* ---- 3D canvas viewport ---- */
.igg__viewport {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.igg__viewport canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
}

.igg__viewport canvas:active {
  cursor: grabbing;
}

/* Floating molecule label, top-left */
.igg__label {
  position: absolute;
  top: 1rem;
  left: 1rem;
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--color-text-secondary);
  pointer-events: none;
}

.igg__label-val {
  color: var(--color-brand-primary);
}

/* Interaction hint, bottom-centre, fades out on first drag */
.igg__hint {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.5s var(--ease);
}

/* ---- Narrative column ---- */
.igg__eyebrow {
  display: block;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-text-secondary);
}

.igg__heading {
  margin: 0.5rem 0 1.25rem;
  font-size: var(--type-scale-3xl);
  font-weight: var(--type-weight-bold);
  color: var(--color-text-primary);
  line-height: 1.15;
}

.igg__lead {
  margin: 0 0 1.5rem;
  font-size: var(--type-scale-base);
  line-height: 1.7;
  color: var(--color-text-secondary);
}

.igg__cards {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.igg__card {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.25rem;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.igg__card:hover {
  border-color: var(--color-border-medium);
  box-shadow: var(--shadow-sm);
}

.igg__icon {
  flex-shrink: 0;
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--r-sm);
  color: var(--color-brand-primary);
  background: color-mix(in srgb, var(--color-brand-primary) 8%, transparent);
}

.igg__icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.igg__card-title {
  margin: 0 0 0.35rem;
  font-size: var(--type-scale-sm);
  font-weight: var(--type-weight-semibold);
  color: var(--color-text-primary);
}

.igg__card-body {
  margin: 0;
  font-size: var(--type-scale-sm);
  line-height: 1.6;
  color: var(--color-text-secondary);
}

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * scada.css: Digital Twin SCADA cleanroom floor-plan component styles.
 * Token-driven throughout (--color-*, --type-*, --r-*, --shadow-*, --dur,
 * --ease); no brand colour is hard-coded. Scoped under [data-scada] and the
 * .scada-section wrapper so it cannot collide with other components.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

/* ============================================================
   Layout
   ============================================================ */
.scada {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

@media (min-width: 900px) {
  .scada {
    grid-template-columns: 2fr 1fr;
    align-items: stretch;
  }
}

.scada__floor {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.scada__facility {
  position: relative;
  min-height: 420px;
  overflow: hidden;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-sm);
  background: var(--color-bg-surface);
}

.scada__caption {
  margin-top: 0.75rem;
  font-family: var(--type-family_mono);
  opacity: 0.75;
}

.scada-svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Pointer routing: only the interactive room zones receive clicks. */
.scada-svg * { pointer-events: none; }
.scada-svg .room-zone { pointer-events: all; }

/* ============================================================
   SVG schematic linework (neutral structure tokens + brand pipes)
   ============================================================ */
.scada-svg .grid-line {
  stroke: var(--color-border-medium);
  stroke-width: 0.25;
  opacity: 0.35;
}

.scada-svg .wall {
  stroke: var(--color-text-secondary);
  stroke-width: 1;
  fill: none;
  opacity: 0.7;
}

.scada-svg .wall--dashed { stroke-dasharray: 6 3; }
.scada-svg .wall--faint { opacity: 0.4; }

.scada-svg .wall-thick {
  stroke: var(--color-text-primary);
  stroke-width: 1.5;
  fill: none;
  opacity: 0.8;
}

.scada-svg .pipe {
  stroke: var(--color-brand-secondary);
  stroke-width: 1.25;
  fill: none;
  opacity: 0.25;
}

.scada-svg .pipe-active {
  stroke: var(--color-brand-secondary);
  stroke-width: 1.25;
  fill: none;
  opacity: 0.45;
}

.scada-svg .pipe--sample {
  opacity: 0.15;
  stroke-dasharray: 4 3;
}

.scada-svg .divider {
  stroke: var(--color-brand-secondary);
  stroke-width: 0.5;
  opacity: 0.15;
  stroke-dasharray: 4 3;
}

.scada-svg .tele-text {
  font-family: var(--type-family_mono);
  font-size: 10px;
  fill: var(--color-text-secondary);
  opacity: 0.8;
}

.scada-svg .zone-text {
  font-family: var(--type-family_mono);
  font-size: 11px;
  fill: var(--color-brand-secondary);
  opacity: 0.6;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.scada-svg .coord-text {
  font-family: var(--type-family_mono);
  font-size: 9px;
  fill: var(--color-text-tertiary);
  opacity: 0.65;
}

/* ============================================================
   Interactive room zones
   ============================================================ */
.scada-svg .room-zone {
  cursor: pointer;
  fill: transparent;
  transition: fill var(--dur) var(--ease), stroke var(--dur) var(--ease);
}

.scada-svg .room-zone:hover {
  fill: color-mix(in srgb, var(--color-brand-primary) 6%, transparent);
}

.scada-svg .room-zone.is-active {
  fill: color-mix(in srgb, var(--color-brand-primary) 9%, transparent);
  stroke: var(--color-brand-primary);
  stroke-width: 1.5;
  opacity: 1;
}

/* ============================================================
   Detail panel
   ============================================================ */
.scada-panel {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--r-md);
  padding: 1.5rem;
  height: 100%;
}

.scada-panel__eyebrow {
  display: block;
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--color-text-tertiary);
}

.scada-panel__hint {
  margin-top: 0.75rem;
  margin-bottom: 1rem;
}

.scada-panel__list {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

/* System list buttons */
.scada-sys-btn {
  display: block;
  text-align: left;
  width: 100%;
  padding: 0.5rem 0.75rem;
  font-family: inherit;
  font-size: var(--type-scale-sm);
  font-weight: var(--type-weight-medium);
  color: var(--color-text-secondary);
  cursor: pointer;
  border: none;
  border-radius: var(--r-sm);
  background: none;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.scada-sys-btn:hover,
.scada-sys-btn.is-active {
  color: var(--color-brand-primary);
  background: color-mix(in srgb, var(--color-brand-primary) 5%, transparent);
}

/* Active state */
.scada-panel__back {
  color: var(--color-brand-accent_interactive);
  border: none;
  background: none;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-medium);
  margin-bottom: 1rem;
  padding: 0;
}

.scada-panel__back:hover { text-decoration: underline; }

.scada-panel__name {
  font-size: var(--type-scale-lg);
  font-weight: var(--type-weight-semibold);
  color: var(--color-text-primary);
  margin-top: 0.5rem;
}

.scada-panel__metric {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-3xl);
  font-weight: var(--type-weight-bold);
  color: var(--color-brand-primary);
  margin-top: 0.75rem;
  line-height: 1.05;
}

.scada-panel__metric-label {
  font-size: var(--type-scale-xs);
  color: var(--color-text-tertiary);
  margin-top: 0.25rem;
  margin-bottom: 1rem;
}

.scada-panel__desc {
  line-height: var(--type-leading-normal);
  margin-bottom: 1rem;
}

.scada-panel__specs { display: block; }

.spec-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.375rem 0;
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: var(--type-scale-xs);
}

.spec-row:last-child { border-bottom: none; }

.spec-row__label { color: var(--color-text-tertiary); }

.spec-row__value {
  font-family: var(--type-family_mono);
  font-weight: var(--type-weight-medium);
  color: var(--color-text-primary);
  text-align: right;
}

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .scada-svg .room-zone,
  .scada-sys-btn {
    transition: none;
  }
}


/* The zone captions are brand-secondary at 60% opacity, and brand-secondary is
   the colour dark mode paints the page with, so they all but vanished there. */
:root[data-theme="dark"] .scada-svg .zone-text {
  fill: var(--color-text-secondary);
  opacity: 0.9;
}

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * venn.css styles the three-circle strategic alignment diagram. Authored
 * entirely against the L0 design tokens; brand colours are never hard-coded.
 *
 * The component sits on a light section by default and inherits correctly on
 * dark ones: every neutral is a token, and the four accents resolve through a
 * single --venn-accent custom property set per [data-accent], so a skin that
 * overrides the brand tokens restyles the diagram with no CSS edit.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.venn {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-8);
  align-items: center;
}

@media (max-width: 60rem) {
  .venn { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Accent resolution ------------------------------------------------- */
.venn [data-accent="primary"]   { --venn-accent: var(--color-brand-primary); }
.venn [data-accent="secondary"] { --venn-accent: var(--color-brand-secondary); }
.venn [data-accent="spark"]     { --venn-accent: var(--color-brand-accent_spark); }
.venn [data-accent="info"]      { --venn-accent: var(--color-status-info); }
/* Amber is derived, not a token: the same spark/danger mix dfi-dashboard uses. */
.venn [data-accent="amber"]     { --venn-accent: color-mix(in srgb, var(--color-brand-accent_spark) 52%, var(--color-status-danger)); }

/* ---- Figure ------------------------------------------------------------ */
.venn__figure {
  min-width: 0;
  display: flex;
  justify-content: center;
}

.venn-svg {
  width: 100%;
  max-width: 30rem;
  height: auto;
  overflow: visible;
}

/* ---- Circles ----------------------------------------------------------- */
.venn-circle {
  fill: var(--venn-accent);
  stroke: var(--venn-accent);
  fill-opacity: 0.06;
  stroke-opacity: 0.35;
  cursor: pointer;
  opacity: 0;
  transform: scale(0.92);
  transform-origin: center;
  transform-box: fill-box;
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease),
    fill-opacity var(--dur) var(--ease),
    stroke-opacity var(--dur) var(--ease);
}

.venn-circle.is-visible { opacity: 1; transform: scale(1); }

.venn-circle.is-active {
  fill-opacity: 0.18;
  stroke-opacity: 0.9;
}

.venn-circle:focus-visible {
  outline: 2px solid var(--color-brand-primary);
  outline-offset: 3px;
}

/* ---- Labels ------------------------------------------------------------ */
.venn-label {
  font-family: var(--type-family_mono);
  font-size: 0.6875rem;
  font-weight: var(--type-weight-semibold);
  letter-spacing: 0.08em;
  fill: var(--color-text-tertiary);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) var(--ease), fill var(--dur) var(--ease);
}

.venn-label.is-visible { opacity: 1; }
.venn-label.is-active  { fill: var(--venn-accent); }

/* ---- Centre badge ------------------------------------------------------ */
.venn-badge {
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}

.venn-badge.is-visible { opacity: 1; }

.venn-badge:focus-visible {
  outline: 2px solid var(--color-brand-primary);
  outline-offset: 3px;
}

.venn-badge__disc {
  fill: var(--venn-accent);
  transition: fill var(--dur) var(--ease);
}

.venn-badge__ring {
  fill: none;
  stroke: var(--venn-accent);
  stroke-width: 1.5;
  stroke-opacity: 0.45;
  transform-origin: center;
  transform-box: fill-box;
  animation: venn-pulse 2.8s var(--ease) infinite;
}

.venn-badge__ring.is-static { animation: none; }

.venn-badge.is-active .venn-badge__ring { stroke-opacity: 0.9; }

.venn-badge__text {
  font-family: var(--type-family_mono);
  font-size: 0.5625rem;
  font-weight: var(--type-weight-bold);
  letter-spacing: 0.06em;
  fill: var(--color-text-on_dark);
  pointer-events: none;
}

@keyframes venn-pulse {
  0%, 100% { transform: scale(1);    stroke-opacity: 0.45; }
  50%      { transform: scale(1.16); stroke-opacity: 0.12; }
}

@media (prefers-reduced-motion: reduce) {
  .venn-badge__ring { animation: none; }
  .venn-circle, .venn-label, .venn-badge { transition: none; }
}

/* ---- Detail panel ------------------------------------------------------ */
.venn-detail {
  min-width: 0;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-left: 3px solid var(--venn-accent, var(--color-border-medium));
  border-radius: var(--r-md);
  padding: var(--space-6);
  opacity: 0;
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.venn-detail.is-shown { opacity: 1; }

.venn-detail__tag {
  display: inline-block;
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--venn-accent, var(--color-text-secondary));
  margin-bottom: var(--space-2);
}

.venn-detail__title {
  font-size: var(--type-scale-xl);
  font-weight: var(--type-weight-semibold);
  line-height: var(--type-leading-snug);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-3);
}

.venn-detail__desc {
  font-size: var(--type-scale-base);
  line-height: var(--type-leading-normal);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-6);
}

/* ---- Metrics ----------------------------------------------------------- */
.venn-detail__metrics {
  display: grid;
  gap: var(--space-3);
  border-top: 1px solid var(--color-border-subtle);
  padding-top: var(--space-4);
}

.venn-metric {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-4);
}

.venn-metric__value {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-lg);
  font-weight: var(--type-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--venn-accent, var(--color-text-primary));
  white-space: nowrap;
}

.venn-metric__label {
  font-size: var(--type-scale-sm);
  line-height: var(--type-leading-snug);
  color: var(--color-text-tertiary);
}

.venn-detail__hint {
  font-size: var(--type-scale-xs);
  color: var(--color-text-tertiary);
  margin: var(--space-6) 0 0;
}

/* ---- Dark sections ----------------------------------------------------- */
/* On a dark band the tokenised surface would be a light card. Use a white
   overlay instead so the panel reads as part of the section, and lift the
   circle fills, which are invisible at 6% over a dark ground. */
.tone-dark .venn-detail,
:root[data-theme="dark"] .venn-detail {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.10);
}

.tone-dark .venn-circle {
  fill-opacity: 0.10;
  stroke-opacity: 0.45;
}

.tone-dark .venn-circle.is-active {
  fill-opacity: 0.24;
  stroke-opacity: 1;
}

.tone-dark .venn-label      { fill: rgba(255, 255, 255, 0.55); }
.tone-dark .venn-detail__hint,
.tone-dark .venn-metric__label { color: rgba(255, 255, 255, 0.55); }
.tone-dark .venn-detail__desc  { color: rgba(255, 255, 255, 0.78); }
.tone-dark .venn-detail__title { color: #fff; }
.tone-dark .venn-detail__metrics { border-top-color: rgba(255, 255, 255, 0.10); }

/*
 * Copyright (c) 2026 Asymm Systems. All rights reserved.
 *
 * waterfall.css styles the capital-stack funding waterfall. Authored entirely
 * against the L0 design tokens; brand colours are never hard-coded. Accents
 * resolve through a single --wf-accent custom property set per [data-accent],
 * so a skin that overrides the brand tokens restyles the chart with no CSS edit.
 *
 * @author Fahim Farook (fahim@asymm.systems)
 */

.waterfall { display: block; }

/* ---- Accent resolution ------------------------------------------------- */
.waterfall [data-accent="primary"]   { --wf-accent: var(--color-brand-primary); }
.waterfall [data-accent="secondary"] { --wf-accent: var(--color-brand-secondary); }
.waterfall [data-accent="spark"]     { --wf-accent: var(--color-brand-accent_spark); }
.waterfall [data-accent="info"]      { --wf-accent: var(--color-status-info); }
/* Amber is derived, not a token: the same spark/danger mix dfi-dashboard uses. */
.waterfall [data-accent="amber"]     { --wf-accent: color-mix(in srgb, var(--color-brand-accent_spark) 52%, var(--color-status-danger)); }

/* ---- Running total ----------------------------------------------------- */
.waterfall__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.waterfall__total {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.waterfall__total-label {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-tertiary);
}

.waterfall__total-value {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-4xl);
  font-weight: var(--type-weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: var(--type-leading-tight);
  color: var(--color-text-primary);
}

.waterfall__share {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-secondary);
}

/* ---- Bar --------------------------------------------------------------- */
.waterfall-bar {
  display: flex;
  width: 100%;
  height: 3.25rem;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--color-bg-sunken);
}

.waterfall-segment {
  position: relative;
  flex: 0 0 auto;
  min-width: 2px;
  height: 100%;
  padding: 0;
  border: 0;
  border-right: 1px solid var(--color-bg-page);
  background: var(--wf-accent);
  cursor: pointer;
  opacity: 0;
  transform: scaleY(0.4);
  transform-origin: bottom;
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease),
    filter var(--dur) var(--ease);
}

.waterfall-segment:last-of-type { border-right: 0; }

.waterfall-segment.is-visible { opacity: 1; transform: scaleY(1); }

/* Selected segment lifts by brightening rather than by moving, so the bar
   never changes height and adjacent segments do not reflow. */
.waterfall-segment.is-active { filter: brightness(1.18) saturate(1.1); }

.waterfall-segment.is-active::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--color-text-primary);
  border-radius: 1px;
  opacity: 0.65;
}

.waterfall-segment:focus-visible {
  outline: 2px solid var(--color-brand-primary);
  outline-offset: 2px;
  z-index: 1;
}

.waterfall-bar__gap {
  flex: 0 0 auto;
  height: 100%;
  background: repeating-linear-gradient(
    135deg,
    transparent,
    transparent 5px,
    var(--color-border-subtle) 5px,
    var(--color-border-subtle) 6px
  );
}

@media (prefers-reduced-motion: reduce) {
  .waterfall-segment { transition: none; }
}

/* ---- Scale rule -------------------------------------------------------- */
.waterfall-scale {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border-subtle);
}

.waterfall-scale__tick {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary);
}

.waterfall-scale__tick.is-end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  text-align: right;
}

.waterfall-scale__value {
  font-weight: var(--type-weight-semibold);
  color: var(--color-text-secondary);
}

.waterfall-scale__caption {
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* ---- Readout ----------------------------------------------------------- */
.waterfall-readout {
  margin-top: var(--space-6);
  padding: var(--space-6);
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-subtle);
  border-left: 3px solid var(--wf-accent, var(--color-border-medium));
  border-radius: var(--r-md);
  opacity: 0;
  transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.waterfall-readout.is-shown { opacity: 1; }

.waterfall-readout__type {
  display: inline-block;
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-xs);
  font-weight: var(--type-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--wf-accent, var(--color-text-secondary));
  margin-bottom: var(--space-2);
}

.waterfall-readout__name {
  font-size: var(--type-scale-xl);
  font-weight: var(--type-weight-semibold);
  line-height: var(--type-leading-snug);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-2);
}

.waterfall-readout__terms {
  font-size: var(--type-scale-base);
  line-height: var(--type-leading-normal);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-6);
}

.waterfall-readout__figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--space-4);
  border-top: 1px solid var(--color-border-subtle);
  padding-top: var(--space-4);
}

.waterfall-figure {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.waterfall-figure__value {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-2xl);
  font-weight: var(--type-weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: var(--type-leading-tight);
  color: var(--wf-accent, var(--color-text-primary));
}

.waterfall-figure__label {
  font-size: var(--type-scale-xs);
  line-height: var(--type-leading-snug);
  color: var(--color-text-tertiary);
}

/* ---- Legend ------------------------------------------------------------ */
.waterfall-legend {
  list-style: none;
  margin: var(--space-6) 0 0;
  padding: 0;
  display: grid;
  gap: 0;
}

.waterfall-legend__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--color-border-subtle);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}

.waterfall-legend__row:last-child { border-bottom: 0; }
.waterfall-legend__row.is-active  { background: var(--color-bg-subtle); }

.waterfall-legend__swatch {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 2px;
  background: var(--wf-accent);
}

.waterfall-legend__name {
  font-size: var(--type-scale-sm);
  color: var(--color-text-primary);
  min-width: 0;
}

.waterfall-legend__amount,
.waterfall-legend__share {
  font-family: var(--type-family_mono);
  font-size: var(--type-scale-sm);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.waterfall-legend__amount { color: var(--color-text-primary); font-weight: var(--type-weight-semibold); }
.waterfall-legend__share  { color: var(--color-text-tertiary); min-width: 3.5rem; }

.waterfall__hint {
  font-size: var(--type-scale-xs);
  color: var(--color-text-tertiary);
  margin: var(--space-4) 0 0;
}

@media (max-width: 40rem) {
  .waterfall-legend__row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .waterfall-legend__share { display: none; }
  .waterfall__total-value { font-size: var(--type-scale-3xl); }
}

/* ---- Dark sections ----------------------------------------------------- */
/* Brand primary is a deep green and brand secondary is the navy the band is
   itself painted in, so both vanish here. Lighten them rather than remapping
   them onto spark and info, which would collapse five segments into two hues
   and destroy the distinction the chart exists to make. Spark and info already
   carry on a dark ground and are left alone. */
.tone-dark .waterfall [data-accent="primary"] {
  --wf-accent: color-mix(in srgb, var(--color-brand-primary) 45%, #FFFFFF);
}
.tone-dark .waterfall [data-accent="secondary"] {
  --wf-accent: color-mix(in srgb, var(--color-brand-secondary_2) 30%, #FFFFFF);
}

/* On a dark band the tokenised surfaces would be light cards, and the sunken
   track disappears. Use white overlays so the chart reads as part of the band. */
.tone-dark .waterfall-bar,
:root[data-theme="dark"] .tone-dark .waterfall-bar {
  background: rgba(255, 255, 255, 0.06);
}

.tone-dark .waterfall-segment { border-right-color: rgba(0, 0, 0, 0.35); }

.tone-dark .waterfall-segment.is-active::after {
  border-color: #fff;
  opacity: 0.85;
}

.tone-dark .waterfall-bar__gap {
  background: repeating-linear-gradient(
    135deg,
    transparent,
    transparent 5px,
    rgba(255, 255, 255, 0.14) 5px,
    rgba(255, 255, 255, 0.14) 6px
  );
}

.tone-dark .waterfall-readout {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.10);
}

.tone-dark .waterfall__total-value,
.tone-dark .waterfall-readout__name,
.tone-dark .waterfall-legend__amount { color: #fff; }

.tone-dark .waterfall__share,
.tone-dark .waterfall-readout__terms,
.tone-dark .waterfall-scale__value { color: rgba(255, 255, 255, 0.78); }

.tone-dark .waterfall__total-label,
.tone-dark .waterfall__hint,
.tone-dark .waterfall-scale__tick,
.tone-dark .waterfall-figure__label,
.tone-dark .waterfall-legend__share { color: rgba(255, 255, 255, 0.55); }

.tone-dark .waterfall-legend__name { color: rgba(255, 255, 255, 0.88); }
.tone-dark .waterfall-legend__row  { border-bottom-color: rgba(255, 255, 255, 0.10); }
.tone-dark .waterfall-legend__row.is-active { background: rgba(255, 255, 255, 0.06); }
.tone-dark .waterfall-scale,
.tone-dark .waterfall-readout__figures { border-top-color: rgba(255, 255, 255, 0.10); }
