/* ============================================================
   INTELLICAMP — Service pages
   Unlike the industry pages, these do NOT share one section set.
   Each service gets the components its story needs, so this file is
   organised by component and every page picks the ones it uses.

   Shared with the rest of the site: header, footer, cards, tags,
   accordion, quotes, work tiles, and all of motion.js. Everything
   below is new.

   TYPE RULE, same as industry.css so nothing drifts:
     section titles  var(--step-1)
     small labels    0.72rem, 0.16em tracking, uppercase
   ============================================================ */

/* ============================================================
   A. SHARED — hero, breadcrumb echo, section furniture
   ============================================================ */

/* Deliberately not .hero: the boot curtain in motion.js is gated on
   .hero and a five-second lockup belongs to the landing page only. */
.svc-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3rem, 8vw, 6rem) clamp(2.6rem, 6vw, 4.4rem);
}

.svc-hero__inner { position: relative; z-index: 1; }

.svc-hero h1 {
  font-size: clamp(2.3rem, 6.4vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -0.045em;
  max-width: 16ch;
  margin-bottom: 1.4rem;
}

.svc-hero .lede { max-width: 60ch; margin-bottom: 2rem; }
.svc-hero .hero__cta { margin-bottom: 2.2rem; }

/* ============================================================
   A2. SERVICE BANNER — the layered field behind the hero
   Four stacked layers, each moving at a different rate against the
   pointer: a drifting grid, an accent bloom, a drawn network, and a
   single slow light sweep. Every layer is decoration and carries
   aria-hidden, so none of it is in the accessibility tree.
   ============================================================ */
.sbn {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  /* set by service.js on pointer move; 0 until then, so the layers
     are in their resting position on a device with no pointer */
  --px: 0;
  --py: 0;
}

/* --- layer 1: the plotting grid ----------------------------- */
.sbn__grid {
  position: absolute;
  inset: -60px;
  opacity: 0.75;
  background-image:
    radial-gradient(circle at center, var(--line) 1.1px, transparent 1.2px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px),
    linear-gradient(var(--line-soft) 1px, transparent 1px);
  background-size: 34px 34px, 170px 100%, 100% 170px;
  mask-image: radial-gradient(125% 90% at 22% 0%, #000 4%, transparent 74%);
  -webkit-mask-image: radial-gradient(125% 90% at 22% 0%, #000 4%, transparent 74%);
  translate: calc(var(--px) * -14px) calc(var(--py) * -14px);
  transition: translate 1.2s var(--ease);
  animation: sbn-drift 34s linear infinite;
}

@keyframes sbn-drift {
  to { background-position: 34px 34px, 170px 0, 0 170px; }
}

/* --- layer 2: the accent bloom ------------------------------ */
.sbn__glow {
  position: absolute;
  top: -22%;
  right: -14%;
  width: 68%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--deco-rgb), 0.16), transparent 62%);
  filter: blur(28px);
  opacity: 0;
  translate: calc(var(--px) * 34px) calc(var(--py) * 30px);
  transition: translate 1.4s var(--ease);
  animation: sbn-bloom 1.6s var(--ease) 0.2s forwards, sbn-breathe 9s ease-in-out 1.8s infinite;
}

@keyframes sbn-bloom { to { opacity: 1; } }
@keyframes sbn-breathe { 0%, 100% { scale: 1; } 50% { scale: 1.09; } }

/* --- layer 3: the decision network -------------------------- *
   Options drawn as a graph: routes that get explored and abandoned
   in muted line, the one that survives in accent. It is the service
   in one picture, which is the only reason it earns the bytes. */
