/* ===========================================================================
   Omyn Design System — R2 Patterns (composites) · patterns.css
   ---------------------------------------------------------------------------
   The composite layer. Every pattern here is an ASSEMBLY of R1 primitives
   (Button, CTAButton, Card, Badge, StatCard, Eyebrow, Section, Input) sitting
   on R0 foundation tokens. Patterns NEVER re-create a primitive and NEVER
   introduce a raw colour. Where R0/R1 left a structural gap (composite-only
   geometry: nav height, device-frame radii, radar/heatmap layout) a token is
   declared in the R2-LOCAL block below and reported for promotion review.

   Coverage: Header (sticky-nav) · Footer (filiation + compliance badges) ·
             ProductCard · DeviceFrame (iPhone + Watch, pure CSS/SVG) ·
             TimelineStep · PersonaTab (segmented control) · Hero ·
             MaturityRadar + Heatmap (static SVG/CSS spec mockups).

   Light is the default; dark inherits automatically through the R0
   [data-theme="dark"] token re-points. Patterns consume the semantic role
   tokens R0 already flips per mode — they do not re-declare colours per mode.

   English only · no AI attribution · purple forbidden · spec artifact only.
   =========================================================================== */

@import "tokens.css";
@import "primitives.css";

/* ===========================================================================
   R2-LOCAL TOKENS — composite-only geometry that has no home in R0/R1.
   These are STRUCTURAL (sizes/timings of multi-primitive assemblies), not new
   colours. Every colour below still resolves to an R0 brand/neutral token.
   Reported back at release close for promotion-into-R0 vs accept-as-R2-local.
   =========================================================================== */
:root {
  --r2-nav-height:        64px;   /* sticky header bar height (matches R1 demo) */
  --r2-nav-blur:          10px;   /* backdrop blur radius for the glass bar      */
  --r2-nav-scrim:         color-mix(in srgb, var(--surface) 88%, transparent);
  --r2-hero-max:          54ch;   /* hero copy measure                           */

  /* DeviceFrame silhouettes — pure CSS, radii are physical product geometry */
  --r2-phone-w:           220px;
  --r2-phone-h:           448px;
  --r2-phone-radius:      var(--radius-32);
  --r2-phone-bezel:       12px;
  --r2-watch-w:           128px;
  --r2-watch-h:           152px;
  --r2-watch-radius:      36px;   /* between R0 radius-32 and a true squircle    */
  --r2-watch-bezel:       10px;
  --r2-device-shadow:     var(--shadow-card-hover);
  /* device bezel: deep neutral in BOTH modes (a real bezel is dark, so it must
     NOT follow --ink which flips to near-white under dark). Derived from the
     R0 dark navy base so it stays inside the palette, never a raw hex. */
  --r2-device-bezel:      #0B1220;   /* = R0 dark --white base; physical chrome  */

  /* Timeline rail */
  --r2-timeline-dot:      var(--icon-16);
  --r2-timeline-rail:     var(--border-1);

  /* Radar / Heatmap chart spec */
  --r2-chart-grid:        color-mix(in srgb, var(--ink) 12%, transparent);
  --r2-chart-axis:        var(--muted);
  --r2-radar-fill:        color-mix(in srgb, var(--color-primary) 22%, transparent);
  --r2-radar-stroke:      var(--color-primary);
  --r2-radar-fill-accent: color-mix(in srgb, var(--color-accent) 20%, transparent);
  --r2-radar-stroke-accent: var(--color-accent);
  /* heatmap five-step ramp, all derived from the primary brand token */
  --r2-heat-0: color-mix(in srgb, var(--color-primary) 6%,  var(--surface));
  --r2-heat-1: color-mix(in srgb, var(--color-primary) 24%, var(--surface));
  --r2-heat-2: color-mix(in srgb, var(--color-primary) 46%, var(--surface));
  --r2-heat-3: color-mix(in srgb, var(--color-primary) 70%, var(--surface));
  --r2-heat-4: var(--color-primary);
}

