/* ==========================================================================
   CodeBenders — Cobalt Next Minimal theme
   ========================================================================== */

:root {
  /* Base palette */
  --color-bg: #0b1c24;
  --color-fg: #d7deea;
  --color-accent: #37b5b4;

  /* ANSI accents */
  --color-red: #ff657a;
  --color-green: #8cc98f;
  --color-yellow: #ffc64c;
  --color-blue: #409dd4;
  --color-magenta: #cba3c7;
  --color-cyan: #37b5b4;
  --color-cyan-bright: #84e4e3;

  /* Typography */
  --font-mono: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Small uppercase tracked labels (section eyebrows, chart/diagram heads) */
  --label-size: 0.75rem;
  --label-tracking: 0.14em;

  /* Spacing scale */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
}

* {
  box-sizing: border-box;
}

html {
  font-size: 16px;
}

body {
  margin: 0;
  background-color: var(--color-bg);
  color: var(--color-fg);
  font-family: var(--font-mono);
  font-size: 1rem;
  line-height: 1.6;
}

h1, h2, h3, h4 {
  font-family: var(--font-mono);
  line-height: 1.2;
  margin: 0 0 var(--space-2);
}

h2 {
  font-size: 1.75rem;
}

p {
  margin: 0 0 var(--space-2);
}

a {
  color: var(--color-cyan-bright);
  text-decoration: none;
}

a:hover,
a:focus {
  text-decoration: underline;
}

ul {
  margin: 0;
  padding-left: 1.25rem;
}

.accent-cyan {
  color: var(--color-cyan);
}

.accent-red { color: var(--color-red); }
.accent-green { color: var(--color-green); }
.accent-yellow { color: var(--color-yellow); }
.accent-blue { color: var(--color-blue); }
.accent-magenta { color: var(--color-magenta); }

/* ==========================================================================
   Header / nav
   ========================================================================== */

.site-header {
  border-bottom: 1px solid rgba(215, 222, 234, 0.15);
}

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

.nav__brand {
  font-weight: bold;
  font-size: 1.1rem;
  color: var(--color-fg);
}

.nav__links {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
}

/* Mirrors the page bands: four loop disciplines, then leadership, then contact. */
.nav__item--band {
  border-left: 1px solid rgba(215, 222, 234, 0.15);
  padding-left: var(--space-3);
}

/* ==========================================================================
   Terminal window (used by the contact section)
   ========================================================================== */

.terminal {
  width: 100%;
  max-width: 46rem;
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.15);
  border-radius: 8px;
  box-shadow: 0 0 32px rgba(55, 181, 180, 0.12), 0 12px 24px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

.terminal__titlebar {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background-color: #0f232c;
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
}

.terminal__dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  display: inline-block;
}

.terminal__dot--red { background-color: var(--color-red); }
.terminal__dot--yellow { background-color: var(--color-yellow); }
.terminal__dot--green { background-color: var(--color-green); }

.terminal__titlebar-label {
  margin-left: var(--space-2);
  font-size: 0.8rem;
  color: rgba(215, 222, 234, 0.65);
}

.terminal__body {
  padding: var(--space-4) var(--space-3);
}

.terminal__line {
  margin: 0 0 var(--space-2);
}

/* The one CLI moment pattern: `$ codebenders <subcommand>`. Sits on its own
   inset slab so it reads as a terminal line rather than styled prose — colour
   alone wasn't enough separation against the page background. The prompt and
   the subcommand carry the hue; the binary stays muted so the eye lands on the
   verb, which is the copy. */
.cmd {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5ch;
  white-space: nowrap;
  max-width: 100%;
  padding: 0.42em 0.75em;
  border: 1px solid rgba(55, 181, 180, 0.3);
  border-radius: 5px;
  background-color: rgba(55, 181, 180, 0.07);
  /* Sized to head a section: clearly above body copy, but still well below the
     title it introduces — it announces the section, it isn't the section. */
  font-size: clamp(0.95rem, 1.15vw, 1.1rem);
  font-weight: bold;
  line-height: 1.35;
}

.cmd__prompt {
  color: var(--color-cyan);
  user-select: none;
}

/* Stays at normal weight against the bold chip so the subcommand still leads. */
.cmd__bin {
  color: rgba(215, 222, 234, 0.6);
  font-weight: normal;
}

.cmd__sub {
  color: var(--color-cyan-bright);
}

/* Every command line ends on a blinking cursor — the component owns it so a
   new CLI moment can't ship without one. */
.cmd::after {
  content: "\2588";
  margin-left: 0.15em;
  color: var(--color-cyan);
  animation: blink 1s step-end infinite;
}

/* The contact line wraps a link, so it can't be nowrap on mobile. */
.cmd--wrap {
  white-space: normal;
  flex-wrap: wrap;
}

/* Inside a .terminal the window itself is already the frame — a second box
   around the command line reads as a box in a box. Keep the colour split and
   the cursor, drop the slab. */
/* A prompt line inside a terminal window, not a section header — so it keeps
   the terminal's own text size and weight rather than the header treatment. */
.terminal .cmd {
  padding: 0;
  border: 0;
  background-color: transparent;
  font-size: inherit;
  font-weight: normal;
}

/* Every section opens on its command: the command line IS the eyebrow, so the
   reader sees the instruction first and the prose below explains what it does.
   The eyebrow wrappers set label tracking and a label colour for the plain text
   they used to hold — neither should reach inside the chip. */
.drift__eyebrow .cmd,
.approach__eyebrow .cmd,
.caps__eyebrow .cmd {
  letter-spacing: normal;
}

.cursor {
  display: inline-block;
  margin-left: 0.15em;
  color: var(--color-cyan);
  animation: blink 1s step-end infinite;
}

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

/* ==========================================================================
   Operating loop
   ========================================================================== */

.loop {
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  background:
    radial-gradient(circle at 74% 48%, rgba(55, 181, 180, 0.07) 0, transparent 42%),
    radial-gradient(circle at 66% 62%, rgba(64, 157, 212, 0.05) 0, transparent 36%);
}

.loop__shell {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  align-items: center;
  gap: clamp(var(--space-3), 5vw, var(--space-5));
  width: 100%;
  max-width: 100rem;
  margin: 0 auto;
}

.loop__prompt {
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.75);
  font-size: 0.9rem;
}

.loop__heading {
  font-size: clamp(1.75rem, 5vw, 3.5rem);
  margin: 0 0 var(--space-2);
}

.loop__intro {
  max-width: 46ch;
  color: rgba(215, 222, 234, 0.75);
  margin: 0 0 var(--space-3);
}

/* Discipline pills — clickable, and auto-activated by the loop cycle.
   Sit below the diagram so selecting one reads as part of the visual. */
.loop__pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-1);
  margin: var(--space-2) 0 0;
  padding: 0;
}

.loop__pill {
  --pill-accent: var(--color-cyan);
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.35rem 0.9rem;
  border: 1px solid rgba(215, 222, 234, 0.18);
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-fg);
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

