@charset "utf-8";
/* ==========================================================================
   page-custom-software.css
   Page-scoped stylesheet for custom-software.html.
   Every rule reads band theme variables — no fixed colours, no hex literals
   that already exist as tokens. Works on dark, void, light and paper bands.
   Document order:
     0. Shared atoms      1. Hero        2. Layer figure
     4. Fit / not-fit     5. Wrong-fit   6. Keep·Connect·Build
     7. Capability chips  8. Build cards 9. Phases
    10. Cost             11. Ledger     12. CTA
    13. Responsive       14. Reduced motion
   ========================================================================== */


/* ==========================================================================
   0. SHARED ATOMS
   Small pieces reused across several sections.
   ========================================================================== */

/* .cs-k — the mono micro-label that heads a card, list or route. */
.cs-k {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.4;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

.cs-k--blue { color: var(--link); }
.cs-k--human { color: var(--amber); }

/* Amber is a fixed brand token; step it toward ink on light bands for contrast. */
.band--light .cs-k--human,
.band--paper-white .cs-k--human {
  color: color-mix(in srgb, var(--amber) 58%, var(--ink));
}

/* .cs-list — dotted qualifier list. --human swaps the dot to attention amber. */
.cs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}

.cs-list > li {
  position: relative;
  padding-left: var(--s-6);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--body);
}

.cs-list > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .58em;
  width: 6px;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--accent);
}

.cs-list--human > li::before {
  background: var(--amber);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber) 16%, transparent);
}

/* .cs-ticks — confirmed-scope checklist inside a build card. */
.cs-ticks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
}

.cs-ticks > li {
  position: relative;
  padding-left: var(--s-6);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--body);
}

.cs-ticks > li::before {
  content: "";
  position: absolute;
  left: 1px;
  top: .42em;
  width: 10px;
  height: 5px;
  border-left: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  transform: rotate(-45deg);
}

/* .cs-human — the "a human stays here" footer note. Amber = human attention. */
.cs-human {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-soft);
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--body);
}

.cs-human::before {
  content: "";
  flex: none;
  margin-top: .45em;
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--amber);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--amber) 15%, transparent);
}


/* ==========================================================================
   1. HERO
   ========================================================================== */

.cs-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.cs-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  align-items: stretch;
  gap: clamp(var(--s-8), 3.5vw, var(--s-14, 3.5rem));
}

.cs-hero__copy {
  display: grid;
  align-content: center;
  justify-items: start;
  gap: var(--s-6);
  max-width: 44rem;
}

/* Capped deliberately: three clean lines beat a bigger ragged five. */
.cs-hero__title {
  margin: 0;
  max-width: none;
  font-size: clamp(2.5rem, 4.35vw, 3.9rem);
  letter-spacing: -.03em;
  line-height: .95;
  color: var(--ink);
}

/* Three deliberate lines — never a ragged four-line wrap. */
.cs-hero__title > span { display: block; }

.cs-hero__accent {
  color: var(--blue-deep, #0B4F8A);
  position: relative;
}

.cs-hero__lead {
  margin: 0;
  max-width: 46ch;
  color: var(--body);
}

.cs-hero__cta {
  margin-top: var(--s-2);
  flex-wrap: wrap;
}

.cs-hero__fine {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-mono);
  letter-spacing: .02em;
}

.cs-hero__fine::before {
  content: "";
  width: var(--s-8);
  height: 1px;
  flex: none;
  background: var(--line-strong);
}

/* Figure column ---------------------------------------------------------- */

.cs-hero__figure {
  position: relative;
  display: flex;
  align-items: stretch;
  justify-content: center;
  min-width: 0;
  padding: 0;
}

/* The hero plate — a tinted card the diagram sits on, lifted off the wash.
   It stretches to the copy column so the right half is never emptier than the
   left, and the diagram centres inside whatever height it is given. */
.cs-figplate {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  padding: clamp(var(--s-5), 1.8vw, var(--s-8));
  border-radius: var(--r-xl);
  background:
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--accent) 7%, var(--paper-card, #fff)),
      var(--paper-card, #fff) 62%
    );
  border: 1px solid color-mix(in srgb, var(--accent) 24%, var(--line));
  box-shadow: var(--shadow-lift);
  transition: box-shadow var(--d-3) var(--e-out), transform var(--d-3) var(--e-out);
}

.cs-hero__figure:hover .cs-figplate {
  transform: translateY(-3px);
  box-shadow: 0 28px 60px -28px rgba(11, 79, 138, .35);
}

.cs-figplate__cap {
  margin: var(--s-5) 0 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.cs-figplate__cap b {
  font-weight: 500;
  color: var(--ink);
}

.cs-figplate__cap i {
  font-style: normal;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: #8A5D05;
}

.cs-figplate__cap i::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--amber);
}


/* ==========================================================================
   2. LAYER FIGURE  (svg.cs-layerfig — viewBox 0 0 600 320)
   core.css already fluid-scales the SVG and inherits currentColor on <text>.
   Here: wrapper cap, plate fills, node chips, packet motion.
   ========================================================================== */