/* ===========================================================================
   HEADER — sticky glass nav. Real omyn logo (light/dark swap), nav links,
   trailing CTA. Composes Button/CTAButton + Badge from R1.
   =========================================================================== */
.omyn-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--r2-nav-scrim);
  backdrop-filter: saturate(140%) blur(var(--r2-nav-blur));
  -webkit-backdrop-filter: saturate(140%) blur(var(--r2-nav-blur));
  border-bottom: var(--border-1) solid var(--line);
}
.omyn-header__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--pad-desktop);
  height: var(--r2-nav-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}
.omyn-header__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
}
/* logo swap is driven by the R0 [data-theme] flag */
.omyn-header__logo { height: 26px; width: auto; display: block; }
.omyn-header__logo--light { display: block; }
.omyn-header__logo--dark  { display: none; }
[data-theme="dark"] .omyn-header__logo--light { display: none; }
[data-theme="dark"] .omyn-header__logo--dark  { display: block; }

.omyn-header__nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  margin-inline-start: auto;
}
.omyn-header__link {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  text-decoration: none;
  padding: var(--space-1) 0;
  border-bottom: 2px solid transparent;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.omyn-header__link:hover,
.omyn-header__link[aria-current="page"] {
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.omyn-header__actions { display: flex; align-items: center; gap: var(--space-3); }

/* mobile hamburger (B2) — hidden on desktop, revealed <860px by the media query */
.omyn-burger {
  display: none; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  background: transparent; border: var(--border-1) solid var(--line);
  border-radius: var(--radius-12); color: var(--ink); cursor: pointer;
  transition: border-color 0.2s var(--ease);
}
.omyn-burger:hover { border-color: var(--color-primary); }
.omyn-burger .material-symbols-outlined { font-size: 22px; }

@media (max-width: 860px) {
  .omyn-header__inner { padding-inline: var(--pad-mobile); position: relative; }
  .omyn-burger { display: inline-flex; }
  /* the desktop CTA is redundant on mobile — the in-menu "Get started" covers it */
  .omyn-header__actions .btn { display: none; }
  /* collapse the toggles to icon-only so brand + actions fit 360–390px without
     overflowing (overflow → sideways page scroll → the open menu drifts off) */
  .omyn-header [data-omyn-lang-label],
  .omyn-header [data-omyn-theme-label] { display: none; }
  .omyn-header .toggle { padding: 7px; gap: 0; }
  /* nav collapses; revealed as a vertical panel only when the burger opens it */
  .omyn-header__nav { display: none; }
  .omyn-header[data-omyn-mobile-open] .omyn-header__nav {
    display: flex; flex-direction: column; align-items: stretch; gap: var(--space-2);
    position: absolute; top: 100%; left: 0; right: 0; margin: 0;
    background: var(--surface); border-bottom: var(--border-1) solid var(--line);
    box-shadow: var(--shadow-card); padding: var(--space-4) var(--pad-mobile);
  }
  /* mega panel rendered inline (no hover) inside the open menu */
  .omyn-header[data-omyn-mobile-open] .omyn-nav-item { display: block; }
  .omyn-header[data-omyn-mobile-open] .omyn-nav-item::after { display: none; }
  .omyn-header[data-omyn-mobile-open] .omyn-mega {
    display: grid; grid-template-columns: 1fr; gap: var(--space-2);
    position: static; opacity: 1; visibility: visible; transform: none;
    min-width: 0; border: 0; box-shadow: none; padding: var(--space-2) 0; background: transparent;
  }
}

/* The header follows the page theme (Sacha 2026-06-25): in dark mode the bar is
   dark like the rest of the page (no white light-island). The neutral tokens
   inherit the R0 [data-theme="dark"] values, so --r2-nav-scrim recomputes dark
   and the logo swap (above) shows the off-white wordmark. */

/* ---------------------------------------------------------------------------
   ÉPURE two-angle mega-menu (promoted to R2 canon from home.html page-local,
   2026-06-25). Interaction pattern borrowed from diana-dev.com (fixed bar +
   on-demand mega-panel with two "angles de vue"); Omyn tricolore DS kept
   (tokens only, no raw hex). CSS-only: hover + :focus-within (keyboard).
   Lives inside .omyn-header so it inherits the light-island token re-point.
   --------------------------------------------------------------------------- */
.omyn-nav-item { position: relative; display: flex; align-items: center; }
/* invisible hover bridge across the gap so the panel stays open */
.omyn-nav-item::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 14px; }
.omyn-nav-trigger {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: var(--fw-medium);
  color: var(--ink-2); background: none; border: 0; padding: var(--space-1) 0;
  border-bottom: 2px solid transparent;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.omyn-nav-item:hover .omyn-nav-trigger,
.omyn-nav-item:focus-within .omyn-nav-trigger { color: var(--color-primary); border-color: var(--color-primary); }
.omyn-nav-trigger .material-symbols-outlined { font-size: 18px; transition: transform 0.22s var(--ease); }
.omyn-nav-item:hover .omyn-nav-trigger .material-symbols-outlined,
.omyn-nav-item:focus-within .omyn-nav-trigger .material-symbols-outlined { transform: rotate(180deg); }
.omyn-mega {
  position: absolute; top: calc(100% + 14px); left: 50%;
  transform: translateX(-50%) translateY(-6px);
  min-width: 540px; background: var(--surface);
  border: var(--border-1) solid var(--line); border-radius: var(--radius-16);
  box-shadow: var(--shadow-card-hover); padding: var(--space-5);
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5);
  opacity: 0; visibility: hidden;
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease), visibility 0.22s var(--ease);
}
.omyn-nav-item:hover .omyn-mega,
.omyn-nav-item:focus-within .omyn-mega { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.omyn-mega__col { display: flex; flex-direction: column; gap: 2px; }
.omyn-mega__head {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); margin-bottom: var(--space-2); padding: 0 10px;
}
.omyn-mega__link {
  display: flex; align-items: flex-start; gap: var(--space-3); text-decoration: none;
  color: var(--ink); font-size: var(--fs-sm); padding: 9px 10px; border-radius: var(--radius-8);
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.omyn-mega__link:hover { background: var(--color-primary-wash); color: var(--color-primary); }
.omyn-mega__link .material-symbols-outlined { font-size: 18px; color: var(--color-primary); margin-top: 1px; flex: none; }
.omyn-mega__link b { font-weight: var(--fw-medium); display: block; }
.omyn-mega__link small { display: block; color: var(--ink-2); font-size: var(--fs-xs); margin-top: 1px; }
@media (max-width: 860px) { .omyn-mega, .omyn-nav-item::after { display: none; } }

/* ===========================================================================
   FOOTER — filiation line + EU AI Act / EHDS compliance badges + meta column.
   Composes Badge from R1.
   =========================================================================== */
.omyn-footer {
  border-top: var(--border-1) solid var(--line);
  background: var(--surface);
  padding-block: var(--space-7);
}
.omyn-footer__inner {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--pad-desktop);
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--space-6);
  align-items: start;
}
.omyn-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
/* align-self pins the cross-axis so the column's default stretch does not
   deform the replaced <img> (height fixed, width intrinsic). */
