@charset "utf-8";
/* ==========================================================================
   page-builds.css — Builds catalogue page
   Scoped styles for builds.html only. Theme variables come from the band
   (.band--dark / .band--light / .band--void); never hardcode a colour here.
   Order follows the document.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Hero — .bhero
   -------------------------------------------------------------------------- */

.bhero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* The hero carries the page on scale alone, but the 50ms rule needs the
     primary CTA visible without scrolling at 1440 — and this headline is four
     lines. Air stays generous at the bottom, tightens at the top. */
  padding-block: calc(var(--band-y) * 0.92) calc(var(--band-y) * 1.15);
}

/* The headline spans the full measure so its two lines can each hold a whole
   phrase; the lead + CTA and the figure sit under it as the two-column row.
   This is what lets the colour switch land on the line break instead of
   mid-phrase, and it keeps one left margin from eyebrow to card grid. */
.bhero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas:
    "head head"
    "copy fig";
  /* start, not center: centering the short copy column against the tall figure
     opened a screen-wide dead zone directly under the headline */
  align-items: start;
  column-gap: clamp(2.5rem, 5vw, var(--s-16));
  row-gap: clamp(1.75rem, 2.6vw, var(--s-10));
}

.bhero__head {
  grid-area: head;
  display: grid;
  gap: var(--s-5);
  min-width: 0;
}

.bhero__copy {
  grid-area: copy;
  display: grid;
  gap: var(--s-6);
  align-content: start;
  max-width: 42rem;
  min-width: 0;
}

/* Sized so BOTH lines fit the full measure without wrapping: the longer line
   is ~10.4em, so the cap sits well inside a 1440 shell. */
.bhero__title {
  margin: 0;
  font-size: clamp(1.85rem, 5.7vw, 5.35rem);
  line-height: 1.03;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.bhero__title-l {
  display: block;
}

.bhero__title-accent {
  color: var(--accent);
}

/* On dark bands the accent gets a cyan→blue wash. */
.band--dark .bhero__title-accent,
.band--void .bhero__title-accent {
  background: linear-gradient(100deg, var(--cyan-hi) 0%, var(--blue-hi) 92%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.bhero__lead {
  margin: 0;
  max-width: 46ch;
  color: var(--body);
}

.bhero__cta {
  margin-top: var(--s-2);
  align-items: center;
  flex-wrap: wrap;
}

/* .bhero__synthetic is gone: DISCLOSURE-POLICY.md keeps the page's single
   statement out of the hero, where it competed with the headline and CTA. */

/* --- hero figure -------------------------------------------------------- */

/* The plate itself is the shared `.figure` primitive (core.css §9b) — padding,
   radius, hairline, shadow all come from there so this diagram sits on exactly
   the same card as every other diagram on the site. Only the internal layout
   and the hero-specific glow are page work. */
/* Tinted plate: the matrix was reading as an empty white box from a metre.
   The wash gives the drawing a field to sit on before a single stroke lands. */
.bhero__figure {
  grid-area: fig;
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: var(--s-5);
  min-width: 0;
  width: 100%;
  max-width: 680px;
  justify-self: end;
  background:
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--accent) 9%, var(--bg-card)) 0%,
      var(--bg-card) 78%
    );
}

.bhero__figure-glow {
  position: absolute;
  left: 50%;
  top: 44%;
  width: min(720px, 118%);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: var(--r-pill);
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at 50% 50%,
    color-mix(in srgb, var(--cyan) 20%, transparent) 0%,
    color-mix(in srgb, var(--blue) 12%, transparent) 42%,
    transparent 68%
  );
  filter: blur(24px);
  opacity: 0.85;
}

.band--light .bhero__figure-glow,
.band--paper-white .bhero__figure-glow {
  opacity: 0.3;
}

/* --------------------------------------------------------------------------
   1b. Diagram palette — page-scoped, band-aware
   Every inline SVG on this page paints from these --dg-* variables instead of
   hardcoded hex, so a graphic authored for the dark canvas cannot go invisible
   when its band flips to light. Light values are the deep-teal / navy pairing:
   saturated enough to hold a 2.5–3px stroke on white.
   -------------------------------------------------------------------------- */