/* Diagram palette — resolves to the shared --rf-* theme vars when present,
   otherwise to the light-band values from the art direction. */
.cs-layerfig,
.cs-mini {
  --d-ch:     var(--rf-ch-1, #2F9AA8);
  --d-ch-in:  var(--rf-ch-0, #6FC4CE);
  --d-node:   var(--rf-node-1, #1077D7);
  --d-node-d: var(--rf-node-2, #0B4F8A);
  --d-port:   var(--rf-port, #0B4F8A);
  --d-ring:   var(--rf-ring, #1077D7);
  --d-out:    var(--rf-out, #0B4F8A);
  --d-label:  var(--rf-label, #5B6B7A);
  --d-amber:  var(--rf-amber, #E7A63A);
  --d-amber-t: #8A5D05;
  --d-plate:  var(--paper-card, #fff);
  --d-line:   var(--line, rgba(11,79,138,.18));
}

/* On dark bands the same diagram re-points to the dark palette. */
.band--dark .cs-layerfig, .band--void .cs-layerfig,
.band--dark .cs-mini,     .band--void .cs-mini {
  --d-ch: var(--rf-ch-1, #7CE7F0);
  --d-ch-in: var(--rf-ch-0, #45B7C4);
  --d-node: var(--rf-node-1, #4FA9F5);
  --d-port: var(--rf-port, #7CE7F0);
  --d-ring: var(--rf-ring, #4FA9F5);
  --d-out: var(--rf-out, #4FA9F5);
  --d-label: var(--rf-label, #7d8b99);
  --d-amber-t: #E7A63A;
  --d-plate: var(--bg-card-2);
}

/* The plate every diagram sits on. */
.cs-figplate {
  margin: 0;
  width: 100%;
}

/* core.css sizes inline SVG with `main svg[viewbox]:not([width])` — specificity
   (0,2,2) — so the deliberate cap needs three classes to land. */
.cs-hero .cs-hero__figure svg.cs-layerfig {
  position: relative;
  width: 100%;
  max-width: 640px;
  overflow: visible;
  color: var(--body);
}

.cs-layerfig text { letter-spacing: .01em; }

/* The mobile cut is a second, purpose-drawn figure — not the desktop drawing
   scaled down. Only one of the pair is ever in the layout; the swap lives in
   §13. Its "kept systems" labels sit at the centre x of their plates. */
.cs-hero .cs-hero__figure svg.cs-layerfig--mob { display: none; }

.cs-layerfig--mob .cs-layerfig__keep text { text-anchor: middle; }

/* Shared diagram label — one size, one family, everywhere. */
.dg-label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  fill: var(--d-label);
}

.dg-label--accent { fill: var(--d-out); }
.dg-label--human  { fill: var(--d-amber-t); font-weight: 500; }

/* The hero figure is the page's load-bearing diagram and is read from a metre
   away, not from a specimen sheet: it takes the kit's next size up. */
.cs-layerfig .dg-label {
  font-size: 13.5px;
  letter-spacing: 1.5px;
  font-weight: 500;
}

/* Existing software that stays — quiet, recessive plate. */
.cs-layerfig__keep { color: var(--muted); }

.cs-layerfig__keep rect {
  fill: var(--d-plate);
  stroke: var(--d-line);
  stroke-width: 1.75;
}

.cs-layerfig__keep text {
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: 1.3px;
  font-weight: 500;
  fill: var(--ink);
}

.cs-layerfig__ports circle { fill: var(--d-port); }

/* Channels — 2.5 on light, round caps (geometry contract). */
.cs-layerfig__ch path {
  fill: none;
  stroke: var(--d-ch);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.cs-layerfig__out {
  fill: none;
  stroke: var(--d-out);
  stroke-width: 3;
  stroke-linecap: round;
}

/* The built layer — the elevated white plate. */
.cs-layerfig__plate {
  fill: color-mix(in srgb, var(--d-node) 4%, var(--d-plate));
  stroke: color-mix(in srgb, var(--d-node) 42%, var(--d-line));
  stroke-width: 2;
}

/* Chips inside the layer = individual capabilities. */
.cs-layerfig__chip text {
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: 1.3px;
  font-weight: 500;
  fill: var(--ink);
}

.cs-layerfig__chip rect {
  fill: color-mix(in srgb, var(--d-node) 9%, transparent);
  stroke: color-mix(in srgb, var(--d-node) 30%, transparent);
  stroke-width: 1.75;
}

.cs-layerfig__chip--on rect {
  fill: color-mix(in srgb, var(--d-node) 14%, transparent);
  stroke: color-mix(in srgb, var(--d-node) 55%, transparent);
}

.cs-layerfig__chip--on text { fill: var(--d-node-d); font-weight: 500; }

.cs-layerfig__chip--human rect {
  fill: color-mix(in srgb, var(--d-amber) 14%, transparent);
  stroke: var(--d-amber);
  stroke-width: 2;
  stroke-dasharray: 4 4;
}

.cs-layerfig__chip--human text { fill: var(--d-amber-t); font-weight: 500; }

/* Human gate — amber, dashed: a person is required here. */
.cs-layerfig__human-link {
  fill: none;
  stroke: var(--d-amber);
  stroke-width: 2;
  stroke-dasharray: 4 4;
  stroke-linecap: round;
}

.cs-layerfig__human rect {
  fill: color-mix(in srgb, var(--d-amber) 10%, var(--d-plate));
  stroke: var(--d-amber);
  stroke-width: 2;
  stroke-dasharray: 4 4;
}

.cs-layerfig__human circle {
  fill: var(--d-amber);
  animation: cs-human-pulse 2.6s var(--e-inout) infinite;
  transform-box: fill-box;
  transform-origin: center;
}

.cs-layerfig__human text {
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: 1.5px;
  fill: var(--d-amber-t);
  font-weight: 500;
}

/* Node + rings — the one governed record. */
.cs-layerfig__node {
  fill: var(--d-node);
  stroke: var(--d-node-d);
  stroke-width: 2;
}

.cs-layerfig__ring {
  fill: none;
  stroke: var(--d-ring);
  stroke-width: 2;
  opacity: .4;
  transform-box: fill-box;
  transform-origin: center;
  animation: cs-ring 3.6s var(--e-inout) infinite;
}

.cs-layerfig__ring--out {
  opacity: .16;
  stroke-dasharray: 3 6;
  animation-delay: -1.2s;
}

/* The packet circles are authored at the SVG origin; CSS flies them down each
   connector into the record node at (300,138) and on into the layer. */
.cs-pk {
  fill: var(--d-ch);
  opacity: 0;
  animation-duration: 4.2s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

.cs-pk--1 { animation-name: cs-packet-a; animation-delay: 0s; }
.cs-pk--2 { animation-name: cs-packet-b; animation-delay: 1.4s; }
.cs-pk--3 { animation-name: cs-packet-c; animation-delay: 2.8s; }

@keyframes cs-packet-a {
  0%   { transform: translate(152px, 57px);  opacity: 0; }
  10%  { opacity: 1; }
  25%  { transform: translate(202px, 68px); }
  50%  { transform: translate(252px, 118px); }
  68%  { transform: translate(302px, 150px); opacity: 1; }
  86%  { transform: translate(384px, 150px); opacity: .3; }
  100% { transform: translate(384px, 150px); opacity: 0; }
}

@keyframes cs-packet-b {
  0%   { transform: translate(152px, 119px); opacity: 0; }
  10%  { opacity: 1; }
  25%  { transform: translate(202px, 124px); }
  50%  { transform: translate(252px, 140px); }
  68%  { transform: translate(302px, 150px); opacity: 1; }
  86%  { transform: translate(384px, 150px); opacity: .3; }
  100% { transform: translate(384px, 150px); opacity: 0; }
}

@keyframes cs-packet-c {
  0%   { transform: translate(152px, 243px); opacity: 0; }
  10%  { opacity: 1; }
  25%  { transform: translate(202px, 232px); }
  50%  { transform: translate(252px, 182px); }
  68%  { transform: translate(302px, 150px); opacity: 1; }
  86%  { transform: translate(384px, 150px); opacity: .3; }
  100% { transform: translate(384px, 150px); opacity: 0; }
}

@keyframes cs-ring {
  0%, 100% { opacity: .16; transform: scale(.94); }
  50%      { opacity: .42; transform: scale(1.06); }
}

@keyframes cs-human-pulse {
  0%, 100% { opacity: .55; transform: scale(.85); }
  50%      { opacity: 1;   transform: scale(1.15); }
}


/* ==========================================================================
   4. FIT / DOES NOT FIT  (.cs-fit)
   ========================================================================== */

.cs-fit {
  align-items: stretch;
}

.cs-fit__card {
  position: relative;
  overflow: hidden;
  display: grid;
  align-content: start;
  gap: var(--s-5);
  padding: clamp(var(--s-6), 2.4vw, var(--s-10));
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}

/* Both rules are the same object: same length, same weight, same hard stop.
   Only the hue changes, because only the hue carries meaning. */
.cs-fit__card::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: clamp(88px, 34%, 168px);
  height: 4px;
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
  background: var(--accent);
}

.cs-fit__card--no::before {
  background: var(--amber);
}

.cs-fit__card {
  transition: box-shadow var(--d-3) var(--e-out), transform var(--d-3) var(--e-out),
    border-color var(--d-3) var(--e-out);
}

.cs-fit__card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: var(--line-strong);
}

/* The one-line verdict that heads each list. */
.cs-fit__line {
  margin: calc(var(--s-3) * -1) 0 0;
  font-family: var(--font-display);
  font-size: var(--t-title-1);
  line-height: 1.2;
  letter-spacing: -.015em;
  color: var(--ink);
  text-wrap: balance;
}


/* ==========================================================================
   5. WRONG FIT  (.cs-wrong)
   ========================================================================== */

.cs-wrong {
  display: grid;
  gap: clamp(var(--s-6), 2.5vw, var(--s-10));
}

/* Breathing room where these blocks stack directly on each other. The
   qualification argument (fit cards → wrong-fit routes) is deliberately tighter
   than the page's other seams: it is one argument, not two sections. */
.cs-phases + .cs-cost,
.cs-kcb + .cs-chips {
  margin-top: clamp(var(--s-10), 4vw, var(--s-16));
}

.cs-fit + .cs-wrong {
  margin-top: clamp(var(--s-8), 2.6vw, var(--s-10));
}

/* `ch` here resolves against the wrapper's 16px font, not the display-size
   heading inside it — so this measure is set in rem, deliberately. */
.cs-wrong__copy {
  display: grid;
  gap: var(--s-4);
  max-width: 46rem;
}

/* A subordinate clause of the H2 above it, so it sits a clear tier below the
   display head — at display scale the two heads flattened into one another. */
.cs-wrong__copy > :first-child {
  margin: 0;
  font-size: var(--t-title-1);
  line-height: 1.24;
  letter-spacing: -.012em;
  color: var(--ink);
  text-wrap: balance;
}

/* One full-width statement, then the three routes beneath it. A narrow left
   column shredded this line into six ragged fragments. */
/* Enough air that the first route's rule cannot be misread as an underline of
   the heading sitting directly above it. */
.cs-wrong {
  grid-template-columns: 1fr;
  gap: clamp(var(--s-8), 3vw, var(--s-10));
}

@media (max-width: 900px) {
  .cs-wrong__copy { max-width: none; }
}

.cs-wrong__routes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-5);
}

/* Rule-topped columns, not cards. By this point in the page a fourth rounded
   white box in a row starts to read as a template rather than an argument. */
.cs-wrong__routes > li {
  display: grid;
  align-content: start;
  gap: var(--s-2);
  padding: var(--s-4) 0 0;
  border: 0;
  border-top: 2px solid color-mix(in srgb, var(--amber) 62%, transparent);
  border-radius: 0;
  background: none;
  box-shadow: none;
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--body);
}

.cs-wrong__routes > li > .cs-k {
  color: color-mix(in srgb, var(--amber) 58%, var(--ink));
}


/* ==========================================================================
   6. KEEP · CONNECT · BUILD  (.cs-kcb)
   ========================================================================== */

.cs-kcb {
  display: grid;
  gap: clamp(var(--s-5), 2vw, var(--s-8));
}

.cs-kcb__tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4);
}

.cs-kcb__tab {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  text-align: left;
  display: grid;
  align-content: start;
  gap: var(--s-2);
  min-height: 44px;
  margin: 0;
  padding: clamp(var(--s-5), 1.6vw, var(--s-6));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  color: var(--body);
  font: inherit;
  transition:
    background var(--d-2) var(--e-out),
    border-color var(--d-2) var(--e-out),
    box-shadow var(--d-2) var(--e-out);
}

.cs-kcb__tab:hover {
  background: var(--bg-card-2);
  border-color: var(--line-strong);
}

.cs-kcb__kicker {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color var(--d-2) var(--e-out);
}

.cs-kcb__name {
  font-family: var(--font-display);
  font-size: var(--t-title-2);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--ink);
}

.cs-kcb__when {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--muted);
}

/* Selected tab — supports whichever hook site.js uses. */
.cs-kcb__tab.is-active,
.cs-kcb__tab[aria-selected="true"],
.cs-kcb__tab[data-active],
.cs-kcb__tab[aria-current]:not([aria-current="false"]) {
  background: var(--bg-card-2);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line));
  box-shadow: var(--shadow-lift);
}

.cs-kcb__tab.is-active .cs-kcb__kicker,
.cs-kcb__tab[aria-selected="true"] .cs-kcb__kicker,
.cs-kcb__tab[data-active] .cs-kcb__kicker,
.cs-kcb__tab[aria-current]:not([aria-current="false"]) .cs-kcb__kicker {
  color: var(--accent);
}

.cs-kcb__tab.is-active .cs-kcb__when,
.cs-kcb__tab[aria-selected="true"] .cs-kcb__when,
.cs-kcb__tab[data-active] .cs-kcb__when,
.cs-kcb__tab[aria-current]:not([aria-current="false"]) .cs-kcb__when {
  color: var(--body);
}

/* Panels ----------------------------------------------------------------- */

.cs-kcb__panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(var(--s-6), 3vw, var(--s-12));
  padding: clamp(var(--s-6), 2vw, var(--s-8));
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}

/* Never fight the show/hide mechanism. */
.cs-kcb__panel[hidden],
.cs-kcb__panel[aria-hidden="true"] {
  display: none;
}

.cs-kcb__copy {
  display: grid;
  align-content: start;
  gap: var(--s-4);
  max-width: 46ch;
}

.cs-kcb__lead {
  margin: 0;
  font-size: var(--t-lead);
  line-height: 1.42;
  letter-spacing: -.005em;
  color: var(--ink);
  text-wrap: pretty;
}

.cs-kcb__cost {
  margin: 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-soft);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--muted);
}

.cs-kcb__cost > :first-child {
  margin-inline-end: var(--s-2);
}

.cs-kcb__cost :is(strong, b) {
  font-weight: 500;
  color: var(--ink);
}

.cs-kcb__fig {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

/* Mini diagrams (viewBox 0 0 320 190) ------------------------------------ */

/* The 320-unit viewBox needs an explicit type size, or labels inherit 16px and
   burst their plates. Width (not max-width) sets the cap — see note above. */
.cs-kcb .cs-kcb__fig svg.cs-mini {
  width: 100%;
  max-width: 520px;
  color: var(--body);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .06em;
}

/* The Keep figure carries no channels, so it was the one panel whose bottom
   third fell empty. Its ghost box now states the consequence as well. */
.cs-mini__sub {
  font-size: 8.5px;
  letter-spacing: .12em;
  fill: var(--d-label);
}

.cs-mini__box {
  color: var(--ink);
}

.cs-mini__box rect {
  fill: var(--d-plate);
  stroke: color-mix(in srgb, var(--d-node) 34%, var(--d-line));
  stroke-width: 2;
}

.cs-mini__ch path {
  fill: none;
  stroke: var(--d-ch);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.cs-mini__node {
  fill: var(--d-node);
  stroke: var(--d-node-d);
  stroke-width: 2;
}

.cs-mini__out {
  fill: none;
  stroke: var(--d-out);
  stroke-width: 3;
  stroke-linecap: round;
}

.cs-mini__ghost {
  color: var(--muted);
}

/* The middle band of the Keep figure — where its siblings carry channels. */
.cs-mini__note {
  fill: var(--d-label);
  letter-spacing: .14em;
}

.cs-mini__ghost rect {
  fill: none;
  stroke: color-mix(in srgb, var(--d-node) 34%, var(--d-line));
  stroke-width: 2.5;
  stroke-dasharray: 6 6;
}

.cs-mini__bar {
  color: var(--d-node-d);
}

.cs-mini__bar rect {
  fill: color-mix(in srgb, var(--d-node) 12%, transparent);
  stroke: color-mix(in srgb, var(--d-node) 55%, transparent);
  stroke-width: 1.75;
}

.cs-mini__layer {
  color: var(--d-node-d);
}

.cs-mini__layer rect {
  fill: color-mix(in srgb, var(--d-node) 14%, transparent);
  stroke: color-mix(in srgb, var(--d-node) 62%, transparent);
  stroke-width: 1.75;
}

/* Every label in the minis is authored at the centre x of its plate, so it must
   be centre-anchored — otherwise CALENDAR and BILLING run out of their boxes. */
.cs-mini text {
  font-weight: 500;
  text-anchor: middle;
}


/* ==========================================================================
   7. CAPABILITY CHIPS  (.cs-chips)
   ========================================================================== */

/* Eight items, four columns, two full rows. As a wrapping pill row this
   orphaned two chips on a second line against a wide ragged gap; as a fixed
   grid it is a block with a clean right edge. */
.cs-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-7) clamp(var(--s-5), 2vw, var(--s-8));
}

.cs-chips > li {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  padding: var(--s-3) 0 0;
  border: 0;
  border-top: 2px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: 0;
  background: none;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  line-height: 1.5;
  letter-spacing: .04em;
  color: var(--ink);
  transition: border-color var(--d-2) var(--e-out), color var(--d-2) var(--e-out);
}

.cs-chips > li::before {
  content: "";
  flex: none;
  align-self: center;
  width: 6px;
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--accent);
}

.cs-chips > li:hover {
  border-top-color: var(--accent);
}


/* ==========================================================================
   8. BUILD CARDS  (.cs-builds / .cs-build)
   ========================================================================== */

.cs-builds {
  align-items: stretch;
}

.cs-build {
  display: grid;
  align-content: start;
  gap: var(--s-5);
}

/* Card glyphs. The 44px plate itself is core.css — it sets the colour the
   stroke inherits, so the glyph re-themes with the band. All this rule does is
   close the grid gap under it, so plate and index numeral read as one head
   rather than two separate markers stacked above the title. */
.cs-build > .card__icon {
  margin-bottom: calc(var(--s-3) * -1);
}

/* .cs-flow — the three-step micro-graphic that heads a build card.
   Same mono/uppercase register as .dg-label, so cards and diagrams match. */
.cs-flow {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) 0;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.4;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

.cs-flow > span {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

.cs-flow > span::before {
  content: "";
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--accent);
}

/* Connector between steps — the routing mark, not a text arrow. */
.cs-flow > span + span { margin-left: var(--s-2); }

.cs-flow > span + span::after { content: none; }

.cs-flow > span:not(:last-child) {
  padding-right: var(--s-6);
  background-image: linear-gradient(90deg, var(--line-strong), var(--line-strong));
  background-size: var(--s-4) 1.5px;
  background-position: right center;
  background-repeat: no-repeat;
}

/* The single-sentence body of a build card. */
.cs-build__line {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--body);
}


/* .cs-synth — the page's single synthetic-data statement. A quiet fact under a
   hairline, not an amber caution slab: amber is reserved for the moments a
   human has to look at (the decision gate, the exception). */
.cs-synth {
  margin: 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--line-soft);
  max-width: 62ch;
  font-size: .8125rem;
  line-height: 1.6;
  color: var(--muted);
}


/* ==========================================================================
   9. PHASES  (.cs-phases / .cs-phase)
   ========================================================================== */

.cs-phases {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
}

.cs-phase {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr) minmax(0, 26rem);
  align-items: start;
  gap: var(--s-5) clamp(var(--s-6), 2.6vw, var(--s-12));
  padding: clamp(var(--s-6), 2.2vw, var(--s-8)) 0;
  border-top: 1px solid var(--line);
  transition: background var(--d-2) var(--e-out);
}