.sbn__net {
  position: absolute;
  top: 50%;
  right: 1.5%;
  /* Sized to clear the text column, not to fill the hero — measured at
     1280/1440/1600/1920, where the lede is the widest run. The left edge
     is masked as well, so a stray node can never sit on a word. */
  width: min(30%, 440px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 20%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

@media (max-width: 1279px) {
  /* below this the hero has no empty side; grid, bloom and sweep stay */
  .sbn__net { display: none; }
}

.sbn__link {
  fill: none;
  stroke-linecap: round;
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
  animation: sbn-draw 1.15s var(--ease) forwards;
  animation-delay: calc(0.45s + var(--d, 0) * 0.16s);
}

.sbn__link--dead { stroke: var(--line); stroke-width: 1.2; }

.sbn__link--live {
  stroke: rgba(var(--deco-rgb), 0.62);
  stroke-width: 1.9;
}

@keyframes sbn-draw { to { stroke-dashoffset: 0; } }

.sbn__node {
  fill: var(--ink);
  stroke: var(--line);
  stroke-width: 1.4;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: sbn-node 0.55s var(--ease) forwards;
  animation-delay: calc(0.6s + var(--d, 0) * 0.16s);
}

.sbn__node--live { stroke: var(--accent-ink); }

@keyframes sbn-node {
  from { opacity: 0; scale: 0.2; }
  to { opacity: 1; scale: 1; }
}

/* the surviving option, marked once the graph has finished drawing */
.sbn__pick {
  fill: var(--accent-ink);
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: sbn-pick 0.7s var(--ease) 2.5s forwards;
}

@keyframes sbn-pick {
  0% { opacity: 0; scale: 0.2; }
  60% { opacity: 1; scale: 1.5; }
  100% { opacity: 1; scale: 1; }
}

.sbn__halo {
  fill: none;
  stroke: var(--accent-ink);
  stroke-width: 1.2;
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: sbn-halo 2.6s ease-out 2.9s infinite;
}

@keyframes sbn-halo {
  0% { opacity: 0.7; scale: 0.5; }
  70%, 100% { opacity: 0; scale: 2.2; }
}

/* a pulse that runs the surviving route, so the eye is walked along it */
.sbn__pulse {
  fill: var(--accent-ink);
  offset-path: path("M60 430 L170 330 L300 255 L450 190 L545 95");
  offset-distance: 0%;
  offset-rotate: 0deg;
  opacity: 0;
  animation: sbn-run 3.4s var(--ease) 2.7s infinite;
}

@keyframes sbn-run {
  0% { offset-distance: 0%; opacity: 0; }
  8% { opacity: 1; }
  62% { offset-distance: 100%; opacity: 1; }
  75%, 100% { offset-distance: 100%; opacity: 0; }
}

/* --- layer 3b: the eval matrix (AI Engineering) -------------- *
   The same slot as the decision network, holding a different picture:
   a grid of test cases turning over, most passing, some not. Cells are
   built in service.js rather than shipped as sixty rects of markup. */
.sbn__eval {
  position: absolute;
  top: 50%;
  right: 1.5%;
  width: min(30%, 440px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 20%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

@media (max-width: 1279px) {
  .sbn__eval { display: none; }
}

.sbn__cell {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: sbn-cell 0.5s var(--ease) forwards;
  animation-delay: calc(0.4s + var(--d, 0) * 0.035s);
}

.sbn__cell--pass { fill: rgba(var(--deco-rgb), 0.34); }
.sbn__cell--fail { fill: var(--coral); opacity: 0; }
.sbn__cell--idle { fill: var(--line); }

@keyframes sbn-cell {
  from { opacity: 0; scale: 0.4; }
  to { opacity: 1; scale: 1; }
}

/* a re-run sweeping the matrix column by column, forever */
.sbn__runbar {
  fill: rgba(var(--deco-rgb), 0.14);
  animation: sbn-rerun 7s var(--ease) 3s infinite;
}

@keyframes sbn-rerun {
  0% { transform: translateX(0); opacity: 0; }
  10%, 70% { opacity: 1; }
  85%, 100% { transform: translateX(400px); opacity: 0; }
}

/* --- layer 3c: the waterfall (Web Platforms) ----------------- *
   A network waterfall: what a page spends, in the order it spends it,
   with the paint marker landing where the budget says it should. */
.sbn__wf {
  position: absolute;
  top: 50%;
  right: 1.5%;
  width: min(30%, 440px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 20%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

@media (max-width: 1279px) {
  .sbn__wf { display: none; }
}

.sbn__wfbar {
  transform-box: fill-box;
  transform-origin: left center;
  scale: 0 1;
  animation: sbn-bar 0.7s var(--ease) forwards;
  animation-delay: calc(0.45s + var(--d, 0) * 0.13s);
}

@keyframes sbn-bar { to { scale: 1 1; } }

.sbn__wfbar--fast { fill: rgba(var(--deco-rgb), 0.5); }
.sbn__wfbar--slow { fill: var(--line); }
.sbn__wfbar--block { fill: var(--coral); opacity: 0.75; }

/* the paint marker, dropped once the bars have run */
.sbn__mark {
  stroke: var(--accent-ink);
  stroke-width: 1.4;
  stroke-dasharray: 4 4;
  opacity: 0;
  animation: sbn-mark 0.6s var(--ease) 2.1s forwards;
}

.sbn__marklabel {
  fill: var(--accent-ink);
  font-family: ui-monospace, monospace;
  font-size: 11px;
  opacity: 0;
  animation: sbn-mark 0.6s var(--ease) 2.3s forwards;
}

@keyframes sbn-mark { to { opacity: 1; } }

/* --- layer 3d: the release train (Mobile Apps) --------------- *
   Versions marching right, each with a hatched gap where the store
   review sits — the part of a mobile release nobody controls. */
.sbn__train {
  position: absolute;
  top: 50%;
  right: 1.5%;
  width: min(30%, 440px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 20%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

@media (max-width: 1279px) {
  .sbn__train { display: none; }
}

.sbn__ship {
  transform-box: fill-box;
  transform-origin: left center;
  scale: 0 1;
  animation: sbn-bar 0.65s var(--ease) forwards;
  animation-delay: calc(0.45s + var(--d, 0) * 0.15s);
}

.sbn__ship--build { fill: rgba(var(--deco-rgb), 0.5); }
.sbn__ship--wait { fill: none; stroke: var(--coral); stroke-width: 1.1; stroke-dasharray: 3 3; }
.sbn__ship--live { fill: var(--accent-ink); }

/* --- layer 3e: the pipeline (Cloud & DevOps) ----------------- *
   Stages joined by a rail with a build running it, forever. */
.sbn__pipe {
  position: absolute;
  top: 50%;
  right: 1.5%;
  width: min(30%, 440px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 20%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

@media (max-width: 1279px) {
  .sbn__pipe { display: none; }
}

.sbn__rail {
  stroke: var(--line);
  stroke-width: 1.4;
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
  animation: sbn-draw 1.5s var(--ease) 0.4s forwards;
}

.sbn__stage {
  fill: var(--ink);
  stroke: rgba(var(--deco-rgb), 0.6);
  stroke-width: 1.4;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: sbn-node 0.5s var(--ease) forwards;
  animation-delay: calc(0.7s + var(--d, 0) * 0.17s);
}

.sbn__build {
  fill: var(--accent-ink);
  offset-path: path("M20 30 L120 30 L120 90 L240 90 L240 150 L400 150");
  offset-distance: 0%;
  offset-rotate: 0deg;
  opacity: 0;
  animation: sbn-run 3.8s var(--ease) 2.4s infinite;
}

/* --- layer 3f: the integration hub (ERP/CRM) ----------------- *
   A core with spokes, and data arriving along them. */
.sbn__hub {
  position: absolute;
  top: 50%;
  right: 1.5%;
  width: min(26%, 360px);
  translate: calc(var(--px) * 22px) calc(-50% + var(--py) * 20px);
  transition: translate 1.3s var(--ease);
  overflow: visible;
  mask-image: linear-gradient(90deg, transparent 0, #000 16%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16%);
}

@media (max-width: 1279px) {
  .sbn__hub { display: none; }
}

.sbn__spoke {
  stroke: var(--line);
  stroke-width: 1.2;
  stroke-dasharray: var(--len, 200);
  stroke-dashoffset: var(--len, 200);
  animation: sbn-draw 0.9s var(--ease) forwards;
  animation-delay: calc(0.5s + var(--d, 0) * 0.12s);
}

.sbn__sys {
  fill: var(--ink);
  stroke: var(--line);
  stroke-width: 1.3;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: sbn-node 0.5s var(--ease) forwards;
  animation-delay: calc(0.75s + var(--d, 0) * 0.12s);
}

.sbn__core {
  fill: none;
  stroke: var(--accent-ink);
  stroke-width: 1.8;
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: sbn-pick 0.7s var(--ease) 1.5s forwards;
}

.sbn__pulseIn {
  fill: var(--accent-ink);
  opacity: 0;
  animation: sbn-in 3.2s var(--ease) infinite;
  animation-delay: calc(2s + var(--d, 0) * 0.42s);
}

@keyframes sbn-in {
  0% { opacity: 0; }
  12% { opacity: 1; }
  62% { opacity: 1; }
  70%, 100% { opacity: 0; }
}

/* --- layer 4: one slow sweep of light ----------------------- */
.sbn__scan {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 42%;
  background: linear-gradient(100deg, transparent, rgba(var(--deco-rgb), 0.05) 45%, transparent);
  animation: sbn-scan 11s var(--ease) 1.2s infinite;
}

@keyframes sbn-scan {
  0% { left: -46%; }
  55%, 100% { left: 108%; }
}

/* .char-word lives in motion.css now — splitChars() builds it on every
   page, not just these. */

/* --- the accent rule under the headline --------------------- */
.sbn-rule {
  display: block;
  width: 168px;
  height: 2px;
  margin-bottom: 1.5rem;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  transform: scaleX(0);
  transform-origin: left;
  animation: sbn-rule 1s var(--ease) 0.85s forwards;
}

@keyframes sbn-rule { to { transform: scaleX(1); } }

/* --- badges: staggered in, then one shimmer pass ------------- */
.svc-badges .tag {
  position: relative;
  overflow: hidden;
  opacity: 0;
  animation: sbn-tag 0.6s var(--ease) forwards;
  animation-delay: calc(1.35s + var(--i, 0) * 0.09s);
}

@keyframes sbn-tag {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.svc-badges .tag::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(var(--accent-rgb), 0.4) 50%, transparent 70%);
  translate: -140% 0;
  animation: sbn-shine 1.1s var(--ease) forwards;
  animation-delay: calc(2.1s + var(--i, 0) * 0.09s);
}

@keyframes sbn-shine { to { translate: 140% 0; } }

/* --- everything above is decoration; switch it all off ------- */
[data-motion="off"] .sbn__grid,
[data-motion="off"] .sbn__glow,
[data-motion="off"] .sbn__scan { animation: none; opacity: 1; }

[data-motion="off"] .sbn__link { animation: none; stroke-dashoffset: 0; }
[data-motion="off"] .sbn__node,
[data-motion="off"] .sbn__pick { animation: none; opacity: 1; }
[data-motion="off"] .sbn__halo,
[data-motion="off"] .sbn__pulse { display: none; }
[data-motion="off"] .sbn-rule { animation: none; transform: none; }
[data-motion="off"] .svc-badges .tag { animation: none; opacity: 1; }
[data-motion="off"] .svc-badges .tag::after { display: none; }

/* --- the service's own tag row --- */
.svc-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.svc-badges .tag {
  border-color: var(--line);
  color: var(--muted);
  transition: border-color 0.3s ease, color 0.3s ease, transform 0.35s var(--ease);
}

.svc-badges .tag:hover { border-color: var(--accent-ink); color: var(--accent-ink); transform: translateY(-2px); }

/* the current service, marked in the mega menu */
.mega__link.is-here strong { color: var(--accent-ink); }

/* --- price / commitment strip under the hero ---------------- *
   Was the one block on these pages with no motion of its own: the
   whole strip faded in as a single [data-reveal] and then sat still.
   Now each cell arrives on its own beat, a hairline sweeps the
   divider between them, and hovering lifts one cell out. */
.svc-facts {
  position: relative;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--line-soft);
}

.svc-facts div {
  position: relative;
  overflow: hidden;
  padding: clamp(1.1rem, 2.4vw, 1.5rem);
  background: var(--ink-2);
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.7s var(--ease), transform 0.85s var(--ease), background 0.4s ease;
  transition-delay: calc(var(--i, 0) * 0.16s);
}

.svc-facts.is-in div { opacity: 1; transform: none; }
.svc-facts div:hover { background: var(--ink-3); }

/* a light that runs the top edge of each cell as it lands */
.svc-facts div::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.9s var(--ease);
  transition-delay: calc(0.3s + var(--i, 0) * 0.16s);
}

.svc-facts.is-in div::before { transform: scaleX(1); }

/* An entrance is over in a second and is easy to scroll straight past.
   This keeps a slow highlight travelling the strip so there is always
   something moving, whenever the visitor happens to look at it. */
.svc-facts::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 38%;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(100deg, transparent, rgba(var(--accent-rgb), 0.07) 48%, transparent);
  left: -42%;
}

.svc-facts.is-in::after { animation: facts-sweep 6.5s var(--ease) 1.4s infinite; }

@keyframes facts-sweep {
  0% { left: -42%; }
  55%, 100% { left: 106%; }
}

.svc-facts b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.3rem, 3vw, 1.9rem);
  letter-spacing: -0.03em;
  color: var(--paper);
  transition: color 0.35s ease, transform 0.5s var(--ease);
}

.svc-facts div:hover b { color: var(--accent-ink); transform: translateX(4px); }

.svc-facts span {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

[data-motion="off"] .svc-facts div,
[data-motion="off"] .svc-facts div::before { transition: none; opacity: 1; transform: none; }
[data-motion="off"] .svc-facts::after { display: none; }

@media (prefers-reduced-motion: reduce) {
  .svc-facts div,
  .svc-facts div::before { transition: none; opacity: 1; transform: none; }
  .svc-facts::after { display: none; }
}

/* ============================================================
   B. TRIGGERS — "you are probably here because…"
   Quote-led cards. The symptom is the headline; the diagnosis is
   the small print underneath it.
   ============================================================ */
.trig {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.trig__item {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: clamp(1.4rem, 3vw, 1.9rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  transition: border-color 0.4s ease, transform 0.5s var(--ease);
}

.trig__item:hover { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.45); transform: translateY(-4px); }

/* the quote mark sits behind the text, cropped by the card */
.trig__mark {
  position: absolute;
  top: -0.42em;
  right: 0.1em;
  z-index: -1;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(6rem, 14vw, 9rem);
  line-height: 1;
  color: var(--pc, var(--accent));
  opacity: 0.09;
  pointer-events: none;
}

.trig__said {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-1);
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--paper);
  max-width: 24ch;
}

.trig__rule {
  display: block;
  height: 1px;
  margin: 1rem 0;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease);
}

.trig__item.is-in .trig__rule { transform: scaleX(1); }

.trig__mean { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

.trig__mean b {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pc, var(--accent));
}

/* ============================================================
   C. AGENDA — the sprint, day by day
   A spine with a fill that draws as you scroll, and rows that open
   without measuring anything (0fr → 1fr).
   ============================================================ */
.agenda { position: relative; display: grid; gap: 0.5rem; padding-left: 2.4rem; }

.agenda::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 10px;
  bottom: 10px;
  width: 2px;
  background: var(--line-soft);
}

.agenda__fill {
  position: absolute;
  left: 11px;
  top: 10px;
  width: 2px;
  height: 0;
  background: linear-gradient(var(--p1), var(--p4), var(--p6));
  transition: height 1.7s var(--ease);
}

/* week dividers break ten days into two halves */
.agenda__week {
  position: relative;
  margin: 0.9rem 0 0.5rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

.agenda__week::before {
  content: "";
  position: absolute;
  left: -2.4rem;
  top: 50%;
  width: 24px;
  height: 1px;
  background: var(--line);
}

.agenda__day { position: relative; }

.agenda__node {
  position: absolute;
  left: -2.4rem;
  top: 1.15rem;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--ink);
  transition: border-color 0.4s ease, background 0.4s ease;
}

.agenda__node::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--line);
  transition: background 0.4s ease, transform 0.4s var(--ease);
}

.agenda__day.lit .agenda__node { border-color: var(--pc, var(--accent)); }
.agenda__day.lit .agenda__node::after { background: var(--pc, var(--accent)); transform: scale(1.25); }

.agenda__btn {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--ink-2);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.35s ease, background 0.35s ease;
}