svg.matrixfig,
svg.spine,
svg.thumb {
  /* shared diagram-kit channel (core.css §9b reads these) — LIGHT band */
  --rf-ch-0: #2f9aa8; /* channel / connector — deep teal */
  --rf-ch-1: #1077d7; /* system action */
  --rf-ch-2: #0b4f8a; /* terminal / outcome */
  --rf-node-0: #0b4f8a;
  --rf-node-1: #1077d7;
  --rf-node-2: #2f9aa8;
  --rf-port: #2f9aa8;
  --rf-ring: #cfe2ea;
  --rf-out: #0b4f8a;
  --rf-label: #5a6b7a;
  --rf-amber: #8a5d05; /* text-safe: this scope paints labels on white */

  /* page aliases — every SVG paints through these, never a literal hex */
  --dg-ch: var(--rf-ch-0); /* channel / connector */
  --dg-ch-ink: #1c6b76; /* teal that has to read as TEXT on white */
  --dg-ch-soft: #8fc9d2;
  --dg-blue: var(--rf-ch-1); /* system action */
  --dg-navy: var(--rf-ch-2); /* outcome / terminal node */
  --dg-amber: var(--rf-amber); /* human attention */
  --dg-amber-ink: #8a5d05; /* amber that has to read as TEXT on white */
  --dg-amber-wash: #fdf3e0;
  --dg-ink: #10202e;
  --dg-label: var(--rf-label);
  --dg-plate: #ffffff;
  --dg-plate-2: #eff5fa;
  --dg-hair: var(--rf-ring);
}

.band--dark svg.matrixfig,
.band--void svg.matrixfig,
.band--dark svg.spine,
.band--void svg.spine,
.band--dark svg.thumb,
.band--void svg.thumb {
  --rf-ch-0: #7ce7f0;
  --rf-ch-1: #4fa9f5;
  --rf-ch-2: #9ad2ff;
  --rf-node-0: #9ad2ff;
  --rf-node-1: #4fa9f5;
  --rf-node-2: #7ce7f0;
  --rf-port: #7ce7f0;
  --rf-ring: #2a3644;
  --rf-out: #9ad2ff;
  --rf-label: #93a1af;
  --rf-amber: #e7a63a;

  --dg-ch-ink: #7ce7f0;
  --dg-ch-soft: #2b6570;
  --dg-amber-ink: #e7a63a;
  --dg-amber-wash: #1a1408;
  --dg-ink: #e8eef5;
  --dg-plate: #101821;
  --dg-plate-2: #0f141c;
}

/* --------------------------------------------------------------------------
   1c. Diagram-kit safety layer
   The marks below are core.css §9b primitives. These rules are wrapped in
   :where() so they carry ZERO specificity: if core.css defines the kit (it
   does), core wins outright. This only guarantees the geometry contract
   survives if this page is ever rendered without the kit. Values are the
   contract verbatim — channel 2.5 light / 2 dark, output 3, port r4, node r17,
   human amber dashed 4 4, labels mono 10.5 / 1.4 tracking.
   -------------------------------------------------------------------------- */