.cs-phases > .cs-phase:last-child {
  border-bottom: 1px solid var(--line);
}

.cs-phase:hover {
  background: color-mix(in srgb, var(--ink) 3%, transparent);
}

.cs-phase__marker {
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  line-height: 1.5;
  letter-spacing: .08em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.cs-phase__main {
  display: grid;
  gap: var(--s-2);
  min-width: 0;
}

.cs-phase__main > :first-child {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-title-2);
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--ink);
}

.cs-phase__main > :last-child {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--body);
  max-width: 62ch;
}

.cs-phase__out {
  display: grid;
  align-content: start;
  gap: var(--s-2);
  padding: var(--s-5);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--body);
}

.cs-phase__out > p:not(.cs-k):not(.cs-phase__gate) {
  margin: 0;
  color: var(--ink);
}

.cs-phase__gate {
  margin: var(--s-1) 0 0;
  padding-top: var(--s-3);
  border-top: 1px dashed var(--line);
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--muted);
}

.cs-phase__gate :is(strong, b, em) {
  font-style: normal;
  font-weight: 500;
  color: var(--amber);
}

.band--light .cs-phase__gate :is(strong, b, em),
.band--paper-white .cs-phase__gate :is(strong, b, em) {
  color: color-mix(in srgb, var(--amber) 58%, var(--ink));
}