.agenda__btn:hover { border-color: var(--line); }
.agenda__day.is-open .agenda__btn { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.5); border-radius: var(--radius) var(--radius) 0 0; }

.agenda__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--muted-3);
  min-width: 3.4em;
}

.agenda__day.is-open .agenda__n { color: var(--pc, var(--accent)); }

.agenda__t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
}

.agenda__chev {
  width: 11px;
  height: 11px;
  border-right: 1.6px solid var(--muted-2);
  border-bottom: 1.6px solid var(--muted-2);
  rotate: 45deg;
  transition: rotate 0.4s var(--ease), border-color 0.3s ease;
}

.agenda__day.is-open .agenda__chev { rotate: -135deg; border-color: var(--pc, var(--accent)); }

/* measurement-free open/close */
.agenda__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s var(--ease);
}

.agenda__day.is-open .agenda__panel { grid-template-rows: 1fr; }

.agenda__panel > div { overflow: hidden; }

.agenda__body {
  padding: 0 1.2rem 1.2rem;
  border: 1px solid rgba(var(--pc-rgb, var(--accent-rgb)), 0.5);
  border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--ink-2);
}

.agenda__body p { font-size: var(--step--1); line-height: 1.65; color: var(--muted-2); max-width: 74ch; }

.agenda__room {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px dashed var(--line-soft);
}

.agenda__room b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
  margin-right: 0.3rem;
  align-self: center;
}

/* ============================================================
   D. ARTEFACTS — what actually lands on your desk
   Cards drawn as documents: ruled "text", a corner fold that lifts.
   ============================================================ */
.arte {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
}

.arte__item {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: 260px;
  padding: clamp(1.3rem, 2.8vw, 1.7rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  transition: border-color 0.4s ease, transform 0.5s var(--ease);
}

.arte__item:hover { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.5); transform: translateY(-5px); }

/* the folded corner */
.arte__fold {
  position: absolute;
  top: 0;
  right: 0;
  width: 42px;
  height: 42px;
  background: linear-gradient(225deg, var(--ink-3) 50%, transparent 50%);
  border-left: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  transition: width 0.45s var(--ease), height 0.45s var(--ease);
}

.arte__item:hover .arte__fold { width: 56px; height: 56px; }

.arte__k {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pc, var(--accent));
}

.arte__item h3 {
  margin-top: 0.6rem;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  max-width: 15ch;
}

.arte__item p {
  margin-top: 0.6rem;
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted-2);
}

/* ruled lines standing in for the document's body text */
.arte__rules {
  margin-top: auto;
  padding-top: 1.4rem;
  display: grid;
  gap: 6px;
}

.arte__rules i {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.8s var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.arte__item.is-in .arte__rules i { transform: scaleX(1); }
.arte__rules i:nth-child(1) { width: 100%; }
.arte__rules i:nth-child(2) { width: 82%; }
.arte__rules i:nth-child(3) { width: 91%; }
.arte__rules i:nth-child(4) { width: 46%; background: var(--pc, var(--accent)); opacity: 0.65; }

/* ============================================================
   E. QUADRANT — bet sizing
   A real plot: two axes, four named quadrants, bets positioned with
   --x / --y. Hovering the list highlights the dot and vice versa.
   ============================================================ */
.quad { display: grid; gap: 1.6rem; }

@media (min-width: 940px) {
  /* The plot is square, so it needs a ceiling — left to fill the column it
     becomes 860px tall and pushes the list into a void beside it. */
  .quad { grid-template-columns: minmax(0, 520px) 1fr; gap: 2.8rem; align-items: center; }
}

.quad__plot {
  position: relative;
  max-width: 520px;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px) 0 0 / 10% 100%,
    linear-gradient(var(--line-soft) 1px, transparent 1px) 0 0 / 100% 10%,
    var(--ink-2);
  overflow: hidden;
}

/* the two heavy midlines that split the four quadrants */
.quad__cross {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, transparent calc(50% - 1px), var(--line) calc(50% - 1px), var(--line) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(transparent calc(50% - 1px), var(--line) calc(50% - 1px), var(--line) calc(50% + 1px), transparent calc(50% + 1px));
}

.quad__zone {
  position: absolute;
  width: 50%;
  height: 50%;
  display: grid;
  align-content: start;
  gap: 0.15rem;
  padding: clamp(0.8rem, 2vw, 1.2rem);
  pointer-events: none;
}

.quad__zone b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.quad__zone span { font-size: var(--step--1); color: var(--muted-3); max-width: 20ch; line-height: 1.45; }

.quad__zone--tl { top: 0; left: 0; }
.quad__zone--tr { top: 0; right: 0; text-align: right; justify-items: end; }
.quad__zone--bl { bottom: 0; left: 0; align-content: end; }
.quad__zone--br { bottom: 0; right: 0; align-content: end; text-align: right; justify-items: end; }

/* the top-left zone is the one you want to be in — tint it */
.quad__zone--tl { background: radial-gradient(90% 90% at 0% 0%, rgba(var(--accent-rgb), 0.08), transparent 70%); }

.quad__axis {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
  pointer-events: none;
}

.quad__axis--x { bottom: 0.55rem; left: 50%; translate: -50% 0; }
.quad__axis--y { top: 50%; left: 0.55rem; translate: 0 -50%; rotate: -90deg; transform-origin: left center; }

.quad__dot {
  position: absolute;
  left: calc(var(--x) * 1%);
  bottom: calc(var(--y) * 1%);
  width: 15px;
  height: 15px;
  translate: -50% 50%;
  border-radius: 50%;
  border: 0;
  padding: 0;
  background: var(--pc, var(--accent));
  cursor: pointer;
  scale: 0;
  transition: scale 0.5s var(--ease), box-shadow 0.35s ease;
  transition-delay: calc(var(--i, 0) * 70ms);
}

.quad.is-in .quad__dot { scale: 1; }

.quad__dot::after {
  content: "";
  position: absolute;
  inset: -9px;
  border-radius: 50%;
  border: 1px solid var(--pc, var(--accent));
  opacity: 0;
  scale: 0.6;
  transition: opacity 0.35s ease, scale 0.45s var(--ease);
}

.quad__dot.on { box-shadow: 0 0 0 4px rgba(var(--ink-rgb), 0.8); z-index: 2; }
.quad__dot.on::after { opacity: 0.9; scale: 1; }

.quad__list { display: grid; gap: 0.4rem; align-content: start; }