.omyn-footer__logo { height: 24px; width: auto; align-self: flex-start; max-width: 100%; object-fit: contain; }
.omyn-footer__logo--light { display: block; }
.omyn-footer__logo--dark  { display: none; }
[data-theme="dark"] .omyn-footer__logo--light { display: none; }
[data-theme="dark"] .omyn-footer__logo--dark  { display: block; }
.omyn-footer__filiation {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  max-width: 46ch;
  line-height: 1.6;
}
.omyn-footer__filiation b { color: var(--ink); font-weight: var(--fw-medium); }
.omyn-footer__compliance {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}
.omyn-footer__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.omyn-footer__coltitle {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.omyn-footer__navlink {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}
.omyn-footer__navlink:hover { color: var(--color-primary); }
.omyn-footer__legal {
  grid-column: 1 / -1;
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: var(--border-1) solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
}
@media (max-width: 860px) {
  .omyn-footer__inner { grid-template-columns: 1fr; padding-inline: var(--pad-mobile); }
}

/* ===========================================================================
   PRODUCTCARD — a Card specialised for a product / offer. Composes Card +
   Eyebrow + Badge + Button. Optional --accent rail (tricolore tonic) marks a
   flagship offer.
   =========================================================================== */
.product-card {
  /* inherits .card from R1; add structural layout only */
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  position: relative;
  overflow: hidden;
}
.product-card__icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-12);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--tint-primary);
  color: var(--color-primary);
}
.product-card__icon .material-symbols-outlined { font-size: var(--icon-20); }
.product-card__title {
  font-family: var(--font-body);
  font-size: var(--fs-h3);
  font-weight: var(--fw-bold);
  letter-spacing: -0.02em;
}
.product-card__body { color: var(--ink-2); }
.product-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}
.product-card__foot {
  margin-top: auto;
  padding-top: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
/* flagship accent rail — tricolore tonic on the leading edge */
.product-card--accent::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--space-1);
  background: var(--color-accent);
}
.product-card--accent .product-card__icon {
  background: var(--tint-accent);
  color: var(--color-accent);
}