/* ==========================================================================
   10. COST  (.cs-cost)
   ========================================================================== */

.cs-cost {
  display: grid;
  gap: clamp(var(--s-6), 2.5vw, var(--s-10));
}

.cs-cost__copy {
  display: grid;
  gap: var(--s-4);
  max-width: var(--w-text);
}

/* Single-line items — pills, not cards, so the block stays light. */
.cs-cost__pills {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.cs-cost__pills > li {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--body);
}

.cs-cost__pills > li::before {
  content: "";
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--accent);
  opacity: .7;
}


/* ==========================================================================
   11. LEDGER  (.cs-ledger)
   ========================================================================== */

.cs-ledger {
  display: grid;
}

.cs-ledger__row {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  align-items: start;
  gap: var(--s-3) clamp(var(--s-6), 2.6vw, var(--s-12));
  padding: clamp(var(--s-5), 2vw, var(--s-8)) 0;
  border-top: 1px solid var(--line);
}

.cs-ledger__row:last-child {
  border-bottom: 1px solid var(--line);
}

.cs-ledger__tag {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* Leave real .badge components alone; only dress up plain elements. */
.cs-ledger__tag > *:not(.badge) {
  display: inline-flex;
  align-items: center;
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-card-2);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.6;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Term left, explanation right — the row reads across the full measure. */
.cs-ledger__body {
  display: grid;
  grid-template-columns: minmax(0, 19rem) minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s-2) clamp(var(--s-6), 2.4vw, var(--s-10));
  min-width: 0;
}