.quad__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.7rem;
  align-items: start;
  width: 100%;
  padding: 0.75rem 0.9rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.quad__row:hover, .quad__row.on { background: var(--ink-2); border-color: var(--line-soft); }

.quad__swatch {
  width: 9px;
  height: 9px;
  margin-top: 0.42em;
  border-radius: 50%;
  background: var(--pc, var(--accent));
}

.quad__row b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: -0.01em;
  color: var(--paper);
}

/* Deliberately a class, not `.quad__row span` — that also matches the
   wrapper span and the swatch, and collapses the whole row to bare padding. */
.quad__note {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--muted-3);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.45s var(--ease), opacity 0.3s ease, margin 0.35s var(--ease);
}

.quad__row.on .quad__note { max-height: 7em; opacity: 1; }

/* ============================================================
   F. QUESTIONS — what we will ask you
   A ruled list; the accent bar grows as each row reveals.
   ============================================================ */
.qask { display: grid; gap: 0; border-top: 1px solid var(--line-soft); }

.qask__row {
  position: relative;
  display: grid;
  gap: 0.3rem 1.4rem;
  padding: 1.15rem 0 1.15rem 1.2rem;
  border-bottom: 1px solid var(--line-soft);
}

@media (min-width: 800px) {
  .qask__row { grid-template-columns: 1fr minmax(0, 34ch); align-items: baseline; }
}

.qask__row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.15rem;
  bottom: 1.15rem;
  width: 2px;
  border-radius: 2px;
  background: var(--pc, var(--accent));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.6s var(--ease);
}

.qask__row.is-in::before { transform: scaleY(1); }

.qask__q {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  color: var(--paper);
}

.qask__why { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

.qask__why b {
  display: block;
  margin-bottom: 0.2rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

/* ============================================================
   G. ANTI — when you should not hire us for this
   Deliberately the odd panel out on the page.
   ============================================================ */
.anti {
  position: relative;
  overflow: hidden;
  padding: clamp(1.6rem, 4vw, 2.6rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    repeating-linear-gradient(135deg, rgba(var(--line-rgb), 0.5) 0 2px, transparent 2px 11px),
    var(--ink-2);
}

.anti__head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1.4rem;
}

.anti__head svg { flex: none; color: var(--coral); }

.anti__head b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
}

.anti__list { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }

.anti__item {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: rgba(var(--ink-rgb), 0.6);
}

.anti__item b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
  margin-bottom: 0.35rem;
}

.anti__item p { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

.anti__note {
  margin-top: 1.3rem;
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted);
}

.anti__note b { color: var(--paper); }

/* ============================================================
   I. EVAL SCOREBOARD — AI Engineering
   A real table of runs. Bars grow from zero on reveal, the winning
   row is marked, and the baseline stays visible so every number has
   something to be measured against.
   ============================================================ */
.evl {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow: hidden;
}

.evl__head,
.evl__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 76px;
  gap: 0.6rem 1rem;
  align-items: center;
  padding: 0.95rem clamp(1rem, 2.4vw, 1.5rem);
}

@media (min-width: 760px) {
  .evl__head,
  .evl__row { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) 76px 84px; }
}

.evl__head {
  border-bottom: 1px solid var(--line-soft);
  background: rgba(var(--ink-rgb), 0.5);
}

.evl__head span {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.evl__head span:nth-child(3),
.evl__head span:nth-child(4),
.evl__row > b,
.evl__row > i { text-align: right; }

.evl__row {
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.35s ease;
}

.evl__row:last-child { border-bottom: 0; }
.evl__row:hover { background: rgba(var(--accent-rgb), 0.035); }

.evl__row--base { color: var(--muted); }

.evl__row--win {
  background: rgba(var(--accent-rgb), 0.06);
  box-shadow: inset 2px 0 0 var(--accent);
}

.evl__name {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
}

.evl__row--base .evl__name { color: var(--muted); font-weight: 500; }

.evl__name em {
  flex: none;
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- the bar --- */
.evl__bar {
  position: relative;
  height: 8px;
  border-radius: 4px;
  background: var(--line-soft);
  overflow: hidden;
}

.evl__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--pc, var(--accent)), rgba(var(--accent-rgb), 0.55));
  transition: width 1.3s var(--ease);
  transition-delay: calc(var(--i, 0) * 0.11s);
}

.evl.is-in .evl__fill { width: calc(var(--v) * 1%); }

.evl__row > b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.evl__row--base > b { color: var(--muted); }

.evl__row > i {
  font-style: normal;
  font-size: 0.84rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.evl__foot {
  padding: 0.95rem clamp(1rem, 2.4vw, 1.5rem);
  border-top: 1px solid var(--line-soft);
  background: rgba(var(--ink-rgb), 0.5);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted);
}

.evl__foot b { color: var(--paper); }

/* ============================================================
   J. GUARDRAILS — what a request passes through
   Five gates on a rail, with a pulse running them so the order is
   legible without reading it.
   ============================================================ */
.grd { position: relative; }

.grd__rail {
  position: absolute;
  left: 0;
  right: 0;
  top: 30px;
  height: 2px;
  /* faded rather than cut: the gates are auto-fit, so there is no column
     count to anchor the end of the rail to. A hard stop past the last
     gate reads as unfinished; a fade reads as a track running on. */
  background: linear-gradient(90deg, var(--line-soft) 0 86%, transparent);
  overflow: hidden;
}

.grd__rail::after {
  content: "";
  position: absolute;
  top: 0;
  left: -22%;
  width: 22%;
  height: 100%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: grd-run 4.5s var(--ease) infinite;
}

@keyframes grd-run {
  0% { left: -22%; }
  70%, 100% { left: 104%; }
}

.grd__gates {
  position: relative;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}

/* Column, so the kicker line can be pushed to a common baseline across
   gates of differing text length instead of floating up under short copy. */
.grd__gate {
  padding-top: 74px;
  display: flex;
  flex-direction: column;
  /* anchors the absolutely-positioned numeral to this gate rather than to
     .grd — without it the dots stay put when the row scrolls */
  position: relative;
  transition: transform 0.45s var(--ease);
}

.grd__gate:hover { transform: translateY(-4px); }

/* Specificity note: the kicker rule below is `.grd__gate span` (0,1,1),
   which outranks a bare `.grd__dot` (0,1,0) and was overriding this
   element's display, letter-spacing and margin — which is what knocked
   the numeral off-centre. Matching on both classes takes it back. */
.grd__gate .grd__dot {
  position: absolute;
  top: 16px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  margin: 0;
  border-radius: 50%;
  border: 1px solid var(--pc, var(--accent));
  background: var(--ink);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  line-height: 1;
  /* trailing letter-space would shift the glyphs left of true centre */
  letter-spacing: 0;
  text-transform: none;
  color: var(--pc, var(--accent));
  transition: background 0.4s var(--ease), color 0.4s var(--ease),
              box-shadow 0.4s var(--ease), transform 0.5s var(--ease);
}

/* the dot fills with its own colour as the gate is approached */
.grd__gate:hover .grd__dot {
  background: var(--pc, var(--accent));
  color: var(--ink);
  transform: scale(1.12);
  box-shadow: 0 0 0 6px rgba(var(--ink-3-rgb), 0.6), 0 10px 26px -8px var(--pc, var(--accent));
}

.grd__gate b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
  margin-bottom: 0.4rem;
}

.grd__gate p { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

/* margin-top:auto is what lines the kickers up with each other regardless
   of how long the paragraph above them runs */
.grd__gate span {
  display: inline-block;
  margin-top: auto;
  padding-top: 0.9rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pc, var(--accent));
}

/* ============================================================
   K. SWAP — model-agnostic by construction
   ============================================================ */
.swap { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); }

.swap__item {
  position: relative;
  overflow: hidden;
  padding: clamp(1.3rem, 2.8vw, 1.7rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  transition: border-color 0.4s ease, transform 0.5s var(--ease);
}

.swap__item:hover { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.5); transform: translateY(-4px); }

.swap__port {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--pc, var(--accent));
}

.swap__port i {
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--pc, var(--accent));
  font-style: normal;
}

.swap__item h3 { font-size: var(--step-1); letter-spacing: -0.025em; }
.swap__item p { margin-top: 0.55rem; font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

/* The paragraphs are different lengths, so "Reach for it when" was starting at
   a different height in all four cards. The grid stretches them to the tallest
   already; making the card a column and pushing this block with margin-top:auto
   hands that slack to the gap above it and puts the four on one baseline. */
.swap__item { display: flex; flex-direction: column; }
.swap__item p { margin-bottom: 0; }

.swap__when {
  position: relative;
  display: block;
  margin-top: auto;          /* takes the slack the short cards have spare */
  padding-top: 1.1rem;
  border-top: 0;             /* the drawn rule below replaces the dashed line */
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted-2);
}

/* the separator carries the card's own source colour and draws itself in
   when the card arrives, rather than being a flat dashed line */