/* ===========================================================================
   DEVICEFRAME — pure-CSS iPhone + Watch silhouettes. The screen slot takes
   arbitrary child content (a mock UI). No images, no SVG required for the
   chrome itself.
   =========================================================================== */
.device {
  display: inline-block;
  position: relative;
}
/* --- iPhone --- */
.device--phone {
  width: var(--r2-phone-w);
  height: var(--r2-phone-h);
  border-radius: var(--r2-phone-radius);
  padding: var(--r2-phone-bezel);
  background: var(--r2-device-bezel);
  box-shadow: var(--r2-device-shadow);
}
.device--phone .device__screen {
  width: 100%;
  height: 100%;
  border-radius: calc(var(--r2-phone-radius) - var(--r2-phone-bezel));
  background: var(--surface);
  overflow: hidden;
  position: relative;
}
/* notch / dynamic-island pill */
.device--phone .device__notch {
  position: absolute;
  top: calc(var(--r2-phone-bezel) + var(--space-2));
  left: 50%;
  transform: translateX(-50%);
  width: 64px;
  height: var(--r2-phone-bezel);
  border-radius: var(--radius-pill);
  background: var(--r2-device-bezel);
  z-index: 2;
}
/* --- Apple Watch --- */
.device--watch {
  width: var(--r2-watch-w);
  height: var(--r2-watch-h);
  border-radius: var(--r2-watch-radius);
  padding: var(--r2-watch-bezel);
  background: var(--r2-device-bezel);
  box-shadow: var(--r2-device-shadow);
  position: relative;
}
.device--watch .device__screen {
  width: 100%;
  height: 100%;
  border-radius: calc(var(--r2-watch-radius) - var(--r2-watch-bezel));
  background: var(--surface);
  overflow: hidden;
}
/* digital crown nub */
.device--watch::after {
  content: "";
  position: absolute;
  right: -4px;
  top: 38%;
  width: 5px;
  height: 26px;
  border-radius: 3px;
  background: var(--muted);
}
.device__screen-pad { padding: var(--space-3); height: 100%; display: flex; flex-direction: column; gap: var(--space-2); }

/* ===========================================================================
   TIMELINESTEP — a vertical process rail. Each step is a dot on a hairline
   rail with an index, title and body. Composes Eyebrow + Badge.
   =========================================================================== */