.loop__pill::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background-color: var(--pill-accent);
  opacity: 0.5;
  transition: opacity 0.2s ease, box-shadow 0.2s ease;
}

/* Reserves height for the longest description so swapping never reflows. */
.loop__detail {
  max-width: 46rem;
  min-height: 3.4rem;
  margin: var(--space-2) auto 0;
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.85rem;
  text-align: center;
}

.loop__detail strong {
  font-weight: normal;
}

.loop__pill:hover,
.loop__pill:focus-visible,
.loop__pill.is-active {
  border-color: var(--pill-accent);
  background-color: rgba(215, 222, 234, 0.04);
  box-shadow: 0 0 18px -6px var(--pill-accent);
  text-decoration: none;
}

.loop__pill:hover::before,
.loop__pill:focus-visible::before,
.loop__pill.is-active::before {
  opacity: 1;
  box-shadow: 0 0 8px var(--pill-accent);
}

.loop__pill--cloud { --pill-accent: var(--color-blue); }
.loop__pill--observability { --pill-accent: var(--color-magenta); }
.loop__pill--security { --pill-accent: var(--color-cyan-bright); }
.loop__pill--compliance { --pill-accent: var(--color-green); }

.loop__visual {
  min-width: 0;
}

.loop__visual-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
  color: rgba(215, 222, 234, 0.5);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

.loop__live {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.loop__live::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background-color: var(--color-cyan);
  box-shadow: 0 0 0 0.22rem rgba(55, 181, 180, 0.15);
}

.loop__diagram {
  width: 100%;
  max-width: 52rem;
  margin: 0 auto;
  aspect-ratio: 820 / 568;
}

.loop__diagram svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.loop__grid {
  fill: none;
  stroke: rgba(215, 222, 234, 0.07);
  stroke-width: 1;
}

.loop__ring {
  fill: none;
  stroke: rgba(215, 222, 234, 0.12);
  stroke-width: 1.25;
}

.loop__spoke {
  fill: none;
  stroke: rgba(215, 222, 234, 0.15);
  stroke-width: 1.25;
  stroke-dasharray: 3 5;
}

.loop__spoke-dot {
  fill: var(--color-bg);
  stroke: rgba(215, 222, 234, 0.35);
  stroke-width: 1.25;
}

.loop__arc {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.45;
  transition: opacity 0.45s ease, stroke-width 0.45s ease;
  animation: loop-cycle 12s ease-in-out infinite;
}

.loop__arc--cloud {
  stroke: var(--color-blue);
  animation-delay: 9s;
}

.loop__arc--observability {
  stroke: var(--color-magenta);
  animation-delay: 0s;
}

.loop__arc--security {
  stroke: var(--color-cyan-bright);
  animation-delay: 3s;
}

.loop__arc--compliance {
  stroke: var(--color-green);
  animation-delay: 6s;
}

.loop__arrow path {
  fill: none;
  stroke: var(--color-blue);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.7;
}

/* Node medallions */
.loop__node-plate {
  fill: #081319;
  stroke: rgba(215, 222, 234, 0.12);
  stroke-width: 1;
}

/* Full ring around each icon. Kept a step wider than the loop segment it sits
   on (arc is 4 idle / 7 active) so the medallion always reads as the heavier
   element where the two meet. */
.loop__node-rim {
  fill: none;
  stroke: var(--node-accent, var(--color-cyan));
  stroke-width: 3;
  opacity: 0.5;
  transition: opacity 0.45s ease, stroke-width 0.45s ease;
}

.loop__icon {
  fill: none;
  stroke: var(--node-accent, var(--color-cyan));
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.75;
  transition: opacity 0.45s ease;
}

.loop__node--cloud { --node-accent: var(--color-blue); }
.loop__node--observability { --node-accent: var(--color-magenta); }
.loop__node--security { --node-accent: var(--color-cyan-bright); }
.loop__node--compliance { --node-accent: var(--color-green); }

.loop__node.is-active .loop__node-rim {
  opacity: 1;
  stroke-width: 5;
}

.loop__node.is-active .loop__icon {
  opacity: 1;
}

.loop__node.is-active .loop__label {
  fill: var(--node-accent);
}

/* Isometric platform core */
.loop__core-glow {
  fill: rgba(64, 157, 212, 0.05);
  stroke: rgba(64, 157, 212, 0.16);
  stroke-width: 1;
  transform-box: fill-box;
  transform-origin: center;
  animation: loop-breathe 4.8s ease-in-out infinite;
}

.loop__slab-top {
  fill: rgba(64, 157, 212, 0.22);
  stroke: var(--color-blue);
  stroke-width: 1.4;
}

.loop__slab-side {
  fill: rgba(8, 19, 25, 0.9);
  stroke: rgba(64, 157, 212, 0.55);
  stroke-width: 1.2;
}

.loop__slab-side--dark {
  fill: rgba(8, 19, 25, 0.97);
}

.loop__slab-beam {
  fill: rgba(132, 228, 227, 0.3);
  stroke: var(--color-cyan-bright);
  stroke-width: 1;
}

.loop__core-label,
.loop__label,
.loop__sub {
  font-family: var(--font-mono);
  text-anchor: middle;
}

.loop__label--right,
.loop__sub--right {
  text-anchor: start;
}

.loop__label--left,
.loop__sub--left {
  text-anchor: end;
}

.loop__core-label {
  fill: rgba(215, 222, 234, 0.75);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
}

.loop__label {
  fill: var(--color-fg);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  transition: fill 0.45s ease;
}

.loop__sub {
  fill: rgba(215, 222, 234, 0.55);
  font-size: 0.7rem;
}

.loop__packet {
  fill: var(--color-cyan-bright);
  filter: drop-shadow(0 0 6px rgba(132, 228, 227, 0.7));
}

/* JS drives the cycle so the pills stay in sync with the arcs; without JS
   the keyframe animation below runs instead. */
.loop--js .loop__arc {
  animation: none;
}

.loop--js .loop__arc.is-active {
  opacity: 1;
  stroke-width: 4;
}

/* No-JS fallback: medallions cycle on the same 12s clock as the arcs. */
.loop__node-rim,
.loop__icon {
  animation: loop-node-cycle 12s ease-in-out infinite;
}

.loop__node--observability .loop__node-rim,
.loop__node--observability .loop__icon { animation-delay: 0s; }
.loop__node--security .loop__node-rim,
.loop__node--security .loop__icon { animation-delay: 3s; }
.loop__node--compliance .loop__node-rim,
.loop__node--compliance .loop__icon { animation-delay: 6s; }
.loop__node--cloud .loop__node-rim,
.loop__node--cloud .loop__icon { animation-delay: 9s; }

.loop--js .loop__node-rim,
.loop--js .loop__icon {
  animation: none;
}

@keyframes loop-cycle {
  0%, 25% { opacity: 1; stroke-width: 4; }
  30%, 100% { opacity: 0.45; stroke-width: 2.5; }
}