.swap__when::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(var(--pc-rgb, var(--accent-rgb)), 0.8),
    rgba(var(--pc-rgb, var(--accent-rgb)), 0.22) 58%,
    transparent
  );
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.85s var(--ease) 0.25s;
}
.swap__item.is-in .swap__when::before { transform: scaleX(1); }

/* a spark runs the length of the rule on hover */
.swap__when::after {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--pc, var(--accent));
  box-shadow: 0 0 12px 1px rgba(var(--pc-rgb, var(--accent-rgb)), 0.9);
  opacity: 0;
  pointer-events: none;
}
.swap__item:hover .swap__when::after { animation: swap-trace 1.15s var(--ease-io); }

@keyframes swap-trace {
  0%   { opacity: 0; left: 0; }
  14%  { opacity: 1; }
  86%  { opacity: 1; }
  100% { opacity: 0; left: 100%; }
}

.swap__when b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pc, var(--accent));
  margin-bottom: 0.35rem;
  transition: letter-spacing 0.5s var(--ease);
}
.swap__item:hover .swap__when b { letter-spacing: 0.2em; }

@media (prefers-reduced-motion: reduce) {
  .swap__item.is-in .swap__when::before { transition: none; }
  .swap__item:hover .swap__when::after { animation: none; }
  .swap__item:hover .swap__when b { letter-spacing: 0.16em; }
}

/* ============================================================
   L. BYTE BUDGET — Web Platforms
   One bar is the whole budget. Segments are what has been spent
   against it, and the overspend sits outside the line in coral so
   the argument is visible rather than asserted.
   ============================================================ */
.bdg { display: grid; gap: 1.6rem; }

@media (min-width: 940px) {
  .bdg { grid-template-columns: minmax(0, 1fr) 340px; gap: 2.6rem; align-items: start; }
}

.bdg__meter {
  padding: clamp(1.3rem, 3vw, 1.9rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
}

.bdg__top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.bdg__total {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  letter-spacing: -0.03em;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.bdg__total em { font-style: normal; font-size: 0.5em; color: var(--muted-3); margin-left: 0.3em; }

.bdg__cap {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

/* the budget figure itself is already on the marker; this says the part
   the marker cannot — how far past it the page went */
.bdg__cap--over {
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--coral);
  border-radius: 6px;
  color: var(--coral);
}

/* The marker and its label live on the track, NOT in the bar: the bar
   clips its segments to the rounded corners, and anything drawn above
   or beyond it gets clipped away with them. */
.bdg__track { position: relative; margin-top: 2.4rem; }

.bdg__bar {
  position: relative;
  display: flex;
  height: 52px;
  border-radius: 10px;
  background: var(--ink-3);
  overflow: hidden;
}

.bdg__seg {
  width: 0;
  background: var(--pc, var(--accent));
  border-right: 1px solid rgba(var(--ink-rgb), 0.55);
  transition: width 1.1s var(--ease), filter 0.3s ease;
  transition-delay: calc(var(--i, 0) * 0.09s);
}

.bdg.is-in .bdg__seg { width: calc(var(--w) * 1%); }
.bdg__seg.on { filter: brightness(1.35); }
.bdg__seg--over { background: repeating-linear-gradient(45deg, var(--coral) 0 6px, rgba(var(--ink-rgb), 0.35) 6px 12px); }

/* the line the budget actually sits at */
.bdg__line {
  position: absolute;
  top: -6px;
  bottom: -6px;
  left: calc(var(--at) * 1%);
  width: 2px;
  background: var(--paper);
  opacity: 0;
  transition: opacity 0.5s ease 1.3s;
}

.bdg.is-in .bdg__line { opacity: 0.85; }

.bdg__lineLabel {
  position: absolute;
  top: -1.9rem;
  left: calc(var(--at) * 1%);
  translate: -50% 0;
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
  opacity: 0;
  transition: opacity 0.5s ease 1.4s;
}

.bdg.is-in .bdg__lineLabel { opacity: 1; }

.bdg__scale {
  display: flex;
  justify-content: space-between;
  margin-top: 0.7rem;
  font-family: ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--muted-3);
}

.bdg__list { display: grid; gap: 0.3rem; align-content: start; }

.bdg__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.7rem;
  align-items: center;
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.bdg__row:hover, .bdg__row.on { background: var(--ink-2); border-color: var(--line-soft); }

.bdg__chip {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--pc, var(--accent));
}

.bdg__row--over .bdg__chip { background: var(--coral); }

.bdg__row b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
}

.bdg__row i {
  font-style: normal;
  font-family: ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}

.bdg__note {
  margin-top: 0.8rem;
  padding-top: 0.9rem;
  border-top: 1px dashed var(--line-soft);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted-2);
}

.bdg__note b { color: var(--coral); }

/* ============================================================
   M. ANATOMY — the design system, bottom up
   Each level is wider than the one below it, because each is built
   out of the last. The width IS the argument.
   ============================================================ */
.anat { display: grid; gap: 0.7rem; }

.anat__level {
  position: relative;
  width: calc(46% + var(--n) * 13.5%);
  max-width: 100%;
  padding: clamp(1.05rem, 2.4vw, 1.4rem) clamp(1.1rem, 2.6vw, 1.6rem);
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--pc, var(--accent));
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  background: linear-gradient(90deg, rgba(var(--pc-rgb, var(--accent-rgb)), 0.07), transparent 62%), var(--ink-2);
  transform-origin: left;
  scale: 0 1;
  transition: scale 0.75s var(--ease), border-color 0.35s ease;
  transition-delay: calc(var(--n) * 0.12s);
}

.anat.is-in .anat__level { scale: 1 1; }
.anat__level:hover { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.6); }

.anat__head { display: flex; align-items: baseline; gap: 0.7rem; flex-wrap: wrap; }

.anat__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  color: var(--pc, var(--accent));
}

.anat__head h3 { font-size: var(--step-1); letter-spacing: -0.025em; }

.anat__count {
  margin-left: auto;
  font-family: ui-monospace, monospace;
  font-size: 0.75rem;
  color: var(--muted-3);
}

.anat__level p { margin-top: 0.45rem; font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); max-width: 62ch; }
.anat__ex { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.8rem; }

/* ============================================================
   N. GATES — accessibility and performance checks that fail a build
   ============================================================ */
.gate {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow: hidden;
}

.gate__row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  gap: 0.5rem 0.9rem;
  align-items: center;
  padding: 0.95rem clamp(1rem, 2.4vw, 1.5rem);
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.35s ease;
}

.gate__row:last-child { border-bottom: 0; }
.gate__row:hover { background: rgba(var(--accent-rgb), 0.035); }

.gate__tick {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.4px solid var(--accent);
  display: grid;
  place-items: center;
  color: var(--accent-ink);
}

.gate__tick svg { width: 11px; height: 11px; }

.gate__row b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
}

/* Only the unclassed description span. Written as `.gate__row span` this
   also matched .gate__tick and .gate__stamp — and at specificity (0,1,1)
   it beat their own (0,1,0) rules, dragging the stamp into column 2 and
   overriding its font size. Same trap as .quad__row span. */
.gate__row > span:not([class]) {
  grid-column: 2;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--muted-2);
}

.gate__stamp {
  grid-row: 1 / span 2;
  grid-column: 3;
  align-self: center;
  padding: 0.32rem 0.6rem;
  border: 1px solid var(--coral);
  border-radius: 6px;
  font-family: ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--coral);
  white-space: nowrap;
}

.gate__stamp--warn { border-color: var(--muted-3); color: var(--muted-2); }

/* ============================================================
   O. RELEASE TRAIN — Mobile Apps
   A twelve-week calendar per platform. Segments are positioned by
   week, not by flex order, so the review window sits where it
   actually falls and its length is legible.
   ============================================================ */
.trn {
  padding: clamp(1.2rem, 3vw, 1.8rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow-x: auto;
}

.trn__inner { min-width: 620px; }

.trn__ruler {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 0.9rem;
  align-items: end;
  margin-bottom: 0.8rem;
}

.trn__weeks {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  border-bottom: 1px solid var(--line-soft);
}

.trn__weeks span {
  padding-bottom: 0.4rem;
  font-family: ui-monospace, monospace;
  font-size: 0.68rem;
  color: var(--muted-3);
  text-align: center;
  border-left: 1px solid var(--line-soft);
}

.trn__weeks span:first-child { border-left: 0; }

.trn__row {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 0.9rem;
  align-items: center;
  padding: 0.55rem 0;
}

.trn__label {
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
}

.trn__label em {
  display: block;
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-3);
  margin-top: 0.1rem;
}

.trn__track {
  position: relative;
  height: 26px;
  border-radius: 4px;
  /* One rule per week. A repeating-linear-gradient inside a tile that is
     itself one week wide repeats within each tile and draws dashes. */
  background-image: linear-gradient(90deg, var(--line-soft) 0 1px, transparent 1px);
  background-size: calc(100% / 12) 100%;
  background-repeat: repeat-x;
}