.cs-ledger__body > :first-child {
  margin: 0;
  font-size: var(--t-title-3);
  line-height: 1.4;
  color: var(--ink);
  text-wrap: balance;
}

.cs-ledger__body > :last-child {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--muted);
  max-width: 68ch;
}

/* .cs-maint — one full-width strip closing the ownership band. */
.cs-maint {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  align-items: start;
  gap: var(--s-5) clamp(var(--s-6), 2.6vw, var(--s-12));
  padding: clamp(var(--s-6), 2.4vw, var(--s-8)) clamp(var(--s-6), 2.4vw, var(--s-10));
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--paper-card, #fff);
  box-shadow: var(--shadow-card);
}

.cs-maint > .eyebrow { margin: 0; }

.cs-maint .cs-ticks {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4) clamp(var(--s-6), 2.4vw, var(--s-10));
}

@media (max-width: 860px) {
  .cs-maint { grid-template-columns: 1fr; }
  .cs-maint .cs-ticks { grid-template-columns: 1fr; }
}


/* ==========================================================================
   12. CTA BAND  (.cs-cta)
   ========================================================================== */

.cs-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.cs-cta > .shell {
  position: relative;
  z-index: 1;
}


/* ==========================================================================
   12b. LIGHT-PRIMARY POLISH — contrast anchors, hover, amber focal points
   ========================================================================== */