svg :where(.dg-channel) {
  fill: none;
  stroke: var(--rf-ch-0);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.band--dark svg :where(.dg-channel),
.band--void svg :where(.dg-channel) {
  stroke-width: 2;
}

svg :where(.dg-output) {
  fill: none;
  stroke: var(--rf-out);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

svg :where(.dg-port) {
  fill: var(--rf-port);
  stroke: none;
}

svg :where(.dg-node) {
  fill: var(--rf-node-0);
  stroke: none;
}

svg :where(.dg-ring) {
  fill: none;
  stroke: var(--rf-ring);
  stroke-width: 1.5;
}

svg :where(.dg-human) {
  fill: none;
  stroke: var(--rf-amber);
  stroke-width: 2;
  stroke-dasharray: 4 4;
  stroke-linecap: round;
}

svg :where(.dg-human-dot) {
  fill: var(--rf-amber);
  stroke: none;
}

svg :where(.dg-label) {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  fill: var(--rf-label);
}

svg :where(.dg-label--accent) {
  fill: var(--rf-ch-1);
}

svg :where(.dg-label--human) {
  fill: var(--dg-amber-ink);
}

svg :where(.dg-plate) {
  fill: var(--dg-plate);
  stroke: var(--rf-ring);
  stroke-width: 2;
  rx: 10;
}

svg :where(.dg-plate--active) {
  stroke: var(--rf-ch-1);
  stroke-width: 2.5;
}

svg :where(.dg-plate--human) {
  fill: var(--dg-amber-wash);
  stroke: var(--rf-amber);
  stroke-width: 2;
  stroke-dasharray: 4 4;
}

/* --------------------------------------------------------------------------
   2. Matrix diagram (hero) — .matrixfig
   -------------------------------------------------------------------------- */

/* [viewBox] raises specificity above core.css's generic `svg[viewBox]` cap */
.bhero__figscroll {
  position: relative;
  z-index: 1;
  width: 100%;
  min-width: 0;
}

svg.matrixfig[viewBox] {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  max-width: 100%;
  margin-inline: auto;
  overflow: visible;
  font-family: var(--font-mono);
}

/* Row names are .dg-label like every other mark on the site — one type size,
   one family. They differ only in ink, which is what makes them read as the
   row's name rather than a stage caption. */
.mx-name {
  fill: var(--dg-ink);
  font-weight: 700;
}

/* One matrix, two cuts. The wide one carries six column headers; the narrow
   one keeps the rows, the amber human stop and the outcome. Only ever one of
   them is in the document flow. */
/* [viewBox] matches the specificity of the svg.matrixfig[viewBox] block above,
   which sets display:block — a bare class selector would lose to it. */
svg.matrixfig--mob[viewBox] {
  display: none;
}

.mx-owner {
  fill: var(--dg-blue);
}

.mx-done {
  fill: var(--dg-navy);
}

/* Channel stroke. The contract floor is 2.5 on light, but the critics read
   this figure as an empty white box from a metre away — so the hero cut runs
   heavier (3.6 / 3) and the labels step up with it. */
.mx-line {
  fill: none;
  stroke-width: 3.6;
  stroke-linecap: round;
}

.band--dark .mx-line,
.band--void .mx-line {
  stroke-width: 3;
}

/* alternating row field — turns six identical lines into a readable ledger */
.mx-band {
  fill: var(--dg-plate-2);
}

/* trigger marks: one silhouette per kind of trigger */
.mx-trig {
  fill: var(--rf-port);
  stroke: none;
}

.mx-trig--open {
  fill: none;
  stroke: var(--rf-port);
  stroke-width: 2.8;
}

.mx-trig--rule {
  fill: none;
  stroke: var(--rf-port);
  stroke-width: 3;
  stroke-linecap: round;
}

/* Hero cut only: type large enough to survive the metre test. The narrow cut
   keeps the 10.5 contract because its measure is 312 units wide. */
svg.matrixfig--desk .dg-label {
  font-size: 12px;
  letter-spacing: 1.3px;
}

svg.matrixfig--desk .mx-name {
  font-size: 12px;
}

/* work travelling the row, pausing at the amber human stop */
.mxpk {
  fill: var(--dg-blue);
  stroke: var(--dg-plate);
  stroke-width: 1.5;
  offset-rotate: 0deg;
}

.mxpk--a {
  offset-path: path("M130 76 H532");
  animation: mx-run 5.4s var(--e-inout) infinite;
}

.mxpk--b {
  offset-path: path("M130 220 H532");
  animation: mx-run 5.4s var(--e-inout) infinite 2.4s;
}

@keyframes mx-run {
  0% {
    offset-distance: 0%;
    opacity: 0;
  }
  6% {
    opacity: 1;
  }
  44% {
    offset-distance: 83%;
    opacity: 1;
  }
  60% {
    offset-distance: 83%;
    opacity: 1;
  }
  82% {
    offset-distance: 100%;
    opacity: 1;
  }
  92%,
  100% {
    offset-distance: 100%;
    opacity: 0;
  }
}

/* rides on .figure__cap — this only sets the hero-specific width and rule */
.bhero__figcap {
  position: relative;
  z-index: 1;
  margin: 0;
  width: 100%;
  max-width: 560px;
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-soft);
  text-align: center;
}

/* --------------------------------------------------------------------------
   3. Spine diagram — .spine
   -------------------------------------------------------------------------- */

/* .figure (core.css §9b) supplies the plate — padding, radius, hairline,
   shadow. Only the page-specific width and rhythm live here. */
.spine-plate {
  margin: var(--s-10) auto var(--s-4);
  max-width: 1040px;
}

svg.spine[viewBox] {
  display: block;
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
  overflow: visible;
  font-family: var(--font-mono);
}

.sppk {
  fill: var(--dg-blue);
  stroke: var(--dg-plate);
  stroke-width: 2;
  offset-path: path("M70 170 H970");
  offset-rotate: 0deg;
  animation: sp-run 6.5s var(--e-inout) infinite;
}

@keyframes sp-run {
  0% {
    offset-distance: 0%;
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  /* pause just SHORT of the amber stop — parking a blue packet on top of the
     focal node reads as a blemish, not as waiting for a decision */
  46% {
    offset-distance: 74%;
    opacity: 1;
  }
  62% {
    offset-distance: 74%;
    opacity: 1;
  }
  84% {
    offset-distance: 100%;
    opacity: 1;
  }
  94%,
  100% {
    offset-distance: 100%;
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   4. The frame — .frame (what every build is made of)
   -------------------------------------------------------------------------- */

.frame {
  list-style: none;
  margin: var(--s-10) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-8) var(--s-10);
}

.frame__step {
  position: relative;
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
  min-width: 0;
}

.frame__step::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 32px;
  height: 1px;
  background: var(--accent);
  opacity: 0.85;
}

.frame__n {
  margin: 0 0 var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink);
}

.frame__b {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

/* the human-handoff step is amber — attention, never decorative */
.frame__step--human {
  border-top-color: color-mix(in srgb, var(--amber) 55%, var(--line));
}

.frame__step--human::before {
  background: var(--amber);
  opacity: 1;
}

.frame__step--human .frame__n {
  color: var(--amber);
}

/* --------------------------------------------------------------------------
   5. Catalogue — .catalog and the build cards
   -------------------------------------------------------------------------- */

/* the catalog head carries the one mid-page CTA the page was missing */
.catalog__intro {
  align-content: start;
  justify-items: start;
}

.catalog__intro > .btn {
  margin-top: var(--s-1);
}

.catalog {
  gap: var(--s-6);
  align-items: stretch;
}

/* A build card is deliberately thin: a bespoke thumbnail, a number, a title,
   ONE line, industry chips, one link. Trigger/action/record/owner detail lives
   on the demo page — the hero matrix already tells that story. */
.bcard {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
  height: 100%;
  border-radius: var(--r-xl);
  transition:
    transform var(--d-3) var(--e-out),
    box-shadow var(--d-3) var(--e-out),
    border-color var(--d-3) var(--e-out);
}

.bcard:hover,
.bcard:focus-within {
  transform: translateY(-5px);
  box-shadow: var(--shadow-lift);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}

/* --- card plate: the bespoke diagram ------------------------------------- */

/* Six line-art thumbnails in one ramp blurred into a single texture on a fast
   scroll. The drawings keep the shared vocabulary; the plate under each one
   rotates through the ramp so the row reads as six things, not one wallpaper. */
.bcard__plate {
  position: relative;
  padding: var(--s-5) var(--s-4);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(
      130% 120% at 50% 0%,
      color-mix(in srgb, var(--plate-tint, var(--accent)) 18%, transparent) 0%,
      transparent 76%
    ),
    var(--bg-card-2);
}

/* no two neighbours share a tint, across the row or down the column */
.catalog > .bcard:nth-child(2),
.catalog > .bcard:nth-child(6) {
  --plate-tint: var(--blue);
}

.catalog > .bcard:nth-child(3),
.catalog > .bcard:nth-child(4) {
  --plate-tint: var(--cyan);
}

svg.thumb[viewBox] {
  display: block;
  width: 100%;
  max-width: 100%;
  margin-inline: auto;
  overflow: visible;
  font-family: var(--font-mono);
  transition: transform var(--d-4) var(--e-out);
}

.bcard:hover svg.thumb[viewBox] {
  transform: scale(1.035);
}

/* Weight-matching: the sparkline in 05 was hairline next to 04's checklist.
   One drawing weight across all six plates. */
svg.thumb .spark {
  stroke-width: 3.4;
}

.band--dark svg.thumb .spark,
.band--void svg.thumb .spark {
  stroke-width: 3;
}

/* Card diagram type is .dg-label — the same primitive the hero matrix and the
   spine use. There is deliberately no page-local label class any more. */

/* --- card body ----------------------------------------------------------- */

.bcard__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  flex: 1 1 auto;
  padding: var(--s-6);
  min-width: 0;
}

.bcard__idx {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.bcard__idx > span {
  display: inline-grid;
  place-items: center;
  min-width: 1.55rem;
  height: 1.55rem;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* Titles are one or two lines depending on the phrase. Reserving two lines
   keeps every body line, chip row and link in a row on the same baseline
   instead of stepping down wherever a title happens to wrap. */
.bcard__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-title-1);
  line-height: 1.2;
  letter-spacing: -0.018em;
  color: var(--ink);
  text-wrap: balance;
}

@media (min-width: 561px) {
  .bcard__title {
    min-block-size: 2.4em;
  }
}

.bcard__line {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--body);
  text-wrap: pretty;
}