.trn__seg {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: calc(var(--from) / 12 * 100%);
  width: calc((var(--to) - var(--from)) / 12 * 100%);
  border-radius: 4px;
  transform-origin: left;
  scale: 0 1;
  transition: scale 0.6s var(--ease);
  transition-delay: calc(var(--i, 0) * 0.1s);
}

.trn.is-in .trn__seg { scale: 1 1; }

.trn__seg--build { background: var(--pc, var(--accent)); opacity: 0.55; }
.trn__seg--live { background: var(--pc, var(--accent)); }

/* the wait nobody controls, drawn as an absence rather than a block */
.trn__seg--review {
  border: 1px dashed var(--coral);
  background: repeating-linear-gradient(45deg, rgba(255, 122, 89, 0.14) 0 5px, transparent 5px 10px);
}

.trn__seg span {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: ui-monospace, monospace;
  font-size: 0.64rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
}

.trn__seg--review span { color: var(--coral); }
.trn__seg--build span { color: var(--paper); }

.trn__key {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
  margin-top: 1.2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.78rem;
  color: var(--muted-2);
}

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

.trn__key i {
  width: 16px;
  height: 10px;
  border-radius: 3px;
  font-style: normal;
}

.trn__key i.build { background: var(--accent); opacity: 0.55; }
.trn__key i.review { border: 1px dashed var(--coral); }
.trn__key i.live { background: var(--accent); }

/* ============================================================
   P. DEVICE MATRIX — what we support and what we drop
   ============================================================ */
.mtx {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow: hidden;
}

.mtx__head,
.mtx__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px;
  gap: 0.5rem 1rem;
  align-items: center;
  padding: 0.85rem clamp(1rem, 2.4vw, 1.5rem);
}

@media (min-width: 720px) {
  .mtx__head,
  .mtx__row { grid-template-columns: 150px minmax(0, 1fr) 62px 108px; }
}

.mtx__head {
  border-bottom: 1px solid var(--line-soft);
  background: rgba(var(--ink-rgb), 0.5);
}

.mtx__head span {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

.mtx__row {
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.35s ease;
}

.mtx__row:last-child { border-bottom: 0; }
.mtx__row:hover { background: rgba(var(--accent-rgb), 0.035); }
.mtx__row--drop { color: var(--muted-3); }

.mtx__os {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
}

.mtx__row--drop .mtx__os { color: var(--muted-2); }

.mtx__bar {
  position: relative;
  height: 7px;
  border-radius: 4px;
  background: var(--line-soft);
  overflow: hidden;
}

.mtx__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 4px;
  background: var(--pc, var(--accent));
  transition: width 1.1s var(--ease);
  transition-delay: calc(var(--i, 0) * 0.09s);
}

.mtx.is-in .mtx__fill { width: calc(var(--v) * 1%); }

.mtx__row > b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--paper);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.mtx__row--drop > b { color: var(--muted-3); }

.mtx__tag {
  justify-self: start;
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--accent);
  border-radius: 6px;
  font-family: ui-monospace, monospace;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  white-space: nowrap;
}

.mtx__tag--part { border-color: var(--muted-3); color: var(--muted-2); }
.mtx__tag--drop { border-color: var(--coral); color: var(--coral); }

/* ============================================================
   Q. DIAL — crash-free sessions against the target
   ============================================================ */
.dial { display: grid; gap: 1.8rem; align-items: center; }

@media (min-width: 860px) {
  .dial { grid-template-columns: 300px minmax(0, 1fr); gap: 3rem; }
}

.dial__gauge { position: relative; width: 100%; max-width: 300px; }
.dial__gauge svg { width: 100%; height: auto; overflow: visible; }

.dial__track { fill: none; stroke: var(--line-soft); stroke-width: 14; stroke-linecap: round; }

.dial__arc {
  fill: none;
  stroke: var(--accent-ink);
  stroke-width: 14;
  stroke-linecap: round;
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
  transition: stroke-dashoffset 1.7s var(--ease);
}

.dial.is-in .dial__arc { stroke-dashoffset: calc(var(--len, 400) - (var(--len, 400) * var(--pct) / 100)); }

.dial__target { stroke: var(--paper); stroke-width: 2; opacity: 0.75; }

.dial__mid {
  position: absolute;
  left: 50%;
  bottom: 12%;
  translate: -50% 0;
  text-align: center;
}

.dial__n {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 5vw, 2.8rem);
  letter-spacing: -0.04em;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.dial__k {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

.dial__notes { display: grid; gap: 0.9rem; }

.dial__note {
  padding: 1rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--pc, var(--accent));
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--ink-2);
}

.dial__note b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
  margin-bottom: 0.35rem;
}

.dial__note p { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

/* ============================================================
   R. PIPELINE — Cloud & DevOps
   Vertical on purpose: the guardrail gauntlet on the AI page is
   horizontal, and these two should not read as the same picture.
   Each stage carries its own duration bar and the running total.
   ============================================================ */
.pipe { position: relative; display: grid; gap: 0.5rem; padding-left: 2.6rem; }

.pipe::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 14px;
  bottom: 14px;
  width: 2px;
  background: var(--line-soft);
}

.pipe__fill {
  position: absolute;
  left: 13px;
  top: 14px;
  width: 2px;
  height: 0;
  background: linear-gradient(var(--p1), var(--p4), var(--p6));
  transition: height 1.8s var(--ease);
}

.pipe.is-in .pipe__fill { height: calc(100% - 28px); }

.pipe__stage {
  position: relative;
  display: grid;
  gap: 0.3rem 1.2rem;
  padding: 0.95rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--ink-2);
  transition: border-color 0.35s ease, transform 0.45s var(--ease);
}

@media (min-width: 800px) {
  .pipe__stage { grid-template-columns: 190px minmax(0, 1fr) 92px; align-items: center; }
}

.pipe__stage:hover { border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.5); transform: translateX(3px); }

.pipe__dot {
  position: absolute;
  left: -2.6rem;
  top: 50%;
  translate: 0 -50%;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--ink);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.68rem;
  color: var(--muted-3);
  transition: border-color 0.4s ease, color 0.4s ease;
}

.pipe__stage.lit .pipe__dot { border-color: var(--pc, var(--accent)); color: var(--pc, var(--accent)); }

.pipe__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  color: var(--paper);
}

.pipe__what { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

.pipe__time { display: grid; gap: 0.35rem; }

@media (min-width: 800px) { .pipe__time { justify-items: end; } }

.pipe__dur {
  font-family: ui-monospace, monospace;
  font-size: 0.78rem;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.pipe__bar {
  width: 100%;
  max-width: 88px;
  height: 6px;
  border-radius: 3px;
  background: var(--line-soft);
  overflow: hidden;
}

.pipe__bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: var(--pc, var(--accent));
  transition: width 1s var(--ease);
  transition-delay: calc(var(--i, 0) * 0.12s);
}

.pipe.is-in .pipe__bar i { width: calc(var(--v) * 1%); }

.pipe__total {
  margin-top: 0.9rem;
  padding: 1rem 1.2rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: var(--step--1);
  color: var(--muted-2);
}

.pipe__total b {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--accent-ink);
  margin-right: 0.5rem;
}

/* ============================================================
   S. COST WATERFALL — where the bill actually goes
   Bars hang from a running total, so each saving is shown as the
   step down it was rather than as a slice of a pie.
   ============================================================ */
.cost {
  padding: clamp(1.2rem, 3vw, 1.8rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow-x: auto;
}

.cost__inner { min-width: 560px; }

.cost__chart {
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.7rem;
  height: 240px;
  align-items: end;
  padding-bottom: 2.6rem;
}

.cost__col { position: relative; height: 100%; }

.cost__block {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--base) * 1%);
  height: calc(var(--h) * 1%);
  border-radius: 5px;
  background: var(--pc, var(--accent));
  transform-origin: bottom;
  scale: 1 0;
  transition: scale 0.7s var(--ease);
  transition-delay: calc(var(--i, 0) * 0.13s);
}

.cost.is-in .cost__block { scale: 1 1; }

.cost__block--start { background: var(--muted-3); }
.cost__block--end { background: var(--accent); }
.cost__block--cut { background: repeating-linear-gradient(45deg, var(--pc) 0 6px, rgba(var(--ink-rgb), 0.4) 6px 12px); }

.cost__val {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--base) * 1% + var(--h) * 1% + 6px);
  text-align: center;
  font-family: ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--paper);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.4s ease;
  transition-delay: calc(0.5s + var(--i, 0) * 0.13s);
}

.cost.is-in .cost__val { opacity: 1; }
.cost__val--cut { color: var(--accent-ink); }

.cost__label {
  position: absolute;
  left: -0.3rem;
  right: -0.3rem;
  bottom: -2.3rem;
  text-align: center;
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--muted-3);
}

.cost__key {
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted-2);
}

.cost__key b { color: var(--paper); }

/* ============================================================
   T. RUNBOOK — the first thirty minutes of an incident
   ============================================================ */