@keyframes loop-node-cycle {
  0%, 25% { opacity: 1; }
  30%, 100% { opacity: 0.55; }
}

@keyframes loop-breathe {
  0%, 100% { transform: scale(0.98); opacity: 0.66; }
  50% { transform: scale(1.045); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  /* No cycling — every arc reads at full strength so the loop stays complete.
     Overrides the JS-driven .is-active weighting too. */
  .loop__arc,
  .loop--js .loop__arc {
    animation: none;
    opacity: 1;
    stroke-width: 2.5;
    transition: none;
  }

  .loop__node-rim,
  .loop--js .loop__node-rim,
  .loop__icon,
  .loop--js .loop__icon {
    animation: none;
    opacity: 1;
    transition: none;
  }

  .loop__core-glow {
    animation: none;
  }

  .loop__packet {
    display: none;
  }
}

/* ==========================================================================
   The drift — problem statement
   ========================================================================== */

/* Deliberately warmer and more agitated than the operating loop above it:
   red/yellow accents and a hairline alarm rule along the top edge. */
.drift {
  position: relative;
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  background:
    radial-gradient(ellipse at 30% 0%, rgba(255, 101, 122, 0.08) 0, transparent 55%),
    radial-gradient(ellipse at 86% 82%, rgba(255, 198, 76, 0.04) 0, transparent 46%);
}

.drift::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0,
    rgba(255, 101, 122, 0.55) 30%,
    rgba(255, 198, 76, 0.55) 70%,
    transparent 100%
  );
}

.drift__shell {
  width: 100%;
  max-width: 78rem;
  margin: 0 auto;
}

.drift__head {
  margin: 0 0 var(--space-4);
}

/* Shares the tracked-label rhythm with .loop__visual-head and
   .drift__chart-head — see --label-* in :root. */
.drift__eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--color-green);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

.drift__heading {
  max-width: 24ch;
  font-size: clamp(1.9rem, 5vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
}

/* The turn in the sentence — where the problem becomes the reader's. */
.drift__heading-alarm {
  color: var(--color-red);
}

.drift__lede {
  max-width: 46ch;
  margin: 0 0 var(--space-1);
  font-size: clamp(1rem, 1.7vw, 1.35rem);
  font-weight: bold;
  line-height: 1.3;
}

.drift__intro {
  max-width: 62ch;
  margin: 0;
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.95rem;
}

/* The conclusion the paragraph builds to — lifted out of the dimmed body so
   it lands even when the reader only skims the last line. Its own block, so it
   starts at the margin at every width, while staying one sentence in the flow
   (and one continuous run for screen readers). The indent picks up the ellipsis
   before it: the line reads as the continuation of that thought, not a new one. */
.drift__intro-strong {
  display: block;
  margin-top: 0.4em;
  padding-left: 2ch;
  color: var(--color-fg);
}

/* One enclosing panel holds the stage strip and the chart, so the escalation
   and its consequence read as a single instrument rather than two widgets. */
/* No `overflow: hidden` here — the chart's right-edge labels sit outside the
   800-unit viewBox and must escape the panel. Stage 04's glow needs to escape
   too, so corner clipping is handled per-child instead. */
.drift__panel {
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.12);
  border-radius: 10px;
  margin-bottom: var(--space-3);
}

/* Four equal columns, matching the chart's four equal phase bands below. The
   svg's plot area spans the same box as this strip, so tile N sits over band N
   without either side needing a compensating inset. */
.drift__stages {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
  padding: var(--space-1) var(--space-2);
  /* No `gap`: it is taken off the top, so the four columns would each be a
     gutter narrower than the chart's quarter bands and drift out of step with
     the dividers. The columns stay exact quarters and the gutter is made by
     insetting each card half a gutter per side — see .drift__stage. */
  border-bottom: 1px solid rgba(215, 222, 234, 0.12);
}

.drift__stage {
  --stage-accent: rgba(215, 222, 234, 0.6);
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  /* Half a gutter each side, so neighbouring cards sit --space-2 apart while
     each grid column still spans a full quarter of the chart below. */
  margin-inline: calc(0.5 * var(--space-2));
  border: 1px solid transparent;
  border-radius: 8px;
}

/* The separator sits on the grid-column edge — half a gutter left of the card
   itself — so it lands exactly on the chart's dashed divider below. Drawing it
   on the card's own border-left would put it 8px off, which reads as a
   misalignment even though the gutter centre is correct. */
.drift__stage + .drift__stage::after {
  content: "";
  position: absolute;
  left: calc(-0.5 * var(--space-2));
  top: 0;
  bottom: 0;
  border-left: 1px solid rgba(215, 222, 234, 0.1);
}

/* Chevron in the gutter between stages — the drift is directional, and it
   points at stage 04, so it carries 04's red. */
.drift__stage + .drift__stage::before {
  content: "";
  position: absolute;
  /* Anchored to this card's left border and stepped out into the gutter. The
     rotated square is centred by the transform, so every chevron ends up the
     same distance from the border it points at. */
  left: calc(-1px - 0.5 * var(--space-2) - 0.5 * var(--space-1));
  top: 50%;
  width: 0.48rem;
  height: 0.48rem;
  border-top: 2.5px solid var(--color-red);
  border-right: 2.5px solid var(--color-red);
  transform: translate(-50%, -50%) rotate(45deg);
}

.drift__stage-index {
  color: var(--stage-accent);
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  font-weight: bold;
  line-height: 1;
}

.drift__stage-text {
  min-width: 0;
}

.drift__stage-title {
  margin: 0 0 0.15rem;
  font-size: 0.9rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-fg);
}

.drift__stage-body {
  margin: 0;
  color: rgba(215, 222, 234, 0.6);
  font-size: 0.82rem;
}

.drift__stage--2 { --stage-accent: rgba(140, 201, 143, 0.85); }
.drift__stage--3 { --stage-accent: var(--color-yellow); }

/* The terminal stage is boxed and lit — this is the one that costs money.
   The border is a muted red so the full-strength chevrons stay legible
   against it; the number carries the saturated accent instead. */
.drift__stage--4 {
  --stage-accent: var(--color-red);
  border: 1px solid rgba(255, 101, 122, 0.38);
  border-radius: 8px;
  box-shadow: 0 0 26px rgba(255, 101, 122, 0.1), inset 0 0 22px rgba(255, 101, 122, 0.04);
}

/* Chart */
.drift__chart {
  padding: var(--space-3) var(--space-2) var(--space-2);
}