/* Tabs read as a real control set on light: white plates, blue selected. */
.cs-kcb__tab {
  background: var(--paper-card, #fff);
  box-shadow: var(--shadow-card);
}

.cs-kcb__tab:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
}

.cs-kcb__tab.is-active,
.cs-kcb__tab[aria-selected="true"],
.cs-kcb__tab[data-active],
.cs-kcb__tab[aria-current]:not([aria-current="false"]) {
  background: var(--paper-card, #fff);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), var(--shadow-lift);
}

.cs-kcb__tab.is-active .cs-kcb__name,
.cs-kcb__tab[aria-selected="true"] .cs-kcb__name {
  color: var(--accent);
}

.cs-kcb__panel { background: var(--paper-card, #fff); }

/* The hero's secondary action was white-on-pale-blue and effectively invisible.
   It is now a real outline button: ink label, accent edge, accent wash. */
.cs-hero__cta .btn--secondary {
  background: var(--paper-card, #fff);
  border: 2px solid var(--accent);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}

.cs-hero__cta .btn--secondary:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--paper-card, #fff));
  border-color: var(--accent);
  color: var(--ink);
}

/* The qualification argument runs across two consecutive bands. Both are set
   tighter than the page default so a buyer who already knows they need
   software reaches "what we build" without wading through it. */
#fit,
#decide {
  padding-block: clamp(var(--s-10), 4.2vw, var(--s-12));
}

/* Two hues, used as evidence: the build card leans blue, the do-not-build card
   leans amber, so the semantic pair is visible before a word is read. */
.cs-fit__card--yes {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent) 6%, var(--paper-card, #fff)),
      var(--paper-card, #fff) 58%);
  border-color: color-mix(in srgb, var(--accent) 22%, var(--line));
}

.cs-fit__card--no {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--amber) 12%, var(--paper-card, #fff)),
      var(--paper-card, #fff) 58%);
  border-color: color-mix(in srgb, var(--amber) 30%, var(--line));
}

/* Kept intentionally plate-free — see §7. */

/* Phase rows — the seven numerals ARE this band's graphic, so they are set at
   display scale rather than as a small mono tick. */
.cs-phase { grid-template-columns: 5rem minmax(0, 1fr) minmax(0, 26rem); }

.cs-phase__marker {
  font-size: clamp(1.7rem, 2.6vw, 2.4rem);
  line-height: 1;
  margin-top: -.08em;
  font-weight: 500;
  letter-spacing: -.02em;
  color: color-mix(in srgb, var(--accent) 42%, var(--line-strong));
  transition: color var(--d-2) var(--e-out);
}

.cs-phase:hover .cs-phase__marker { color: var(--accent); }

/* Seven of these stack in one band. As white rounded cards they turned the
   band into a grid of identical boxes; as tinted, left-ruled panels they read
   as outcomes hanging off the spine of the process. */
.cs-phase__out {
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  border: 0;
  border-left: 2px solid color-mix(in srgb, var(--accent) 34%, transparent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  box-shadow: none;
  transition: background var(--d-2) var(--e-out), border-color var(--d-2) var(--e-out);
}

.cs-phase:hover .cs-phase__out {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-left-color: var(--accent);
}

/* The three decision gates are the amber moments in this band. */
.cs-phase__gate { border-top-color: color-mix(in srgb, var(--amber) 45%, transparent); }

/* Cost block — two columns, the number-sized statement carrying the band end. */
.cs-cost {
  grid-template-columns: minmax(0, 1fr) minmax(0, .8fr);
  align-items: center;
  padding: clamp(var(--s-6), 2.4vw, var(--s-10));
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--paper-card, #fff);
  box-shadow: var(--shadow-card);
}

.cs-cost__copy > .display-3 { margin: 0; letter-spacing: -.02em; }

@media (max-width: 900px) {
  .cs-cost { grid-template-columns: 1fr; }
}

/* Ledger rows — hairline lights and the row lifts on hover. */
.cs-ledger__row {
  transition: background var(--d-2) var(--e-out);
  padding-inline: var(--s-4);
  margin-inline: calc(var(--s-4) * -1);
  border-radius: var(--r-md);
}

.cs-ledger__row:hover { background: color-mix(in srgb, var(--accent) 5%, transparent); }

/* Build cards get a white plate + real lift on light. */
.cs-build {
  background: var(--paper-card, #fff);
  transition: transform var(--d-3) var(--e-out), box-shadow var(--d-3) var(--e-out);
}

.cs-build:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }

.cs-build .card__index {
  color: var(--accent);
  font-size: var(--t-title-2);
}

/* Pills lift; the de-boxed routes only warm their rule. */
.cs-cost__pills > li {
  background: var(--paper-card, #fff);
  transition: transform var(--d-2) var(--e-out), box-shadow var(--d-2) var(--e-out),
    border-color var(--d-2) var(--e-out);
}

.cs-cost__pills > li:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
  border-color: var(--line-strong);
}

.cs-wrong__routes > li {
  transition: border-color var(--d-2) var(--e-out);
}

.cs-wrong__routes > li:hover { border-top-color: var(--amber); }

/* ==========================================================================
   13. RESPONSIVE
   ========================================================================== */

@media (max-width: 1100px) {
  .cs-hero__inner {
    grid-template-columns: 1fr;
    gap: clamp(var(--s-8), 5vw, var(--s-12));
  }

  .cs-hero__copy { max-width: 44rem; }
  .cs-hero__title { max-width: 18ch; }

  .cs-hero__figure {
    justify-content: flex-start;
    padding-inline: 0;
  }

  /* Must out-specify the desktop cap above, or the rule never lands. */
  .cs-hero .cs-hero__figure svg.cs-layerfig { max-width: 560px; }

  .cs-figplate { justify-content: flex-start; }

  .cs-kcb__panel {
    grid-template-columns: 1fr;
    gap: clamp(var(--s-6), 4vw, var(--s-10));
  }

  .cs-kcb__copy { max-width: none; }

  .cs-kcb__fig {
    padding-top: var(--s-6);
    border-top: 1px solid var(--line-soft);
  }

  .cs-phase {
    grid-template-columns: 4.5rem minmax(0, 1fr);
  }

  .cs-phase__out { grid-column: 2; }
}

/* Only 4 or 2 columns — 3 would orphan two items on a third row again. */
@media (max-width: 860px) {
  .cs-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .cs-kcb__tabs { grid-template-columns: 1fr; }

  .cs-kcb__tab {
    grid-template-columns: auto 1fr;
    align-items: baseline;
    column-gap: var(--s-4);
  }

  .cs-kcb__kicker { grid-column: 1; grid-row: 1; }
  .cs-kcb__name   { grid-column: 2; grid-row: 1; }
  .cs-kcb__when   { grid-column: 1 / -1; grid-row: 2; }

  .cs-wrong__routes,
  .cs-cost__pills {
    grid-template-columns: 1fr;
  }

  .cs-ledger__row {
    grid-template-columns: 1fr;
    gap: var(--s-4);
  }

  .cs-ledger__tag { align-self: start; }

  .cs-ledger__body { grid-template-columns: 1fr; }
}

/* ---- Mobile cut of the hero figure -------------------------------------
   Below 560px the desktop 640-unit drawing scales to ~46%, which drops its
   labels to ~6px. Instead of shrinking it further, the phone-drawn 320-unit
   figure takes over: same argument, fewer elements, shorter labels, and type
   that lands around 12px because the viewBox is close to the render width. */
@media (max-width: 560px) {
  .cs-hero .cs-hero__figure svg.cs-layerfig--desk { display: none; }

  .cs-hero .cs-hero__figure svg.cs-layerfig--mob {
    display: block;
    position: relative;
    width: 100%;
    max-width: 100%;
    overflow: visible;
    color: var(--body);
  }

  /* The tab-panel minis shrink on the same curve — hold them over the floor. */
  .cs-kcb .cs-kcb__fig svg.cs-mini { font-size: 13px; letter-spacing: .04em; }

  .cs-mini__sub { font-size: 11px; letter-spacing: .08em; }
}

@media (max-width: 620px) {
  .cs-hero__copy { gap: var(--s-5); }
  .cs-hero__title { max-width: none; }
  .cs-hero__lead { max-width: none; }

  .cs-hero__cta { width: 100%; }

  /* Two stacked buttons of different widths read as an accident. */
  .cs-hero__cta > .btn {
    flex: 1 1 100%;
    justify-content: center;
  }

  .cs-hero__fine::before { display: none; }

  .cs-hero__figure { padding: 0; }
  .cs-hero .cs-hero__figure svg.cs-layerfig { max-width: 100%; }

  .cs-phase {
    grid-template-columns: 1fr;
    gap: var(--s-4);
    padding-block: var(--s-8);
  }

  .cs-phase__out {
    grid-column: 1;
    padding: var(--s-5);
  }

  .cs-phase__marker { font-size: var(--t-title-2); margin-top: 0; }

  .cs-chips { gap: var(--s-4) var(--s-5); }

  /* Wrapped flows leave a connector dangling at the line end — drop the rule
     and let spacing carry the sequence instead. */
  .cs-flow { gap: var(--s-2) var(--s-5); }

  .cs-flow > span:not(:last-child) {
    padding-right: 0;
    background-image: none;
  }

  .cs-flow > span + span { margin-left: 0; }

  .cs-fit__card,
  .cs-kcb__panel,
  .cs-wrong__routes > li,
  .cs-cost__pills > li {
    padding: var(--s-6);
  }
}

@media (max-width: 400px) {
  .cs-chips { grid-template-columns: 1fr; }
  .cs-ledger__body > :first-child { font-size: var(--t-body); }
}


/* ==========================================================================
   14. REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .cs-pk,
  .cs-layerfig__ring {
    animation: none;
  }

  .cs-pk { opacity: .8; }
  .cs-layerfig__ring { opacity: .3; }

  .cs-kcb__tab,
  .cs-chips > li,
  .cs-phase {
    transition: none;
  }
}