.timeline { display: flex; flex-direction: column; }
.timeline__step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  padding-bottom: var(--space-6);
}
.timeline__step:last-child { padding-bottom: 0; }
.timeline__marker {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.timeline__dot {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--on-brand);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.timeline__step--done .timeline__dot { background: var(--color-primary); }
.timeline__step--current .timeline__dot {
  background: var(--color-accent);          /* tricolore tonic marks "you are here" */
  box-shadow: 0 0 0 var(--focus-ring-width) var(--tint-accent);
}
.timeline__step--todo .timeline__dot {
  background: var(--surface);
  color: var(--muted);
  border: var(--border-1) solid var(--line);
}
.timeline__rail {
  flex: 1;
  width: var(--r2-timeline-rail);
  background: var(--line);
  margin-block: var(--space-1);
}
.timeline__step:last-child .timeline__rail { display: none; }
.timeline__title {
  font-family: var(--font-body);
  font-size: var(--fs-lead);
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
}
.timeline__body { color: var(--ink-2); margin-top: var(--space-2); font-size: var(--fs-sm); }

/* ===========================================================================
   PERSONATAB — segmented control. A pill rail with an active blue segment.
   Single-select; the active segment carries the primary fill.
   =========================================================================== */
.persona-tabs {
  display: inline-flex;
  gap: var(--space-1);
  padding: var(--space-1);
  background: var(--bg-2);
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius-pill);
}
.persona-tab {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.persona-tab .material-symbols-outlined { font-size: var(--icon-18); }
.persona-tab:hover { color: var(--color-primary); }
.persona-tab[aria-selected="true"] {
  background: var(--color-primary);
  color: var(--on-brand);
  box-shadow: var(--shadow-pill);
}
.persona-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
}

/* ===========================================================================
   HERO — the page-opening band. Composes Eyebrow + section title + lead +
   CTAButton + StatCard rail. Two-column on desktop (copy + visual slot).
   =========================================================================== */
.hero {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--space-8) var(--pad-desktop);
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--space-7);
  align-items: center;
}
/* min-width:0 lets the copy column shrink below its content's intrinsic min,
   so a long hero word can't blow the grid track past the mobile viewport */
.hero__copy { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.hero__title {
  font-family: var(--font-body);
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
  letter-spacing: -0.03em;
  line-height: 1.02;
  max-width: var(--r2-hero-max);
  overflow-wrap: anywhere;
}
/* tricolore tonic on a single load-bearing word */
.hero__title em { color: var(--color-accent); font-style: normal; }
.hero__lead {
  font-size: var(--fs-lead);
  color: var(--ink-2);
  max-width: var(--r2-hero-max);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-2); }
.hero__proof {
  display: flex;
  gap: var(--space-6);
  margin-top: var(--space-5);
  flex-wrap: wrap;
}
.hero__visual {
  display: flex;
  align-items: center;
  justify-content: center;
  /* min-width:0 lets the visual column shrink below its content's intrinsic
     min, so the non-wrapping <pre> codeblock scrolls internally (overflow:auto)
     instead of forcing the grid track past the mobile viewport */
  min-width: 0;
}
/* the visual card + its non-wrapping codeblock must not establish a content
   floor wider than the (now shrinkable) grid track: clamp both to the column
   and let the codeblock scroll horizontally inside the card */
.hero__visual .card { min-width: 0; max-width: 100%; }
.hero__visual .codeblock { max-width: 100%; overflow-x: auto; }
@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; padding-inline: var(--pad-mobile); padding-block: var(--space-7); }
  .hero__title { font-size: var(--fs-h1); }
  .hero__visual { order: -1; }
  /* the ghost CTA label is long; let hero CTAs wrap instead of forcing the
     copy column past the viewport (.cta is nowrap by default) */
  .hero__actions .cta { white-space: normal; }
}

/* ===========================================================================
   MATURITYRADAR — STATIC SVG/CSS spec mockup. Establishes the visual contract
   (polar grid rings, axes, tricolore series fills, legend) that the PRODUCTION
   build binds Recharts <RadarChart> to. NO React here — spec artifact only.
   Production note: Recharts <Radar> stroke/fill = --r2-radar-stroke/-fill;
   grid = --r2-chart-grid; ticks = --r2-chart-axis.
   =========================================================================== */