.drift__chart-head {
  margin: 0 0 var(--space-1);
  padding-left: var(--space-1);
  color: rgba(140, 201, 143, 0.75);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

.drift__chart svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.drift__phase-lines {
  fill: none;
  stroke: rgba(215, 222, 234, 0.08);
  stroke-width: 1;
  stroke-dasharray: 3 6;
}

.drift__baseline {
  fill: none;
  stroke: rgba(215, 222, 234, 0.25);
  stroke-width: 1;
}

.drift__area {
  fill: url(#drift-area-fill);
  stroke: none;
}

.drift__curve {
  fill: none;
  stroke: var(--color-red);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.drift__focus {
  fill: none;
  stroke: rgba(140, 201, 143, 0.7);
  stroke-width: 1.75;
  stroke-dasharray: 7 7;
  stroke-linecap: round;
}

.drift__threshold {
  fill: none;
  stroke: rgba(255, 198, 76, 0.7);
  stroke-width: 1;
  stroke-dasharray: 6 6;
}

.drift__curve-label,
.drift__focus-label,
.drift__threshold-label,
.drift__breach-label,
.drift__marker-label,
.drift__axis-label {
  font-family: var(--font-mono);
}

/* Right-anchored so they end inside the 800-unit viewBox rather than
   overflowing it — no reliance on an ancestor not clipping. */
.drift__curve-label,
.drift__focus-label {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-anchor: end;
}

.drift__curve-label {
  fill: var(--color-red);
}

.drift__focus-label {
  fill: rgba(140, 201, 143, 0.85);
}

.drift__threshold-label {
  fill: var(--color-yellow);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
}

/* Inflection annotations — the specific bills, not abstractions. */
.drift__marker-dot {
  fill: var(--color-red);
}

.drift__marker-stem {
  fill: none;
  stroke: rgba(255, 101, 122, 0.5);
  stroke-width: 1;
}

.drift__marker-label {
  fill: rgba(255, 101, 122, 0.9);
  font-size: 0.68rem;
  text-anchor: middle;
}

.drift__marker-label--right {
  text-anchor: end;
}

/* Where the debt curve crosses into the business's field of view. */
.drift__breach {
  fill: var(--color-red);
}

.drift__breach-ring {
  fill: none;
  stroke: var(--color-red);
  stroke-width: 2;
}

.drift__breach-halo {
  fill: none;
  stroke: var(--color-red);
  stroke-width: 1.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: drift-breach 2.8s ease-out infinite;
}

.drift__breach-drop {
  fill: none;
  stroke: rgba(255, 101, 122, 0.6);
  stroke-width: 1;
  stroke-dasharray: 4 4;
}

.drift__breach-label {
  fill: var(--color-red);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
}

.drift__axis-label {
  fill: rgba(215, 222, 234, 0.55);
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  text-anchor: middle;
}

.drift__close {
  margin: 0;
  color: var(--color-fg);
  font-size: clamp(0.95rem, 1.5vw, 1.2rem);
  letter-spacing: 0.01em;
}

.drift__close .accent-red {
  font-weight: bold;
}

@keyframes drift-breach {
  0% { transform: scale(1); opacity: 0.85; }
  100% { transform: scale(2.6); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .drift__breach-halo {
    animation: none;
    opacity: 0.35;
  }
}

/* ==========================================================================
   The approach — how we work

   The answer to .drift, and deliberately the opposite temperature: the drift
   runs hot and curved (red, exponential, out of control), this runs cool and
   straight (cyan, three numbered steps, finite). Cyan here is the brand
   accent — the `$` prompt colour used site-wide — not a claim on the security
   discipline; the step cards carry no discipline colour of their own.
   ========================================================================== */

/* Green wash, deliberately answering .drift's red one directly above: that
   section is the problem, this is the resolution, and the page should feel
   the temperature change before a word is read. */
.approach {
  position: relative;
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  background:
    radial-gradient(ellipse at 30% 0%, rgba(140, 201, 143, 0.11) 0, transparent 58%),
    radial-gradient(ellipse at 84% 78%, rgba(140, 201, 143, 0.06) 0, transparent 48%);
}

.approach::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0,
    rgba(140, 201, 143, 0.6) 35%,
    rgba(140, 201, 143, 0.4) 75%,
    transparent 100%
  );
}

.approach__shell {
  width: 100%;
  max-width: 78rem;
  margin: 0 auto;
}

.approach__head {
  margin: 0 0 var(--space-4);
}

/* Same tracked-label rhythm as .drift__eyebrow and .leadership__eyebrow. */
.approach__eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--color-green);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

/* First clause sits back, so the turn in the sentence carries the contrast
   without needing a second colour. */
.approach__heading {
  max-width: 24ch;
  font-size: clamp(1.9rem, 5vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.55);
}

/* Answers .drift__heading-alarm: same turn in the sentence, cooled down.
   Deliberately NOT cyan — the lede's marks own the cyan in this block, and
   two cyans stacked killed the pop on both. Contrast here is weight, not hue. */
.approach__heading-accent {
  color: var(--color-fg);
}

.approach__lede {
  max-width: 46ch;
  margin: 0 0 var(--space-1);
  font-size: clamp(1rem, 1.7vw, 1.35rem);
  font-weight: bold;
  line-height: 1.5;
}

/* The two words the section is actually about. Marked rather than merely
   coloured — this is the one claim the reader should leave with. Green ties
   them to the resolution ramp running through the cards below. */
.approach__mark {
  color: var(--color-green);
  background: rgba(140, 201, 143, 0.12);
  border-bottom: 1px solid rgba(140, 201, 143, 0.6);
  padding: 0.05em 0.3em;
  border-radius: 3px;
  white-space: nowrap;
}

.approach__intro {
  max-width: 62ch;
  margin: 0;
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.95rem;
}

/* Three steps across — a finite sequence, unlike the drift's four-stage slide
   into the red. */
/* Equal-height cards (default stretch): the row reads as one instrument
   rather than three ragged panels. Step 02 is the tallest — its findings
   list sets the height and the other two match it. */
.approach__steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: 0;
}

/* Each card carries its own tint, deepening toward green across the three
   steps so the row reads as progress from "not started" to "delivered".
   Green is the resolution colour of this section, answering the drift's red;
   the gradient fades out downward so the text sits on flat panel. */
.approach__step {
  position: relative;
  background-color: #081319;
  background-image: linear-gradient(
    170deg,
    var(--step-wash, transparent) 0,
    transparent 60%
  );
  border: 1px solid rgba(215, 222, 234, 0.12);
  border-radius: 10px;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-2);
  border-left: 2px solid var(--step-tint, rgba(215, 222, 234, 0.25));
}

/* Step 01 starts effectively neutral — nothing has happened yet — so the
   ramp has somewhere to travel from. An earlier version began at 0.35 green
   and the three cards read as "similar", not as a progression. */
.approach__step--1 {
  --step-tint: rgba(215, 222, 234, 0.28);
  --step-wash: transparent;
}

.approach__step--2 {
  --step-tint: rgba(140, 201, 143, 0.6);
  --step-wash: rgba(140, 201, 143, 0.05);
}

/* Step 03: full green — the outcome is met, and the only card that glows. */
.approach__step--3 {
  --step-tint: var(--color-green);
  --step-wash: rgba(140, 201, 143, 0.12);
  border-color: rgba(140, 201, 143, 0.3);
  box-shadow: 0 0 30px rgba(140, 201, 143, 0.13);
}