.rb { display: grid; gap: 0.6rem; }

.rb__row {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
  padding: 1rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--pc, var(--accent));
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--ink-2);
  transition: border-color 0.35s ease, transform 0.45s var(--ease);
}

.rb__row:hover { transform: translateX(4px); }

.rb__t {
  font-family: ui-monospace, monospace;
  font-size: 0.8rem;
  color: var(--pc, var(--accent));
  font-variant-numeric: tabular-nums;
  padding-top: 0.1rem;
}

.rb__row b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
  margin-bottom: 0.3rem;
}

.rb__row p { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

.rb__who {
  display: inline-block;
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

/* ============================================================
   U. COMPARISON — ERP/CRM platforms, side by side
   The marked cell is where we would start, and it is never the
   same platform in every row, because it never is.
   ============================================================ */
.cmpr {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  overflow-x: auto;
}

.cmpr__inner { min-width: 660px; }

.cmpr__head,
.cmpr__row {
  display: grid;
  grid-template-columns: 156px repeat(3, minmax(0, 1fr));
  gap: 1rem;
  padding: 1rem clamp(1rem, 2.4vw, 1.5rem);
  align-items: start;
}

.cmpr__head {
  border-bottom: 1px solid var(--line-soft);
  background: rgba(var(--ink-rgb), 0.5);
  align-items: center;
}

.cmpr__head b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  color: var(--paper);
}

.cmpr__head span:first-child,
.cmpr__k {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-3);
}

.cmpr__row { border-bottom: 1px solid var(--line-soft); }
.cmpr__row:last-child { border-bottom: 0; }

.cmpr__cell {
  position: relative;
  padding: 0.7rem 0.8rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--muted-2);
  transition: border-color 0.35s ease, background 0.35s ease;
}

.cmpr__cell:hover { border-color: var(--line-soft); background: rgba(var(--accent-rgb), 0.03); }

/* where we would start for that row — not a verdict on the product */
.cmpr__cell--pick {
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.06);
  color: var(--text-2);
}

.cmpr__cell--pick::after {
  content: "our pick here";
  display: block;
  margin-top: 0.5rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.cmpr__note {
  padding: 1rem clamp(1rem, 2.4vw, 1.5rem);
  border-top: 1px solid var(--line-soft);
  background: rgba(var(--ink-rgb), 0.5);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted-2);
}

.cmpr__note b { color: var(--paper); }

/* ============================================================
   V. HUB — what has to talk to what
   ============================================================ */
.hub { display: grid; gap: 1.8rem; align-items: center; }

@media (min-width: 900px) {
  .hub { grid-template-columns: minmax(0, 1fr) 340px; gap: 3rem; }
}

.hub__map { width: 100%; }
.hub__map svg { width: 100%; height: auto; overflow: visible; }

.hub__spoke {
  stroke: var(--line);
  stroke-width: 1.4;
  stroke-dasharray: var(--len, 200);
  stroke-dashoffset: var(--len, 200);
  transition: stroke-dashoffset 1s var(--ease);
  transition-delay: calc(var(--d, 0) * 0.11s);
}

.hub.is-in .hub__spoke { stroke-dashoffset: 0; }

.hub__node {
  fill: var(--ink-2);
  stroke: var(--line);
  stroke-width: 1.4;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 0.45s ease, scale 0.5s var(--ease);
  transition-delay: calc(0.3s + var(--d, 0) * 0.11s);
  scale: 0.5;
}

.hub.is-in .hub__node { opacity: 1; scale: 1; }

.hub__core-shape {
  fill: rgba(var(--accent-rgb), 0.1);
  stroke: var(--accent-ink);
  stroke-width: 1.8;
}

.hub__label {
  fill: var(--muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 11px;
  text-anchor: middle;
  opacity: 0;
  transition: opacity 0.45s ease;
  transition-delay: calc(0.45s + var(--d, 0) * 0.11s);
}

.hub.is-in .hub__label { opacity: 1; }
.hub__label--core { fill: var(--accent-ink); font-size: 12px; }

.hub__notes { display: grid; gap: 0.9rem; align-content: center; }

.hub__note {
  padding: 1rem 1.2rem;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--pc, var(--accent));
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--ink-2);
}

.hub__note b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--paper);
  margin-bottom: 0.3rem;
}

.hub__note p { font-size: var(--step--1); line-height: 1.6; color: var(--muted-2); }

/* ============================================================
   W. DECISION LADDER — configure or customise
   ============================================================ */
.tree { display: grid; gap: 0.7rem; }

.tree__q {
  display: grid;
  gap: 0.9rem;
  padding: clamp(1.1rem, 2.6vw, 1.5rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
}

@media (min-width: 840px) {
  .tree__q { grid-template-columns: minmax(0, 1fr) 300px 300px; align-items: center; }
}

.tree__ask { display: flex; gap: 0.8rem; align-items: baseline; min-width: 0; }

.tree__n {
  flex: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  color: var(--muted-3);
}

.tree__ask p {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  color: var(--paper);
}

.tree__branch {
  position: relative;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: rgba(var(--ink-rgb), 0.5);
}

.tree__branch b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 0.35rem;
  color: var(--muted-3);
}

.tree__branch p { font-size: var(--step--1); line-height: 1.55; color: var(--muted-2); }

.tree__branch--yes { border-color: rgba(var(--accent-rgb), 0.4); }
.tree__branch--yes b { color: var(--accent-ink); }
.tree__branch--no { border-color: rgba(255, 122, 89, 0.35); }
.tree__branch--no b { color: var(--coral); }

.tree__end {
  padding: clamp(1.1rem, 2.6vw, 1.5rem);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--muted);
}

.tree__end b { color: var(--paper); }

/* ============================================================
   X. OPEN ROLES — Careers
   A list, not a card grid: roles are scanned for a match, and a grid
   makes people read every tile to find the one line they care about.
   ============================================================ */
.role { display: grid; gap: 0.5rem; }

.role__item {
  position: relative;
  display: grid;
  gap: 0.5rem 1.4rem;
  padding: clamp(1.1rem, 2.6vw, 1.5rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--ink-2);
  color: inherit;
  overflow: hidden;
  transition: border-color 0.35s ease, transform 0.45s var(--ease), background 0.35s ease;
}

@media (min-width: 860px) {
  .role__item { grid-template-columns: minmax(0, 1fr) 160px 130px 40px; align-items: center; }
}

.role__item:hover {
  border-color: rgba(var(--pc-rgb, var(--accent-rgb)), 0.5);
  background: var(--ink-3);
  transform: translateX(4px);
}

/* the accent edge that arrives with the pointer */
.role__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--pc, var(--accent));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.4s var(--ease);
}

.role__item:hover::before { transform: scaleY(1); }

.role__title {
  min-width: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-1);
  letter-spacing: -0.025em;
  color: var(--paper);
}

.role__team {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--muted-2);
  max-width: 58ch;
}

.role__meta {
  font-family: ui-monospace, monospace;
  font-size: 0.76rem;
  color: var(--muted-2);
}

.role__type {
  justify-self: start;
  padding: 0.3rem 0.62rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.role__go {
  justify-self: start;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--muted-2);
  transition: border-color 0.35s ease, color 0.35s ease, transform 0.4s var(--ease);
}

@media (min-width: 860px) { .role__go { justify-self: end; } }

.role__item:hover .role__go {
  border-color: var(--accent-ink);
  color: var(--accent-ink);
  transform: translateX(3px) rotate(45deg);
}

/* nothing open — say so plainly rather than showing an empty list */
.role__none {
  padding: clamp(1.2rem, 3vw, 1.7rem);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  font-size: var(--step--1);
  line-height: 1.65;
  color: var(--muted);
}

.role__none b { color: var(--paper); }

/* ============================================================
   H. Small shared bits
   ============================================================ */

/* a wide pull-quote line used between sections on several services */
/* ---------- Pull-quote ----------
   A band of its own rather than a paragraph between two hairlines: it carries
   its own ground, its own light, and keeps the sentence on one line at desktop
   widths so it lands as a statement instead of a wrapped block. */

.svc-line {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: block;
  max-width: none;
  margin: 0;
  padding: clamp(2.4rem, 6vw, 4.2rem) clamp(1.4rem, 4vw, 3.2rem);
  border: 1px solid rgba(var(--accent-rgb), 0.16);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(var(--accent-rgb), 0.09), transparent 55%),
    radial-gradient(90% 130% at 92% 100%, rgba(var(--p5-rgb), 0.1), transparent 58%),
    linear-gradient(160deg, var(--ink-2), var(--ink-3));
  text-align: left;
}