/* --- industry chips ------------------------------------------------------ */

.chips {
  list-style: none;
  margin: var(--s-1) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.chips > li {
  padding: 0.24rem 0.62rem;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-card-3);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.06em;
  line-height: 1.5;
  color: var(--muted);
  white-space: nowrap;
  transition: border-color var(--d-2) var(--e-out);
}

.bcard:hover .chips > li {
  border-color: var(--line-strong);
}

/* --- the one link -------------------------------------------------------- */

/* The card's only link, and on a phone the card's only tap target. The
   padding-top is the gap from the chips above; the padding-bottom exists purely
   so the hit area clears 44px in the vertical axis without moving the type. */
.bcard__go {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: auto 0 0;
  min-height: 44px;
  padding-top: var(--s-5);
  padding-bottom: var(--s-2);
  box-sizing: border-box;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--link);
  text-decoration: none;
}

.bcard__go > svg {
  flex: none;
  transition: transform var(--d-2) var(--e-out);
}

.bcard:hover .bcard__go > svg {
  transform: translateX(4px);
}

.bcard__go::after {
  border-radius: var(--r-xl);
}

.catalog__foot {
  display: grid;
  justify-items: center;
  gap: var(--s-5);
  margin: var(--s-12) auto 0;
  max-width: 64ch;
  text-align: center;
}