/* Index, icon and title share a centred row — baseline alignment left the
   large numeral sitting oddly against the small caps title. */
.approach__step-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
}

.approach__step-index {
  margin: 0;
  color: var(--step-tint, rgba(215, 222, 234, 0.45));
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  font-weight: bold;
  line-height: 1;
}

/* Terminal-style bracket glyph, matching .service__glyph's vocabulary. */
.approach__step-glyph {
  color: var(--step-tint, var(--color-fg));
  font-size: 1.15rem;
  line-height: 1;
}

.approach__step-title {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
}

.approach__step-body {
  margin: 0 0 var(--space-2);
  font-size: 0.95rem;
}

.approach__step-list {
  margin: 0;
  padding-left: 1.1rem;
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.85rem;
}

.approach__step-list li {
  margin-bottom: 0.15rem;
}

/* Sample assessment output — the one place the section shows rather than
   tells. Severity is the ranking the whole engagement runs on, so it gets a
   real badge instead of another bullet. */
.approach__findings {
  list-style: none;
  margin: 0 0 var(--space-2);
  padding: 0;
}

.approach__finding {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  padding: 0.28rem 0;
  border-bottom: 1px solid rgba(215, 222, 234, 0.07);
  font-size: 0.85rem;
}

.approach__finding:last-child {
  border-bottom: 0;
}

.approach__finding-text {
  color: rgba(215, 222, 234, 0.8);
}

.approach__finding code {
  font-family: var(--font-mono);
  color: var(--color-fg);
}

/* Fixed width so the three severities stack into a readable column. */
.approach__badge {
  flex: 0 0 auto;
  min-width: 3.4rem;
  text-align: center;
  padding: 0.05rem 0.35rem;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-size: 0.68rem;
  font-weight: bold;
  letter-spacing: 0.08em;
  line-height: 1.5;
}

/* Severity uses the page's existing alarm ramp — red/yellow/green already
   mean exactly this in .drift. Not a discipline claim: no card here borrows
   a service accent. */
.approach__badge--high {
  color: var(--color-red);
  background: rgba(255, 101, 122, 0.1);
}

.approach__badge--med {
  color: var(--color-yellow);
  background: rgba(255, 198, 76, 0.1);
}

/* Neutral, not green: green now carries "delivered" across this section's
   card ramp, and a green LOW badge read for a half-beat as "already done". */
.approach__badge--low {
  color: rgba(215, 222, 234, 0.6);
  background: rgba(215, 222, 234, 0.06);
}

/* Commentary on the findings above, not another finding — set apart so the
   list reads as closed. */
.approach__step-note {
  margin: var(--space-2) 0 0;
  padding-top: var(--space-1);
  border-top: 1px solid rgba(215, 222, 234, 0.07);
  color: rgba(215, 222, 234, 0.55);
  font-size: 0.8rem;
  font-style: italic;
}

/* ==========================================================================
   The Platform band
   ========================================================================== */

/* This band sits outside the discipline→colour table on purpose: it's how the
   loop is run, not a fifth thing in it. So it takes no accent hue at all —
   an earlier cyan version read as a second #security section. Its separation
   from the neighbouring bands is structural (edge, wash, panel), not chromatic. */
/* Deliberately darker than .approach above it rather than differently hued:
   the seam between the two bands has to register, and value is the only axis
   left once colour is off the table. */
.stack {
  position: relative;
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  background-color: #071219;
  background-image:
    radial-gradient(ellipse at 70% 0%, rgba(215, 222, 234, 0.045) 0, transparent 58%),
    radial-gradient(ellipse at 16% 82%, rgba(215, 222, 234, 0.025) 0, transparent 48%);
}

.stack::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0,
    rgba(215, 222, 234, 0.32) 30%,
    rgba(215, 222, 234, 0.2) 72%,
    transparent 100%
  );
}

.stack__shell {
  width: 100%;
  max-width: 78rem;
  margin: 0 auto;
}

.stack__head {
  margin: 0 0 var(--space-4);
}

/* Same tracked-label rhythm as .drift__eyebrow and .approach__eyebrow, but
   uncoloured — those two mark their band's argument colour, and the only hue
   free here already belongs to #security. */
.stack__eyebrow {
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.55);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

/* Matches .approach__heading: first clause recedes so the turn carries. */
.stack__heading {
  max-width: 24ch;
  font-size: clamp(1.9rem, 5vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.55);
}

.stack__heading-accent {
  color: var(--color-fg);
}

.stack__lede {
  max-width: 46ch;
  margin: 0 0 var(--space-1);
  font-size: clamp(1rem, 1.7vw, 1.35rem);
  font-weight: bold;
  line-height: 1.5;
}

.stack__intro {
  max-width: 62ch;
  margin: 0;
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.95rem;
}

/* Three equal columns — a flat set, not a sequence, so no numbering and no
   ramp: unlike .approach__steps these carry no order.
   Contained as one panel (the .drift__panel treatment) rather than a row of
   separate cards: .approach directly above runs the same eyebrow → heading →
   lede → three-card → CLI shape, and two loose card rows in a row read as the
   same beat twice. One instrument here, three panels there. */
.stack__groups {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0 0 var(--space-3);
  padding: 0;
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.12);
  border-radius: 10px;
  overflow: hidden;
}

/* Dividers between columns, not borders around them. */
.stack__group {
  padding: var(--space-3) var(--space-2);
}

.stack__group + .stack__group {
  border-left: 1px solid rgba(215, 222, 234, 0.1);
}

/* min-height holds the two-line case ("Roles you don't have to hire" wraps
   between ~900px and ~1200px while its siblings don't). Without it the third
   card's hairline sits lower than the other two and the row stops reading as
   one instrument. */
.stack__group-head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 3.4rem;
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
}

/* Terminal bracket glyph, same vocabulary as .service__glyph — but neutral,
   not cyan: a coloured card two sections above #security read as a second
   security claim. Colour here is weight, not hue. */
.stack__group-glyph {
  color: rgba(215, 222, 234, 0.5);
  font-size: 1.05rem;
  line-height: 1;
}

.stack__group-title {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.2;
}

.stack__list {
  margin: 0;
  padding-left: 1.1rem;
  color: rgba(215, 222, 234, 0.75);
  font-size: 0.85rem;
}

.stack__list li {
  margin-bottom: 0.3rem;
}

.stack__list li:last-child {
  margin-bottom: 0;
}

/* The section's one CLI moment. Rendered as a plan output rather than a bare
   prompt line because the last row — apply, awaiting review — is the point. */
/* No coloured glow: .service--cyan owns that treatment for #security, and a
   glowing cyan card here read as the same claim made twice. */
.stack__close {
  max-width: 46rem;
  margin: 0;
  padding: var(--space-2);
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.14);
  border-radius: 10px;
}

.stack__close-prompt {
  margin: 0 0 var(--space-1);
}

.stack__output {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
  color: rgba(215, 222, 234, 0.7);
}

.stack__output li {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  padding: 0.15rem 0;
}