/* the ground never sits still: two blooms drift across it on different clocks */
.svc-line__glow {
  position: absolute;
  inset: -30%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(28% 34% at 30% 40%, rgba(var(--accent-rgb), 0.16), transparent 65%),
    radial-gradient(24% 30% at 70% 60%, rgba(var(--p5-rgb), 0.16), transparent 65%);
  animation: line-aurora 18s ease-in-out infinite;
}
@keyframes line-aurora {
  0%, 100% { transform: translate(-4%, -2%) scale(1) rotate(0deg); }
  33%      { transform: translate(6%, 4%) scale(1.14) rotate(4deg); }
  66%      { transform: translate(-2%, 6%) scale(1.06) rotate(-3deg); }
}

/* a wide highlight crosses the whole band, continuously */
.svc-line::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -40%;
  width: 32%;
  z-index: -1;
  pointer-events: none;
  transform: skewX(-14deg);
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.09), transparent);
  animation: line-sweep 7.5s var(--ease-io) infinite;
}
@keyframes line-sweep {
  0%       { left: -40%; }
  55%, 100% { left: 130%; }
}

.svc-line__t {
  position: relative;
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.45rem, 2.7vw, 2.55rem);
  line-height: 1.2;
  letter-spacing: -0.035em;
  color: var(--paper);
  text-wrap: balance;
}
/* one line once there is room for one */
@media (min-width: 1080px) { .svc-line__t { white-space: nowrap; } }

.svc-line__sub {
  position: relative;
  display: block;
  margin-top: 0.9rem;
  max-width: 62ch;
  font-family: var(--font-body, inherit);
  font-size: clamp(0.95rem, 1.05vw, 1.12rem);
  line-height: 1.6;
  letter-spacing: 0;
  color: var(--muted);
}

/* the two words the sentence turns on — a gradient that never stops moving */
.svc-line em {
  position: relative;
  font-style: normal;
  background: linear-gradient(
    100deg,
    var(--accent-ink) 0%,
    var(--accent) 25%,
    #ffffff 42%,
    var(--accent) 58%,
    var(--accent-ink) 85%
  );
  background-size: 260% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: line-flow 6s linear infinite;
  filter: drop-shadow(0 0 18px rgba(var(--accent-rgb), 0.35));
}
@keyframes line-flow {
  0%   { background-position: 260% 50%; }
  100% { background-position: -60% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .svc-line__glow,
  .svc-line::after,
  .svc-line em { animation: none; }
  .svc-line em { background-position: 40% 50%; }
}

[data-motion="off"] .sbn__cell { animation: none; opacity: 1; }
[data-motion="off"] .sbn__wfbar { animation: none; scale: 1 1; }
[data-motion="off"] .sbn__mark,
[data-motion="off"] .sbn__marklabel { animation: none; opacity: 1; }
[data-motion="off"] .sbn__runbar,
[data-motion="off"] .grd__rail::after { display: none; }
[data-motion="off"] .sbn__ship { animation: none; scale: 1 1; }
[data-motion="off"] .sbn__rail,
[data-motion="off"] .sbn__spoke { animation: none; stroke-dashoffset: 0; }
[data-motion="off"] .sbn__sys,
[data-motion="off"] .sbn__core { animation: none; opacity: 1; }
[data-motion="off"] .sbn__pulseIn { display: none; }
[data-motion="off"] .hub__spoke { transition: none; stroke-dashoffset: 0; }
[data-motion="off"] .hub__node,
[data-motion="off"] .hub__label { transition: none; opacity: 1; scale: 1; }
[data-motion="off"] .sbn__stage { animation: none; opacity: 1; }
[data-motion="off"] .sbn__build { display: none; }
[data-motion="off"] .pipe__fill { transition: none; }
[data-motion="off"] .evl__fill,
[data-motion="off"] .bdg__seg,
[data-motion="off"] .anat__level,
[data-motion="off"] .trn__seg,
[data-motion="off"] .mtx__fill,
[data-motion="off"] .dial__arc,
[data-motion="off"] .pipe__bar i,
[data-motion="off"] .cost__block,
[data-motion="off"] .cost__val { transition: none; }

@media (prefers-reduced-motion: reduce) {
  .sbn__cell { animation: none; opacity: 1; }
  .sbn__wfbar { animation: none; scale: 1 1; }
  .sbn__mark, .sbn__marklabel { animation: none; opacity: 1; }
  .sbn__runbar, .grd__rail::after { display: none; }
  .sbn__ship { animation: none; scale: 1 1; }
  .sbn__rail, .sbn__spoke { animation: none; stroke-dashoffset: 0; }
  .sbn__sys, .sbn__core { animation: none; opacity: 1; }
  .sbn__pulseIn { display: none; }
  .hub__spoke { transition: none; stroke-dashoffset: 0; }
  .hub__node, .hub__label { transition: none; opacity: 1; scale: 1; }
  .sbn__stage { animation: none; opacity: 1; }
  .sbn__build { display: none; }
  .pipe__fill { transition: none; }
  .evl__fill, .bdg__seg, .anat__level,
  .trn__seg, .mtx__fill, .dial__arc,
  .pipe__bar i, .cost__block, .cost__val { transition: none; }
  .sbn__grid, .sbn__glow, .sbn__scan { animation: none; opacity: 1; }
  .sbn__link { animation: none; stroke-dashoffset: 0; }
  .sbn__node, .sbn__pick { animation: none; opacity: 1; }
  .sbn__halo, .sbn__pulse { display: none; }
  .sbn-rule { animation: none; transform: none; }
  .svc-badges .tag { animation: none; opacity: 1; }
  .svc-badges .tag::after { display: none; }
  .sbn__grid, .sbn__glow, .sbn__net { transition: none; }
  .trig__rule, .arte__rules i, .qask__row::before { transition: none; }
}


/* ---------- Eval scoreboard: rows are choices, so they are buttons ----------

   Each row is now a real <button> rather than a div with a click handler, so
   Tab, Enter and Space work and a screen reader announces it as pressable.
   That brings the UA button styles with it, hence the reset — width, font and
   text-align have to be handed back before the grid rules can take effect. */

.evl__row {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  -webkit-appearance: none;
          appearance: none;
  transition: background 0.35s ease, box-shadow 0.35s ease;
}
.evl__row:last-child { border-bottom: 0; }
.evl__row:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -3px; }

/* the recommended row keeps its standing marker */
.evl__row--win { box-shadow: inset 2px 0 0 var(--accent); }

/* the chosen row holds its state after the shimmer has passed */
.evl__row[aria-pressed="true"] {
  background: rgba(var(--accent-rgb), 0.09);
  box-shadow: inset 3px 0 0 var(--accent);
}
.evl__row[aria-pressed="true"] .evl__name { color: var(--paper); }
.evl__row[aria-pressed="true"] > b { color: var(--accent-ink); }

/* ---- the shimmer ----
   A band crosses the row on click. It lives on ::after with z-index 1 so it
   passes OVER the bar and the numbers rather than under them, and the class
   is stripped on animationend so a second click fires it again. */
.evl__row::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 45%;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-140%) skewX(-18deg);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(var(--accent-rgb), 0.05) 30%,
    rgba(var(--accent-rgb), 0.28) 50%,
    rgba(var(--accent-rgb), 0.05) 70%,
    transparent
  );
}
.evl__row.is-shine::after { animation: evl-shine 0.85s var(--ease-io); }

@keyframes evl-shine {
  0%   { opacity: 0; transform: translateX(-140%) skewX(-18deg); }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(320%) skewX(-18deg); }
}

/* the row's own bar re-runs with it, so the click reads as "show me this one" */
.evl__row.is-shine .evl__fill {
  animation: evl-refill 0.85s var(--ease) both;
}
@keyframes evl-refill {
  0%   { width: 0; }
  100% { width: calc(var(--v) * 1%); }
}

@media (prefers-reduced-motion: reduce) {
  .evl__row.is-shine::after,
  .evl__row.is-shine .evl__fill { animation: none; }
}


/* ============================================================
   26. Spark field (.sparks) — reusable

   The pull-quote grew one of these but it was welded to that block. This is
   the same idea as a component: drop <span class="sparks"> with any number
   of <i> children into a positioned container, place each with --x / --y,
   size it with --s and offset it in time with --d. No two fire together, so
   the field never reads as a repeating pattern.
   ============================================================ */

.sparks {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  display: block;
  overflow: hidden;
  border-radius: inherit;
}

.sparks i {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: calc(4px * var(--s, 1));
  height: calc(4px * var(--s, 1));
  border-radius: 50%;
  background: var(--deco);
  opacity: 0;
  animation: spark-fire 5s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

/* the cross-flare that makes a dot read as a spark rather than a bullet */
.sparks i::before,
.sparks i::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
}
.sparks i::before {
  width: calc(24px * var(--s, 1)); height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--deco-rgb), 0.95), transparent);
}
.sparks i::after {
  width: 1px; height: calc(24px * var(--s, 1));
  background: linear-gradient(180deg, transparent, rgba(var(--deco-rgb), 0.95), transparent);
}

@keyframes spark-fire {
  0%, 76%, 100% { opacity: 0; transform: scale(0.35); }
  84%           { opacity: 1; transform: scale(1); }
  91%           { opacity: 0.3; transform: scale(0.7); }
}