.catalog__foot-line {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--muted);
}

.catalog__foot-cta {
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
}

/* --------------------------------------------------------------------------
   6. What the demonstrations are — .truth
   -------------------------------------------------------------------------- */

.truth {
  gap: var(--s-6);
  align-items: stretch;
}

.truth__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  height: 100%;
  min-width: 0;
  transition: border-color var(--d-2) var(--e-out);
}

/* ICON-SYSTEM.md. These three cards used to open with a short accent rule —
   decoration that marked the top of the card and said nothing. The glyph plate
   now sits in exactly that position and carries a meaning instead: scope,
   record, guarantee. One graphic per card, so the rule is gone rather than
   stacked above the plate. Colour comes from .card__icon via currentColor, so
   the glyphs re-theme with the band. */
.truth__card > .card__icon {
  margin-bottom: calc(var(--s-1) * -1);
}

.truth__card:hover {
  border-color: var(--line-strong);
}

.truth__body {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-title-2);
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-wrap: pretty;
}

/* Carries the disclosures link alone now — the two notice slabs it used to
   host restated the Data card above it. */
.truth__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-6);
  margin-top: var(--s-6);
  padding-top: var(--s-6);
  border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   7. Principles ledger — .prin
   -------------------------------------------------------------------------- */

.prin {
  list-style: none;
  margin: var(--s-10) 0 0;
  padding: 0;
  display: grid;
  border-top: 1px solid var(--line);
}

.prin__row {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) 13rem;
  align-items: start;
  gap: var(--s-4) var(--s-8);
  padding: var(--s-6) var(--s-2);
  border-bottom: 1px solid var(--line-soft);
  transition: background var(--d-2) var(--e-out);
  min-width: 0;
}

.prin__row:hover {
  background: var(--bg-card);
}

.prin__n {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  line-height: 1.8;
  color: var(--muted);
}

.prin__main {
  display: grid;
  gap: var(--s-2);
  min-width: 0;
}

.prin__main > * {
  margin: 0;
}

.prin__main > :where(:first-child) {
  font-family: var(--font-display);
  font-size: var(--t-title-2);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;
}