.stack__status {
  flex: 0 0 auto;
  color: var(--color-green);
}

/* The one row that hasn't happened yet — it's waiting on the reader. */
.stack__status--pending {
  color: var(--color-yellow);
}

.stack__output-pending {
  color: var(--color-fg);
}

/* Fixed column so the three statuses align like real CLI output. */
.stack__key {
  flex: 0 0 auto;
  min-width: 6rem;
  color: var(--color-cyan-bright);
}

/* ==========================================================================
   Capabilities band

   The four loop disciplines, spelled out. Named and coloured exactly as the
   loop names and colours them — this band is the ring unrolled, so a cell that
   disagreed with its node would break the page's one running argument.
   ========================================================================== */

/* Deliberately darker than the band above rather than differently hued — all
   four accents are spoken for inside the grid, so value is the only axis left
   to mark the band's edge. */
.caps {
  position: relative;
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  background-color: #071219;
}

.caps::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0,
    rgba(215, 222, 234, 0.32) 30%,
    rgba(215, 222, 234, 0.2) 72%,
    transparent 100%
  );
}

.caps__shell {
  width: 100%;
  max-width: 78rem;
  margin: 0 auto;
}

.caps__head {
  margin: 0 0 var(--space-4);
}

/* Same tracked-label rhythm as .drift__eyebrow and .approach__eyebrow. Left
   uncoloured: all four accents are spoken for in the grid below, and picking
   one of them here would read as a fifth claim. */
.caps__eyebrow {
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.55);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

/* Matches .approach__heading: the first clause recedes so the turn carries. */
.caps__heading {
  max-width: 24ch;
  font-size: clamp(1.9rem, 5vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.55);
}

.caps__heading-accent {
  color: var(--color-fg);
}

/* Four cards, two across. Each is lit from its own top edge: an accent bar
   across the head, a wash bleeding down from it, and a border tinted to
   match — the discipline's colour arrives before its name does. */
.caps__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.caps__card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--space-4) var(--space-3) var(--space-3);
  background-color: #081319;
  background-image: linear-gradient(
    170deg,
    var(--card-wash, transparent) 0,
    transparent 62%
  );
  border: 1px solid var(--card-edge, rgba(215, 222, 234, 0.15));
  border-radius: 12px;
  box-shadow: 0 0 34px var(--card-glow, transparent), 0 12px 24px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

/* The lit top edge. Inset from the corners so it reads as a bar of light on
   the card rather than a thicker border. */
.caps__card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent 0,
    var(--card-accent, transparent) 12%,
    var(--card-accent, transparent) 88%,
    transparent 100%
  );
}

.caps__card--cloud {
  --card-accent: var(--color-blue);
  --card-edge: rgba(64, 157, 212, 0.32);
  --card-wash: rgba(64, 157, 212, 0.1);
  --card-glow: rgba(64, 157, 212, 0.1);
}

.caps__card--observability {
  --card-accent: var(--color-magenta);
  --card-edge: rgba(203, 163, 199, 0.32);
  --card-wash: rgba(203, 163, 199, 0.1);
  --card-glow: rgba(203, 163, 199, 0.1);
}

.caps__card--security {
  --card-accent: var(--color-cyan);
  --card-edge: rgba(55, 181, 180, 0.32);
  --card-wash: rgba(55, 181, 180, 0.1);
  --card-glow: rgba(55, 181, 180, 0.1);
}

.caps__card--compliance {
  --card-accent: var(--color-green);
  --card-edge: rgba(140, 201, 143, 0.32);
  --card-wash: rgba(140, 201, 143, 0.1);
  --card-glow: rgba(140, 201, 143, 0.1);
}

/* Glyph, name and index on one row; the loop node's subtitle tucks beneath
   the name, quoted verbatim so ring and card never tell two stories. */
.caps__card-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "glyph name  index"
    "glyph sub   index";
  align-items: center;
  column-gap: var(--space-2);
  margin-bottom: var(--space-3);
}

/* Boxed, not bare — the glyph is the card's badge, matching the tinted
   square in the accent bar above it. */
.caps__glyph {
  grid-area: glyph;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--card-edge, rgba(215, 222, 234, 0.2));
  border-radius: 8px;
  background-color: var(--card-wash, transparent);
  color: var(--card-accent, var(--color-fg));
  font-size: 0.9rem;
  line-height: 1;
}

.caps__name {
  grid-area: name;
  align-self: end;
  margin: 0;
  font-size: 1.35rem;
  line-height: 1.1;
}

/* Sits on the name's baseline, top-right — a session number, not a caption
   for the subtitle beneath. */
.caps__index {
  grid-area: index;
  margin: 0;
  color: rgba(215, 222, 234, 0.35);
  font-size: 0.9rem;
  letter-spacing: var(--label-tracking);
}

.caps__sub {
  grid-area: sub;
  align-self: start;
  margin: 0;
  color: rgba(215, 222, 234, 0.45);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}

/* Tracked caps in the card's accent — the two labels are what give the card
   its spine: what you get, then how. */
.caps__label {
  margin: 0 0 var(--space-1);
  color: var(--card-accent, var(--color-fg));
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

.caps__outcome {
  margin: 0 0 var(--space-3);
  font-size: 1rem;
  line-height: 1.5;
}

/* Three pillars across, each under its own short accent rule. Stretched to
   the card's floor so all four cards' pillar blocks bottom out together. */
.caps__pillars {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-1) 0 0;
}

.caps__pillar {
  border-top: 2px solid var(--card-accent, rgba(215, 222, 234, 0.3));
  padding-top: var(--space-2);
}

.caps__pillar-title {
  margin: 0 0 0.35rem;
  color: rgba(215, 222, 234, 0.92);
  font-size: 0.88rem;
  font-weight: normal;
  line-height: 1.35;
}

.caps__pillar-body {
  margin: 0;
  color: rgba(215, 222, 234, 0.5);
  font-size: 0.76rem;
  line-height: 1.45;
}

/* Closing strip: the four dots restate the disciplines as one set, which is
   the band's actual claim — you get the loop, not four vendors. */
.caps__summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3);
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.12);
  border-radius: 12px;
  margin-bottom: var(--space-3);
}

.caps__summary-dots {
  display: flex;
  gap: 0.4rem;
}

.caps__summary-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
}

.caps__summary-dot--cloud { background-color: var(--color-blue); }
.caps__summary-dot--observability { background-color: var(--color-magenta); }
.caps__summary-dot--security { background-color: var(--color-cyan); }
.caps__summary-dot--compliance { background-color: var(--color-green); }

.caps__summary-lede {
  flex: 1 1 18rem;
  margin: 0;
  font-size: 1rem;
}

.caps__summary-note {
  margin: 0;
  color: rgba(215, 222, 234, 0.5);
  font-size: 0.85rem;
}

/* A quieter tier than the marked lede above: key promises stand out without
   turning two supporting sentences into another headline. */
.approach__intro strong,
.caps__summary-note strong {
  color: var(--color-green);
  font-weight: 700;
}