.radar { display: flex; flex-direction: column; gap: var(--space-4); }
.radar__svg { width: 100%; height: auto; display: block; max-width: 360px; margin-inline: auto; }
.radar__grid    { fill: none; stroke: var(--r2-chart-grid); stroke-width: 1; }
.radar__axis    { stroke: var(--r2-chart-grid); stroke-width: 1; }
.radar__label   { fill: var(--muted); font-family: var(--font-mono); font-size: 10px; }
.radar__series  { fill: var(--r2-radar-fill); stroke: var(--r2-radar-stroke); stroke-width: 2; }
.radar__series--accent { fill: var(--r2-radar-fill-accent); stroke: var(--r2-radar-stroke-accent); stroke-width: 2; }
.radar__dot     { fill: var(--r2-radar-stroke); }
.radar__dot--accent { fill: var(--r2-radar-stroke-accent); }
.radar__legend { display: flex; gap: var(--space-4); justify-content: center; flex-wrap: wrap; }
.radar__legend-item {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-2);
}
.radar__swatch { width: 14px; height: 14px; border-radius: var(--radius-8); display: inline-block; }
.radar__swatch--primary { background: var(--r2-radar-stroke); }
.radar__swatch--accent  { background: var(--r2-radar-stroke-accent); }

/* ===========================================================================
   HEATMAP — STATIC CSS-grid spec mockup. A maturity matrix; cell intensity is
   the five-step primary ramp (--r2-heat-0..4). PRODUCTION binds Recharts or a
   data-driven grid to the same ramp. NO React here — spec artifact only.
   =========================================================================== */
.heatmap { display: flex; flex-direction: column; gap: var(--space-3); overflow-x: auto; }
.heatmap__grid {
  display: grid;
  grid-template-columns: auto repeat(var(--r2-heat-cols, 5), 1fr);
  gap: var(--space-1);
  min-width: 420px;
}
.heatmap__corner { }
.heatmap__colhead,
.heatmap__rowhead {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  display: flex;
  align-items: center;
}
.heatmap__colhead { justify-content: center; text-align: center; padding-bottom: var(--space-1); }
.heatmap__rowhead { padding-right: var(--space-2); white-space: nowrap; }
.heatmap__cell {
  aspect-ratio: 1 / 1;
  min-width: 40px;
  border-radius: var(--radius-8);
  border: var(--border-1) solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
}
.heatmap__cell[data-level="0"] { background: var(--r2-heat-0); color: var(--ink-2); }
.heatmap__cell[data-level="1"] { background: var(--r2-heat-1); color: var(--ink-2); }
.heatmap__cell[data-level="2"] { background: var(--r2-heat-2); color: var(--ink); }
.heatmap__cell[data-level="3"] { background: var(--r2-heat-3); color: var(--on-brand); }
.heatmap__cell[data-level="4"] { background: var(--r2-heat-4); color: var(--on-brand); }
.heatmap__legend {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
}
.heatmap__scale { display: inline-flex; gap: 2px; }
.heatmap__scale span {
  width: 18px; height: 14px; border-radius: 3px; display: inline-block;
  border: var(--border-1) solid var(--line);
}

/* =====================================================================
   CONTEXTUAL SECTION SUB-NAV (D-NAV-2) — a separate wayfinding element,
   distinct from the invariant global beacon header (D-NAV-1). Holds the
   current page's in-page section anchors; the beacon never does.
   ===================================================================== */
.omyn-subnav {
  display: flex; align-items: center; gap: var(--space-1);
  overflow-x: auto; scrollbar-width: none;
  padding: 10px var(--space-5);
  background: var(--surface);
  border-bottom: var(--border-1) solid var(--line);
}
.omyn-subnav::-webkit-scrollbar { display: none; }
.omyn-subnav__label {
  flex: none; margin-right: var(--space-2);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
.omyn-subnav__link {
  flex: none; white-space: nowrap; text-decoration: none;
  color: var(--ink-2); font-size: var(--fs-sm);
  padding: 5px 12px; border-radius: var(--radius-8);
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.omyn-subnav__link:hover,
.omyn-subnav__link[aria-current="page"] {
  background: var(--color-primary-wash); color: var(--color-primary-strong);
}