.prin__main > :where(:last-child:not(:first-child)) {
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

/* holds a .badge — it is a container, not a chip itself */
.prin__stage {
  display: flex;
  justify-content: flex-end;
  justify-self: end;
  align-self: start;
  margin: 0;
  padding-top: 0.15rem;
}

/* --------------------------------------------------------------------------
   8. Closing CTA band — .bcta
   -------------------------------------------------------------------------- */

.bcta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  text-align: center;
}

.bcta :where(.lead, .prose, p) {
  margin-inline: auto;
}

.bcta :where(.row) {
  justify-content: center;
}

.bcta :where(.section-head) {
  text-align: center;
}

/* --------------------------------------------------------------------------
   9. Run-player states (defensive)
   -------------------------------------------------------------------------- */

[data-run-state] {
  transition: opacity var(--d-3) var(--e-out);
}

[data-run-state="past"] {
  opacity: 0.55;
}

[data-run-state="current"] {
  opacity: 1;
}

[data-run-state="future"] {
  opacity: 0.32;
}

/* --------------------------------------------------------------------------
   10. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1180px) {
  .bhero__inner {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "head"
      "copy"
      "fig";
    gap: var(--s-10);
  }

  .bhero__copy {
    max-width: 44rem;
  }

  .bhero__figure {
    width: 100%;
    max-width: 620px;
    justify-self: center;
    margin-inline: auto;
  }

  .prin__row {
    grid-template-columns: 3rem minmax(0, 1fr) 11rem;
    gap: var(--s-4) var(--s-6);
  }
}

@media (max-width: 1024px) {
  .frame {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-8);
  }

  .bcard__body {
    padding: var(--s-5);
  }
}

@media (max-width: 860px) {
  .prin__row {
    grid-template-columns: 3rem minmax(0, 1fr);
    gap: var(--s-3) var(--s-5);
  }

  .prin__stage {
    grid-column: 2;
    justify-self: start;
  }
}

/* Wide diagrams stay legible instead of shrinking to mush. Two strategies:
   the hero matrix scales its own type up so the amber human stop stays on
   screen; the spine (decorative, and fully restated by the legend under it)
   simply steps aside on small screens rather than demanding a sideways swipe. */
@media (max-width: 900px) {
  .spine-plate {
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  svg.spine[viewBox] {
    min-width: 720px;
  }
}

@media (max-width: 620px) {
  .spine-plate {
    display: none;
  }

  .bhero__figure {
    padding: var(--s-6) var(--s-4) var(--s-5);
  }

  /* ART-DIRECTION §4.6: never squash. 566 units inside a ~300px column would
     set the stage labels at ~5px, so the narrow cut takes over — same kit,
     same geometry, fewer columns, labels back at ~10px. */
  svg.matrixfig--desk[viewBox] {
    display: none;
  }

  svg.matrixfig--mob[viewBox] {
    display: block;
  }

  .bhero__cta > .btn {
    flex: 1 1 100%;
    justify-content: center;
  }
}

@media (max-width: 768px) {
  .truth__foot {
    justify-content: flex-start;
    gap: var(--s-5);
  }

  .catalog {
    gap: var(--s-6);
  }
}

@media (max-width: 560px) {
  .frame {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-6);
  }

  .bhero__figure {
    max-width: 100%;
  }

  .bcard__plate {
    padding: var(--s-5) var(--s-4) var(--s-4);
  }

  .bcard__body {
    padding: var(--s-5) var(--s-5) var(--s-6);
    gap: var(--s-3);
  }

  .prin__row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-2);
    padding-block: var(--s-5);
  }

  .prin__stage {
    grid-column: 1;
  }
}

/* --------------------------------------------------------------------------
   11. Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  /* rest the packet on the amber human stop — the point of both diagrams */
  .mxpk--a,
  .mxpk--b {
    animation: none;
    opacity: 1;
    offset-distance: 83%;
  }

  .sppk {
    animation: none;
    opacity: 1;
    offset-distance: 74%;
  }

  .bcard,
  .bcard .thumb,
  .bcard__go > svg,
  .chips > li,
  .prin__row,
  [data-run-state] {
    transition: none;
  }

  .bcard:hover,
  .bcard:focus-within {
    transform: none;
  }

  .bcard:hover svg.thumb[viewBox] {
    transform: none;
  }
}