/* Roles strip — who shows up, in the vocabulary the reader already hires in.
   Deliberately takes no discipline hue: a role is a hat worn across all four
   cards above, and colouring one of them would read as a fifth discipline.
   Contrast here is value and the hairline rule, matching the .stack treatment.
   One panel rather than six loose cards, so it reads as a single roster and
   stays clearly subordinate to the four cards above it. */
.roles {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.12);
  border-radius: 12px;
}

.roles__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
}

.roles__heading {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.2;
}

/* Fixed counts, not auto-fit: auto-fit left a ragged orphan row (4+1) through
   the ~850–1000px window, which reads as an accident directly below four
   precisely laid-out cards. Five across here, then pinned again at each
   breakpoint below so every width lands on a deliberate split. */
.roles__list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-3) var(--space-2);
  margin: 0;
  padding: 0;
}

.roles__role {
  --role-accent: var(--color-cyan);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  text-align: center;
}

/* The icon is the content here — with the glosses gone the roster is a visual
   strip, so the glyph carries it. Drawn bare, with no badge box: the four cards
   above already use the boxed-badge treatment, and repeating it here made the
   roster read as another row of cards rather than a lighter strip below them.
   Each role takes its own tint.

   NOTE, deliberate exception: these hues also carry discipline meanings in the
   loop (see the discipline→colour table in CLAUDE.md). Here they are decorative
   variety across a compact icon strip, not a claim — a role is worn across all
   four disciplines. The roster stays outside that table; do not read
   SRE-as-blue as "SRE is Cloud", and do not sync these to the loop. */
.roles__glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--role-accent);
}

.roles__glyph svg {
  width: 3.9rem;
  height: 3.9rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.roles__name {
  margin: 0;
  color: var(--color-fg);
  font-size: 0.98rem;
  letter-spacing: 0.02em;
  line-height: 1.25;
}

.roles__role--sre {
  --role-accent: var(--color-blue);
}

.roles__role--devops {
  --role-accent: var(--color-magenta);
}

.roles__role--devsecops {
  --role-accent: var(--color-cyan-bright);
}

.roles__role--platform {
  --role-accent: var(--color-green);
}

.roles__role--finops {
  --role-accent: var(--color-yellow);
}

/* ==========================================================================
   Service sections
   ========================================================================== */

.service {
  display: flex;
  justify-content: center;
  padding: var(--space-4) var(--space-3);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
}

.service__card {
  position: relative;
  width: 100%;
  max-width: 46rem;
  background-color: #081319;
  border: 1px solid rgba(215, 222, 234, 0.15);
  border-radius: 8px;
  padding: var(--space-4) var(--space-3);
}

.service__glyph {
  display: inline-block;
  font-size: 1.75rem;
  line-height: 1;
  margin-bottom: var(--space-2);
}

.service__heading {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
}

.service__description {
  max-width: 65ch;
}

.service__list {
  max-width: 65ch;
  color: var(--color-fg);
}

.service__list li {
  margin-bottom: var(--space-1);
}

.service--blue .service__card {
  border-color: rgba(64, 157, 212, 0.4);
  box-shadow: 0 0 24px rgba(64, 157, 212, 0.12);
}

.service--blue .service__glyph {
  color: var(--color-blue);
}

.service--red .service__card {
  border-color: rgba(255, 101, 122, 0.4);
  box-shadow: 0 0 24px rgba(255, 101, 122, 0.12);
}

.service--red .service__glyph {
  color: var(--color-red);
}

.service--yellow .service__card {
  border-color: rgba(255, 198, 76, 0.4);
  box-shadow: 0 0 24px rgba(255, 198, 76, 0.12);
}

.service--yellow .service__glyph {
  color: var(--color-yellow);
}

.service--magenta .service__card {
  border-color: rgba(203, 163, 199, 0.4);
  box-shadow: 0 0 24px rgba(203, 163, 199, 0.12);
}

.service--magenta .service__glyph {
  color: var(--color-magenta);
}

.service--green .service__card {
  border-color: rgba(140, 201, 143, 0.4);
  box-shadow: 0 0 24px rgba(140, 201, 143, 0.12);
}

.service--green .service__glyph {
  color: var(--color-green);
}

.service--cyan .service__card {
  border-color: rgba(55, 181, 180, 0.4);
  box-shadow: 0 0 24px rgba(55, 181, 180, 0.12);
}

.service--cyan .service__glyph {
  color: var(--color-cyan);
}

/* ==========================================================================
   Leadership band

   A wrapper around the two fractional sections, not a new card component —
   the cards inside stay plain `.service` blocks. The tinted background and
   the header are what mark leadership as a second tier below the four
   loop disciplines.
   ========================================================================== */

.leadership {
  background-color: rgba(64, 157, 212, 0.04);
  border-top: 1px solid rgba(215, 222, 234, 0.15);
  border-bottom: 1px solid rgba(215, 222, 234, 0.1);
  padding-top: var(--space-5);
}

.leadership__head {
  width: 100%;
  max-width: 46rem;
  margin: 0 auto var(--space-3);
  padding: 0 var(--space-3);
}

/* Same tracked-label rhythm as .drift__eyebrow and .loop__visual-head. */
.leadership__eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--color-yellow);
  font-size: var(--label-size);
  letter-spacing: var(--label-tracking);
}

.leadership__heading {
  max-width: 20ch;
  font-size: clamp(1.6rem, 3.5vw, 2.5rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
}

.leadership__lede {
  max-width: 46ch;
  margin: 0 0 var(--space-2);
  color: rgba(215, 222, 234, 0.7);
  font-size: 0.95rem;
}

.leadership__prompt {
  margin: 0;
  color: var(--color-fg);
}

/* The band's own edge already separates it from the contact section. */
.leadership .service:last-child {
  border-bottom: 0;
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact {
  display: flex;
  justify-content: center;
  padding: var(--space-5) var(--space-3);
}

/* Sits next to .cmd__sub, which is the same hue — the underline is what marks
   it as the clickable part of the command rather than more of the command. */
.contact__link {
  color: var(--color-cyan-bright);
  text-decoration: underline;
  text-underline-offset: 0.25em;
  text-decoration-color: rgba(132, 228, 227, 0.5);
}

.contact__link:hover,
.contact__link:focus {
  text-decoration-color: var(--color-cyan-bright);
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding: var(--space-3);
  text-align: center;
  border-top: 1px solid rgba(215, 222, 234, 0.15);
  font-size: 0.875rem;
}

.site-footer__links {
  list-style: none;
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  margin: var(--space-1) 0 0;
  padding: 0;
  font-size: 0.8rem;
}

/* ==========================================================================
   Responsive breakpoints
   ========================================================================== */

/* Tablet and below (~768px) */
@media (max-width: 768px) {
  .nav {
    justify-content: flex-start;
    padding: var(--space-2);
  }

  .nav__links {
    gap: var(--space-2);
    font-size: 0.9rem;
  }

  .nav__item--band {
    padding-left: var(--space-2);
  }

  .loop {
    padding: var(--space-4) var(--space-2);
  }

  /* Single column — diagram above the copy is too tall, so copy leads. */
  .loop__shell {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }

  .drift {
    padding: var(--space-4) var(--space-2);
  }

  /* Four across is too cramped; 2×2 keeps the escalation readable. The chart
     scrolls independently here, so the strip no longer tracks it — the plain
     `gap` gutter is simpler than the half-margin the aligned layout needs. */
  .drift__stages {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
  }

  .drift__stage {
    margin-inline: 0;
  }

  /* No margin to offset here, so the separator sits on the card edge. Card 3
     opens the second row, so it gets no left separator. */
  .drift__stage + .drift__stage::after {
    left: calc(-0.5 * var(--space-2));
  }

  .drift__stage:nth-child(3)::after {
    display: none;
  }

  .drift__stage:nth-child(n + 3) {
    border-top: 1px solid rgba(215, 222, 234, 0.1);
  }

  /* Chevrons point along a single row; they misread in a 2×2 grid. */
  .drift__stage + .drift__stage::before {
    display: none;
  }

  .drift__head {
    margin-bottom: var(--space-3);
  }

  /* The chart's labels don't survive being squeezed — let it scroll at its
     natural width instead of collapsing into overlap. */
  .drift__chart {
    overflow-x: auto;
  }

  .drift__chart svg {
    min-width: 40rem;
  }

  .approach {
    padding: var(--space-4) var(--space-2);
  }

  /* Three across gets cramped; a single column keeps the steps ordered and
     the bullets readable. */
  .approach__steps {
    grid-template-columns: 1fr;
  }

  .approach__head {
    margin-bottom: var(--space-3);
  }

  .stack {
    padding: var(--space-4) var(--space-2);
  }

  /* Three across gets cramped; the columns are a flat set, so stacking them
     costs nothing. */
  .stack__groups {
    grid-template-columns: 1fr;
  }

  /* Stacked, the dividers run the wrong way. */
  .stack__group + .stack__group {
    border-left: 0;
    border-top: 1px solid rgba(215, 222, 234, 0.1);
  }

  /* Stacked, there's no sibling row to align to — the reserved two-line
     height is just a gap. */
  .stack__group-head {
    min-height: 0;
  }

  .stack__head {
    margin-bottom: var(--space-3);
  }

  .terminal__body {
    padding: var(--space-3) var(--space-2);
  }

  .service {
    padding: var(--space-3) var(--space-2);
  }

  .service__card {
    padding: var(--space-3) var(--space-2);
  }

  .caps {
    padding: var(--space-4) var(--space-2);
  }

  /* Two across squeezes each card's three pillars past readable. */
  .caps__list {
    grid-template-columns: 1fr;
  }

  .caps__head {
    margin-bottom: var(--space-3);
  }

  .roles {
    padding: var(--space-2);
  }

  /* Five don't fit across this width; 3+2 is the clean split, and the glyph
     steps down with it. */
  .roles__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .roles__glyph svg {
    width: 3.4rem;
    height: 3.4rem;
  }

  .leadership {
    padding-top: var(--space-4);
  }

  .leadership__head {
    padding: 0 var(--space-2);
  }

  .contact {
    padding: var(--space-4) var(--space-2);
  }
}

/* Mobile (~480px and below) */
@media (max-width: 480px) {
  /* Long commands would otherwise overflow the slab rather than wrap inside it. */
  /* Long commands wrap inside the slab rather than overflowing it. */
  .cmd {
    white-space: normal;
    flex-wrap: wrap;
  }

  .nav {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
  }

  .nav__links {
    flex-direction: column;
    gap: var(--space-1);
    width: 100%;
  }

  /* Stacked links — the band separator becomes a rule above, not beside. */
  .nav__item--band {
    border-left: none;
    border-top: 1px solid rgba(215, 222, 234, 0.15);
    padding-left: 0;
    padding-top: var(--space-1);
  }

  .loop__intro {
    max-width: 100%;
  }

  /* Too narrow for labels beside the ring — the pills below carry them. */
  .loop__diagram {
    aspect-ratio: 820 / 568;
  }

  .loop__label,
  .loop__sub {
    display: none;
  }

  .loop__pill {
    font-size: 0.8rem;
  }

  .loop__detail {
    min-height: 5rem;
  }

  .loop__core-label {
    font-size: 0.95rem;
  }

  /* Single column — the four stages read as a top-to-bottom timeline. */
  .drift__stages {
    grid-template-columns: 1fr;
  }

  .drift__stage {
    padding: var(--space-2);
  }

  /* Stacked: the rows are divided top-to-bottom, never side-to-side. */
  .drift__stage + .drift__stage::after {
    display: none;
  }

  .drift__stage:nth-child(n + 2) {
    border-top: 1px solid rgba(215, 222, 234, 0.1);
  }

  .drift__stage--4 {
    border: 1px solid var(--color-red);
  }

  .drift__heading,
  .drift__lede,
  .drift__intro,
  .drift__close {
    max-width: 100%;
  }

  .approach__heading,
  .approach__lede,
  .approach__intro {
    max-width: 100%;
  }

  .approach__step {
    padding: var(--space-2);
    border-left-width: 2px;
  }

  /* Long findings wrap under their badge rather than squeezing the text
     column to a few characters. */
  .approach__finding {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  .approach__mark {
    white-space: normal;
  }

  .stack__heading,
  .stack__lede,
  .stack__intro,
  .stack__close {
    max-width: 100%;
  }

  .stack__group {
    padding: var(--space-2);
  }

  /* Long output rows wrap under their key instead of squeezing the message
     column to a few characters. */
  .stack__output li {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  .stack__key {
    min-width: 0;
  }

  .terminal__titlebar-label {
    font-size: 0.7rem;
  }

  .service__heading {
    flex-wrap: wrap;
  }

  h2 {
    font-size: 1.35rem;
  }

  .service__description,
  .service__list {
    max-width: 100%;
  }

  .caps__heading {
    max-width: 100%;
  }

  .caps__card {
    padding: var(--space-3) var(--space-2) var(--space-2);
  }

  /* Three pillars across leaves two words per column here — stacked, each
     keeps its accent rule and reads as a heading with a line under it. */
  .caps__pillars {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }

  /* Pinned to two rather than left to auto-fit: at this width the tracks are
     narrow enough that the gloss wraps to three ragged lines, so the cap comes
     off and each column takes the full track. */
  /* Three across squeezes the glyph past the size that makes it the point;
     two keeps it large. */
  .roles__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3) var(--space-1);
  }

  .roles__glyph svg {
    width: 3.15rem;
    height: 3.15rem;
  }

  .leadership {
    padding-top: var(--space-3);
  }

  .leadership__heading,
  .leadership__lede {
    max-width: 100%;
  }

  .leadership__prompt {
    font-size: 0.9rem;
  }

  .site-footer__links {
    flex-direction: column;
    gap: var(--space-1);
  }
}
