/* a2a bank reference runtime - console styling.
 *
 * The page is split down the middle on purpose. The left half is warm, light
 * and calm, because that is the whole of what the customer experiences. The
 * right half is dark and instrumented, because that is what one tap set off.
 * The seam between them is the argument the prototype is making, so it is a
 * hard edge and never a gradient.
 */
/* The palette lives in a2a-tokens.css, Direction A (Ember & Steel), linked
 * ahead of this file in both pages. Ember is the human side: the customer, alerts,
 * DENY, faults, the current step. Steel is the machine side: telemetry, GA
 * products, ALLOW, the traced path.
 *
 * What follows is only what Direction A does not cover. Nothing here is a
 * value anybody invented: each one is what this build already used, kept so
 * that wiring up the tokens did not quietly restyle a surface that nobody
 * had made a decision about yet. Every one of them is a question still open,
 * and they are grouped by the question they are waiting on.
 */
:root {
  /* Type. The tokens file also defines --font-display, --font-ui and
   * --font-mono for Newsreader and IBM Plex, and both faces are now loaded.
   * The switch is deliberately not made here: it would change every glyph on
   * the page, which is more than this step is supposed to move. */
  --display: "Bodoni Moda", Didot, "Times New Roman", serif;
  --sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* The seam is a width here, and a colour in the tokens file. Renamed rather
   * than resolved: var(--seam-w) is the colour, var(--seam-w) is the 2px track
   * the split screen is built on. */
  --seam-w: 2px;

  /* Amber, the third accent. Direction A has two, and this page turned out to
   * need a third: not refused, not passed, waiting on a person. Maturity used
   * to borrow it and no longer does, so it now means only escalation, an
   * armed control and a gap somebody has to close. The wash and edge are the
   * alpha steps this file already used, named rather than invented. */
  --amber: #d6a756;
  --amber-fill: #8a6212;
  --amber-edge: rgba(214, 167, 86, 0.42);
  --amber-wash: rgba(214, 167, 86, 0.14);

  /* Bone had three alphas doing one job, at .09, .13 and .14. One wash. */
  --ink-wash: rgba(247, 241, 233, 0.12);

  /* The phone. A dark device sitting on the paper half, so it is neither the
   * estate ramp nor the paper ramp. Direction A has no equivalent and element
   * 09 is where the customer surface gets decided. */
  --ph-bg: #14120e;
  --ph-lift: #201c16;
  --ph-line: rgba(247, 241, 233, 0.14);
  --ph-ink: #f0ebdd;
  --ph-dim: #9b9382;
  --ph-accent: #b53a22;
  --ph-accent-soft: rgba(181, 58, 34, 0.16);
  --ph-accent-ink: #fbf6ec;
  --ph-link: #e28a72;
  --ph-card-a: #2c2720;
  --ph-card-b: #231d14;
  --ph-warn: #d6a756;
  --ph-bad: #e28a72;

  /* Zone grounds in the mesh. Element 02 replaces these with a --zone-edge
   * and --surface, so they are held at today's values until then. */
  --zone-outside: #121009;
  --zone-dmz: #231d14;
  --zone-ew: #221d15;

  /* The device bezel, darker than any page ground on purpose: it is an object
   * on a desk rather than a panel. */
  --bezel: #0c0a07;

  /* Steps of a token rather than colours of their own: one notch brighter on
   * hover, and the scrim behind the drawer. --steel-hover is the old accent's
   * light step and has no Direction A equivalent. */
  --btn-hover: #fff;
  --steel-hover: #b6cae6;
  --scrim: rgba(17, 15, 11, 0.72);

  /* Shading, not pigment: a wash over whatever sits behind it. */
  --wash-dark: rgba(0, 0, 0, 0.22);
  --wash-dark-2: rgba(0, 0, 0, 0.3);
  --wash-light: rgba(255, 255, 255, 0.07);
  --wash-light-2: rgba(255, 255, 255, 0.09);
  --lift-near: rgba(27, 24, 17, 0.35);
  --lift-far: rgba(27, 24, 17, 0.62);

  /* Paper, the two steps Direction A does not carry. Both are unused today. */
  --paper-2: #f7f2e6;
  --paper-edge: rgba(27, 24, 17, 0.18);

  /* A control whose only boundary is its border needs that border at 3:1,
   * which is WCAG 1.4.11. --hairline is 1.45:1 on --ground and --rule is
   * 1.99:1, so neither will do for one. This is the lightest step along
   * --rule's own hue that clears the floor on the lightest ground a control sits on. Solved for the
   * requirement rather than picked by eye, and it is for controls only:
   * cards and dividers keep --hairline and --rule. */
  --edge-control: #736d67;

  /* No ink at all, for print. */
  --print-paper: #fff;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  font-size: 15px;
  color: var(--paper-ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--steel-fill); color: var(--ink-hi); }

/* ================= topbar ================= */
.topbar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: 1rem;
  padding: 0.6rem 1.4rem;
  background: var(--ground);
  border-bottom: 1px solid var(--rule);
}
.mark { display: flex; align-items: center; gap: 0.65rem; }
/* The mark: two agents, one continuous exchange. The nodes are equal
 * because neither side of an agent to agent call is the customer of the
 * other, and they take the pulse in turn, which is the whole idea in two
 * seconds of animation. */
.mark-logo { width: 30px; height: 30px; flex: none; overflow: visible; }
/* The mark is two agents and one continuous exchange, so the exchange moves.
 * A short stroke travels the upper arc left to right, then the lower arc back,
 * and the loop takes 3.2s. It is a2a, drawn.
 *
 * This is motion along a path, not the opacity throb the design rules rule
 * out: a pulse decorates, a packet crossing from one node to the other is the
 * thing the mark is about. The nodes sit still and equal, because neither
 * side of an agent to agent call is the customer of the other. */
.ml-arc { fill: none; stroke: var(--ember); stroke-width: 1.8; stroke-linecap: round; opacity: 0.45; }
.ml-node { fill: var(--ember); }
.ml-flow {
  fill: none; stroke: var(--ember); stroke-width: 2.8; stroke-linecap: round;
  stroke-dasharray: 15 100;
  animation: ml-travel 3.2s linear infinite;
}
.ml-flow.back { animation-delay: 1.6s; }
@keyframes ml-travel {
  0%   { stroke-dashoffset: 15; }
  50%  { stroke-dashoffset: -100; }
  100% { stroke-dashoffset: -100; }
}

.mark-text h1 {
  font-family: var(--display); font-weight: 400; font-size: 1.4rem;
  font-style: italic;
  color: var(--ink-hi); line-height: 1; letter-spacing: 0.01em;
}
.mark-text p {
  font-family: var(--mono); font-size: 0.58rem; color: var(--ink-mid);
  text-transform: uppercase; letter-spacing: 0.16em; margin-top: 0.15rem;
}
.clock {
  font-family: var(--mono); font-size: 0.7rem; color: var(--ink);
  border: 1px solid var(--hairline); border-radius: 0;
  padding: 0.3rem 0.6rem; white-space: nowrap;
}
.spacer { flex: 1 1 auto; }
.transport { display: flex; gap: 0.4rem; flex-wrap: wrap; }

.btn {
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.02em;
  color: var(--ground); background: var(--ink-hi);
  border: 1px solid transparent; border-radius: 0;
  padding: 0.42rem 0.85rem; cursor: pointer;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.btn:hover { background: var(--btn-hover); }
.btn.primary { background: var(--steel); color: var(--ground); font-weight: 500; }
.btn.primary:hover { background: var(--steel-hover); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--edge-control); }
.btn.ghost:hover { color: var(--ink-hi); border-color: var(--ink-mid); }
.btn:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }

/* ================= the spine ================= */
.spine {
  position: sticky; top: 51px; z-index: 55;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  overflow-x: auto; scrollbar-width: none;
}
.spine::-webkit-scrollbar { display: none; }
/* The rail. Eight marks on a rule, and only the one being watched speaks.
   The rules that drew eight equal columns lived here and were still arguing
   with this from four hundred lines further down, which is how .moment ended
   up with a background, an underline and a border it no longer wanted. */
.moment {
  position: relative; text-align: left; font-family: inherit;
  display: flex; align-items: center; gap: 0.5rem;
  background: none; border: 0; border-radius: 0;
  padding: 0 0.15rem; min-height: 52px; cursor: pointer;
  color: var(--ink-mid);
}
/* the rule between the marks, drawn by the marks themselves */
.moment + .moment::before {
  content: ""; width: 34px; height: 1px; background: var(--rule); flex: none;
  margin-right: 0.5rem;
}
.m-dot {
  width: 23px; height: 23px; flex: none; border-radius: 50%;
  border: 1px solid var(--edge-control);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0;
  color: var(--ink-pending); background: var(--ground);
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.moment.done .m-dot { color: var(--ink); border-color: var(--ink-pending); }
.moment.viewing .m-dot {
  background: var(--ember-fill); border-color: var(--ember-fill); color: var(--ink-hi);
}
.moment .m-title {
  font-size: 0.82rem; color: var(--ink-hi); white-space: nowrap; padding-left: 0.15rem;
}
.moment .m-when {
  font-family: var(--mono); font-size: 0.58rem; color: var(--ink-mid);
  text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap; padding-right: 0.3rem;
}
.moment:hover .m-dot { border-color: var(--ember); color: var(--ink); }
.moment.viewing:hover .m-dot { color: var(--ink-hi); }
.moment:focus-visible { outline: 2px solid var(--ember); outline-offset: -3px; }

/* ================= the split ================= */
.split {
  display: grid;
  grid-template-columns: 1fr var(--seam-w) 1fr;
  grid-template-rows: 1fr;
  /* the topbar and the spine are both sticky and both fixed height, so the
   * split has to make up the rest or the dark body shows under the paper */
  min-height: calc(100vh - 121px);
}
/* the seam. Every item below is pinned to row 1 explicitly: this pseudo
 * element is the first grid item, so without that the auto-placement cursor
 * has already passed column 1 and the human half drops to a second row. */
.split::before {
  content: ""; grid-column: 2; grid-row: 1;
  background: var(--seam);
}

.side-label {
  display: flex; align-items: center; gap: 0.55rem;
  padding-bottom: 1.1rem;
}
.side-label h2 {
  font-family: var(--mono); font-size: 0.6rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.2em;
}
.side-dot { width: 5px; height: 5px; border-radius: 50%; flex: none; }
.side-meta {
  margin-left: auto; font-family: var(--mono); font-size: 0.62rem;
  color: var(--ink-mid);
}

/* ---------------- human half ---------------- */
.human {
  grid-column: 1; grid-row: 1;
  background: var(--paper);
  color: var(--paper-ink);
  padding: 2.4rem clamp(1.2rem, 4vw, 3.4rem) 3rem;
  min-height: 100%;
}
.human .side-label h2 { color: var(--paper-meta); }
.human .side-dot { background: var(--steel-fill); }

.stage { display: flex; justify-content: center; }

/* ---------------- the phone ---------------- *
 * Its own design system, because it is a different product surface from the
 * console around it. Dark app, warm paper under it: the device reads as an
 * object on a desk rather than a panel in a dashboard.
 */
.phone { width: 100%; max-width: 326px; }
.phone-bezel {
  background: var(--bezel);
  border-radius: 40px;
  padding: 8px;
  box-shadow:
    0 0 0 1px var(--wash-light) inset,
    0 30px 60px -26px var(--lift-far),
    0 4px 14px -4px var(--lift-near);
}
.phone-screen {
  background: var(--ph-bg);
  border-radius: 33px;
  /* A phone is a fixed piece of glass. It was min-height alone, so a long
     screen stretched the device instead of scrolling inside it: sixteen
     mandates on the profile tab, or See all on a run with forty movements,
     and the handset grew to twice the height of the column beside it. The
     content scrolls now and the navigation stays where a thumb expects it.
     No visible scrollbar, because phones do not have one. */
  height: 648px;
  overflow-y: auto;
  scrollbar-width: none;
  display: flex; flex-direction: column;
  overflow: hidden;
  color: var(--ph-ink);
  font-size: 14px;
}
.ic { width: 18px; height: 18px; display: block; flex: none; }

.ph-status {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.7rem 1.15rem 0.35rem;
  font-family: var(--mono); font-size: 0.6rem; color: var(--ph-dim);
}
.ph-sig { font-size: 0.4rem; letter-spacing: 0.12em; }

.ph-head { display: flex; align-items: center; gap: 0.65rem; padding: 0.45rem 1.05rem 0.9rem; }
.ph-head.sub { padding-bottom: 0.7rem; }
.ph-who { flex: 1 1 auto; min-width: 0; }
.ph-date { display: block; font-size: 0.68rem; color: var(--ph-dim); }
.ph-name { display: block; font-size: 0.95rem; font-weight: 500; letter-spacing: -0.01em; }
.ph-title { flex: 1 1 auto; font-size: 0.95rem; font-weight: 500; }
.ph-chip {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  background: var(--ph-lift); color: var(--ph-dim);
  display: flex; align-items: center; justify-content: center;
}
.ph-ava {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  background: var(--ph-lift); color: var(--ph-ink);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.03em;
}
.ph-ava.glyph { color: var(--ph-dim); }
.ph-ava.glyph.good { background: var(--ph-accent-soft); color: var(--ph-link); }
.ph-ava.glyph.warn { background: var(--amber-wash); color: var(--ph-warn); }
.ph-ava.glyph.bad { background: var(--ember-wash); color: var(--ph-bad); }

/* the card */
.ph-card {
  margin: 0 1.05rem;
  border-radius: 20px; padding: 1rem 1.05rem 0.95rem;
  background: linear-gradient(162deg, var(--ph-card-a), var(--ph-card-b));
  box-shadow: 0 1px 0 var(--wash-light-2) inset;
}
.ph-card.shut { opacity: 0.45; filter: saturate(0.4); }
.pc-top { display: flex; align-items: center; gap: 0.5rem; }
.pc-label {
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.13em;
  color: rgba(240, 235, 221, 0.72);
}
/* The hit area is 44px; the glyph is still 15px. Padding out and margin back
 * is how a control gets a thumb-sized target without the design moving. */
.pc-eye {
  background: none; border: 0; cursor: pointer; color: rgba(240, 235, 221, 0.6);
  padding: 15px; margin: -15px; display: inline-flex; align-items: center;
}
.pc-eye:hover { color: var(--ph-ink); }
.pc-eye:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; border-radius: 0; }
.pc-eye .ic { width: 15px; height: 15px; }
.pc-wave { margin-left: auto; color: rgba(240, 235, 221, 0.55); }
.pc-wave .ic { width: 17px; height: 17px; }

.pc-bal { margin: 0.7rem 0 1.5rem; display: flex; align-items: baseline; }
.pc-whole { font-size: 1.95rem; font-weight: 500; letter-spacing: -0.025em; font-variant-numeric: tabular-nums; }
.pc-cents { font-size: 1.15rem; font-weight: 500; color: rgba(240, 235, 221, 0.72); }
.pc-bal.moved { animation: tick 0.55s ease; }
@keyframes tick {
  0% { color: var(--ph-accent); transform: translateY(-2px); }
  100% { color: inherit; transform: none; }
}
.pc-pan { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.06em; color: rgba(240, 235, 221, 0.82); }
.pc-meta { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.4rem; }
.pc-meta span {
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.1em;
  color: rgba(240, 235, 221, 0.5);
}
.pc-tier {
  margin-left: auto; background: var(--ph-accent); color: var(--ph-accent-ink) !important;
  border-radius: 999px; padding: 0.16rem 0.5rem; font-weight: 600;
}

.ph-dots { display: flex; justify-content: center; gap: 5px; padding: 0.8rem 0 0.2rem; }
.ph-dots .dot {
  width: 16px; height: 3px; border-radius: 0; background: var(--ph-line);
  border: 0; padding: 0; cursor: pointer;
}
.ph-dots .dot.on { background: var(--ph-dim); }
.ph-dots .dot:hover { background: var(--ph-dim); }
.ph-dots .dot:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 3px; }

/* actions */
.ph-acts { display: flex; justify-content: space-between; padding: 0.75rem 1.35rem 0.95rem; }
.ph-act { display: flex; flex-direction: column; align-items: center; gap: 0.38rem; }
.ph-act span { font-size: 0.66rem; color: var(--ph-dim); }
.pa-ring {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--ph-lift); color: var(--ph-ink);
  display: flex; align-items: center; justify-content: center;
}
.pa-ring .ic { width: 20px; height: 20px; }

/* segmented control */
.ph-seg { display: flex; gap: 0.4rem; padding: 0 1.05rem 0.55rem; }
.seg {
  display: flex; align-items: center; gap: 0.35rem;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--ph-lift); color: var(--ph-dim);
  font-family: inherit; font-size: 0.76rem; padding: 0.4rem 0.85rem;
  min-height: var(--hit-min); justify-content: center;
  transition: background 0.18s, color 0.18s;
}
.seg:hover { color: var(--ph-ink); }
.seg.on { background: var(--ph-accent); color: var(--ph-accent-ink); font-weight: 500; }
.seg:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; }
.seg-n { font-family: var(--mono); font-size: 0.58rem; opacity: 0.7; }

.ph-lh {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0.5rem 1.05rem 0.35rem;
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.14em; color: var(--ph-dim);
}
.ph-seeall {
  background: none; border: 0; cursor: pointer; padding: 0;
  font-family: var(--mono); font-size: 0.6rem; color: var(--ph-link);
}
.ph-seeall:hover { text-decoration: underline; text-underline-offset: 2px; }
.ph-seeall:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; }

/* rows */
.ph-list { padding: 0 1.05rem; display: flex; flex-direction: column; gap: 0.35rem; }
.ph-empty { font-size: 0.78rem; color: var(--ph-dim); padding: 1.6rem 0; text-align: center; }
.ph-row {
  display: flex; align-items: center; gap: 0.65rem;
  background: var(--ph-lift); border-radius: 14px; padding: 0.6rem 0.7rem;
}
.ph-row .ic { width: 16px; height: 16px; }
.r-mid { flex: 1 1 auto; min-width: 0; }
.r-name { display: block; font-size: 0.8rem; line-height: 1.32; }
.r-sub { display: block; font-family: var(--mono); font-size: 0.58rem; color: var(--ph-dim); margin-top: 0.14rem; }
.r-amt { font-size: 0.82rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.r-amt.in { color: var(--ph-ink); }
.ph-row.alert .r-name {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; font-size: 0.76rem;
}
.ph-row.alert.warn { background: var(--amber-wash); }
.ph-row.alert.bad { background: var(--ember-wash); }
.ph-row.alert.good { background: rgba(209, 70, 42, 0.08); }
.ph-row.fresh { animation: slide-in 0.45s cubic-bezier(0.2, 0.8, 0.3, 1) both; }
@keyframes slide-in {
  from { opacity: 0; transform: translateY(-7px); }
  to { opacity: 1; transform: none; }
}

/* bottom navigation */
.ph-nav {
  margin-top: auto; display: flex; justify-content: space-around;
  padding: 0.7rem 0.7rem 0.9rem; border-top: 1px solid var(--ph-line);
  /* pinned to the bottom of the glass while the content scrolls under it */
  position: sticky; bottom: 0; background: var(--ph-bg);
}
.phone-screen::-webkit-scrollbar { display: none; }
.nav {
  display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  color: var(--ph-dim); font-size: 0.6rem;
  padding: 0.3rem 0.75rem; border-radius: 999px;
}
.nav .ic { width: 19px; height: 19px; }
.nav.on { background: var(--ph-accent); color: var(--ph-accent-ink); font-weight: 500; }
.nav { border: 0; background: none; font-family: inherit; cursor: pointer; }
.nav:hover { color: var(--ph-ink); }
.nav.on:hover { color: var(--ph-accent-ink); }
.nav:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; }
button.ph-chip { border: 0; cursor: pointer; font-family: inherit; padding: 0; }
button.ph-chip:hover { color: var(--ph-ink); }
button.ph-chip:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; }

/* the three tabs behind the navigation. Every figure on them is read out of
   the ledger, the limits engine or the mandate registry, so they carry the
   phone's own type and not a second style for a second kind of truth. */
.ph-note { font-family: var(--mono); font-size: 0.56rem; color: var(--ph-dim); letter-spacing: 0.04em; }
.ph-sum { display: flex; gap: 0.4rem; padding: 0 1.05rem 0.7rem; }
.ps-cell { flex: 1 1 0; background: var(--ph-lift); padding: 0.6rem 0.7rem; min-width: 0; }
.ps-label { display: block; font-size: 0.6rem; color: var(--ph-dim); letter-spacing: 0.06em; text-transform: uppercase; }
.ps-amt {
  display: block; margin-top: 0.22rem; font-size: 0.92rem; font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}
.ph-row.col { flex-direction: column; align-items: stretch; gap: 0.4rem; }
.ps-line { display: flex; align-items: center; gap: 0.6rem; }
.ps-bar { height: 3px; background: var(--ph-line); }
.ps-bar i { display: block; height: 100%; background: var(--ph-dim); }
.r-amt.bad { color: var(--ph-bad); }
.r-tag {
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ph-dim); white-space: nowrap;
}
.r-tag.off { color: var(--ph-bad); }

/* send money */
.ph-payee {
  display: flex; align-items: center; gap: 0.6rem;
  margin: 0 1.05rem; background: var(--ph-lift); border-radius: 16px; padding: 0.65rem 0.7rem;
}
.ph-change {
  font-size: 0.7rem; color: var(--ph-ink); border: 1px solid var(--ph-line);
  border-radius: 999px; padding: 0.28rem 0.7rem; white-space: nowrap;
}
.ph-youpay {
  text-align: center; padding: 1.5rem 0 0.2rem;
  font-family: var(--mono); font-size: 0.54rem; letter-spacing: 0.16em; color: var(--ph-dim);
}
.ph-amount { display: flex; align-items: baseline; justify-content: center; gap: 0.25rem; }
.pa-cur { font-size: 1.3rem; color: var(--ph-dim); }
.pa-whole { font-size: 2.5rem; font-weight: 500; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.pa-cents { font-size: 1.4rem; font-weight: 500; color: var(--ph-dim); }
.ph-from { text-align: center; font-size: 0.68rem; color: var(--ph-dim); margin-top: 0.5rem; }
.ph-chips { display: flex; justify-content: center; gap: 0.5rem; padding: 1.2rem 1.05rem 0.4rem; }
.ph-quick {
  flex: 1 1 0; text-align: center; background: var(--ph-lift); border-radius: 12px;
  padding: 0.55rem 0; font-size: 0.78rem; color: var(--ph-ink);
}
.ph-pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; padding: 0.55rem 1.05rem 0; }
.pad-key {
  display: flex; align-items: center; justify-content: center;
  background: var(--ph-lift); border-radius: 12px; padding: 0.7rem 0;
  font-size: 1.05rem; color: var(--ph-ink);
}
.pad-key .ic { width: 20px; height: 20px; color: var(--ph-dim); }
.ph-cta {
  margin: auto 1.05rem 1.1rem; text-align: center;
  border: 1px solid var(--ph-line); border-radius: 14px;
  padding: 0.8rem 0; font-size: 0.86rem; color: var(--ph-dim);
}

.moment-copy { max-width: 340px; margin: 1.9rem auto 0; text-align: center; }
.moment-copy .mc-when {
  font-family: var(--mono); font-size: 0.56rem; text-transform: uppercase;
  letter-spacing: 0.18em; color: var(--paper-meta);
}
.moment-copy h3 {
  font-family: var(--display); font-weight: 400; font-size: 1.85rem;
  line-height: 1.12; letter-spacing: -0.01em; margin: 0.35rem 0 0.55rem;
}
.moment-copy p { font-size: 0.87rem; line-height: 1.6; color: var(--paper-body); }

/* ---------------- machine half ---------------- */
.machine {
  grid-column: 3; grid-row: 1;
  background: var(--ground);
  color: var(--ink-hi);
  padding: 2.4rem clamp(1.2rem, 4vw, 3.4rem) 3rem;
  min-height: 100%;
  position: relative;
}
/* faint machine-room grid, so the dark side has texture rather than flat black */
/* no grid texture: this is a document, not a heads up display */
.machine > * { position: relative; }
.machine .side-label h2 { color: var(--ink-mid); }
.machine .side-dot { background: var(--steel); }

.trigger {
  font-family: var(--display); font-size: 1.5rem; font-style: italic;
  line-height: 1.3; color: var(--ink-hi); margin-bottom: 1.7rem;
  max-width: 34ch;
}
.trigger .t-idle { font-style: normal; font-size: 0.9rem; font-family: var(--sans); color: var(--ink-pending); line-height: 1.65; display: block; }

/* the agent chain */
.chain { list-style: none; display: flex; flex-direction: column; }
.node { animation: rise 0.42s cubic-bezier(0.2, 0.8, 0.3, 1) both; }
@keyframes rise {
  from { opacity: 0; transform: translateY(9px); }
  to { opacity: 1; transform: none; }
}
/* the handoff between two agents, carrying how long the bank took about it */
.node.hop {
  font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid);
  letter-spacing: 0.08em; padding: 0.45rem 0 0.45rem 3.3rem; position: relative;
}
.node.hop::before {
  content: ""; position: absolute; left: 17px; top: 0; bottom: 0;
  border-left: 1px solid var(--hairline);
}
.node.hop::after {
  content: ""; position: absolute; left: 14px; bottom: 2px;
  width: 7px; height: 7px; border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline); transform: rotate(45deg);
}
.node.world {
  font-family: var(--mono); font-size: 0.67rem; color: var(--ink-mid);
  padding: 0.55rem 0 0.55rem 3.3rem; position: relative;
}
.node.world::after {
  content: ""; position: absolute; left: 17px; top: 0; bottom: 0;
  border-left: 1px dashed var(--ink-mid); opacity: 0.5;
}
/* the checkpoint acting on one of its own agents */
.node.judged {
  display: flex; align-items: flex-start; gap: 0.6rem;
  margin: 0.55rem 0; padding: 0.55rem 0.7rem;
  border: 1px dashed var(--amber-edge); border-radius: 0;
  font-size: 0.78rem; line-height: 1.45; color: var(--amber);
}
.node.judged .j-mark {
  font-family: var(--mono); font-weight: 600; flex: none;
  width: 16px; height: 16px; border-radius: 50%; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.6rem; border: 1px solid var(--amber-edge);
}

.act-agent .arrow { color: var(--ink-mid); margin: 0 0.35rem; }
/* the agent in its own words. Quiet, but it is the reason it decided this way. */
.act-voice {
  font-family: var(--display); font-style: italic; font-size: 0.95rem;
  line-height: 1.35; color: var(--ink); margin-top: 0.3rem;
}
.act-out.block, .act-out.failed { color: var(--ink); }
.act-out.escalate, .act-out.hold { color: var(--amber); }
.chip {
  font-family: var(--mono); font-size: 0.55rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.1em;
  padding: 0.22rem 0.45rem; border-radius: 0; flex: none; margin-top: 1px;
}
.chip.pass { background: var(--ink-wash); color: var(--ink); }
.chip.block { background: var(--ember-wash); color: var(--ember); }
.chip.escalate, .chip.hold { background: var(--amber-wash); color: var(--amber); }
.chip.failed { background: var(--ember-wash); color: var(--ember); }

/* ten pips: the gates, legible at a glance without a word of text */
.pips { display: flex; gap: 3px; padding: 0 0.85rem 0.6rem 3.25rem; }
.pip { width: 100%; height: 3px; border-radius: 1px; background: var(--raised); }
.pip.ok { background: var(--ink-mid); }
.pip.no { background: var(--ember); }

/* the receipt, folded away until asked for */
.receipt { border-top: 1px solid var(--rule); }
.receipt > summary {
  list-style: none; cursor: pointer;
  font-family: var(--mono); font-size: 0.62rem; color: var(--ink-mid);
  padding: 0.5rem 0.85rem; display: flex; align-items: center; gap: 0.4rem;
  min-height: var(--hit-min); display: flex; align-items: center;
}
.receipt > summary::-webkit-details-marker { display: none; }
.receipt > summary::before { content: "\25B8"; font-size: 0.55rem; transition: transform 0.2s; }
.receipt[open] > summary::before { transform: rotate(90deg); }
.receipt > summary:hover { color: var(--ink-hi); }
.receipt-body { padding: 0.1rem 0.85rem 0.9rem; }

.gate-row { display: flex; gap: 0.55rem; padding: 0.24rem 0; font-size: 0.7rem; align-items: baseline; }
.gate-row .g-n { font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid); width: 1.3rem; flex: none; }
.gate-row .g-name { color: var(--ink); width: 8.5rem; flex: none; }
.gate-row .g-detail { color: var(--ink); flex: 1 1 auto; line-height: 1.45; }
.gate-row.no .g-name, .gate-row.no .g-detail { color: var(--ember); }
.gate-row.skip { opacity: 0.4; }

.kv {
  font-family: var(--mono); font-size: 0.66rem; color: var(--ink-mid);
  margin-top: 0.7rem; padding-top: 0.6rem; border-top: 1px dashed var(--hairline);
  line-height: 1.7; word-break: break-word;
}
.kv b { color: var(--ink); font-weight: 500; }
.kv .link {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--steel); text-decoration: underline;
  text-underline-offset: 2px;
}

/* the moment's bottom line */
.summary { margin-top: 1.6rem; border-top: 1px solid var(--rule); padding-top: 1.1rem; }
.summary .s-verdict {
  font-family: var(--display); font-size: 2.1rem; line-height: 1.1;
  letter-spacing: -0.01em;
}
.summary .s-verdict.clean { color: var(--steel); }
.summary .s-verdict.stopped { color: var(--ember); }
.summary .s-verdict.routed { color: var(--amber); }
.summary .s-line { font-size: 0.84rem; line-height: 1.6; color: var(--ink); margin-top: 0.35rem; max-width: 46ch; }
.summary .s-stats {
  font-family: var(--mono); font-size: 0.62rem; color: var(--ink-mid);
  margin-top: 0.75rem; display: flex; flex-wrap: wrap; gap: 0.3rem 1.1rem;
}

/* folds at the foot of the machine side */
.machine-foot { margin-top: 2.2rem; display: flex; flex-direction: column; gap: 0.5rem; }
.fold { border: 1px solid var(--hairline); border-radius: 0; }
.fold > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center;
  font-family: var(--mono); font-size: 0.66rem; color: var(--ink);
  padding: 0.6rem 0.8rem; letter-spacing: 0.02em;
  min-height: var(--hit-min);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before { content: "\25B8"; font-size: 0.55rem; margin-right: 0.5rem; transition: transform 0.2s; }
.fold[open] > summary::before { transform: rotate(90deg); }
.fold > summary:hover { color: var(--ink-hi); }
.fold-n { margin-left: auto; color: var(--ink-mid); font-size: 0.6rem; }
.fold-body { padding: 0.2rem 0.8rem 0.85rem; }

.switch-grid { display: grid; gap: 0.4rem; }
.switch {
  display: flex; align-items: flex-start; gap: 0.6rem; text-align: left;
  background: transparent; border: 1px solid var(--edge-control); border-radius: 0;
  padding: 0.55rem 0.65rem; cursor: pointer; color: var(--ink);
  font-family: inherit; transition: border-color 0.15s, background 0.15s;
}
.switch:hover { border-color: var(--ink-mid); background: var(--surface); }
.switch:focus-visible { outline: 2px solid var(--steel); outline-offset: 1px; }
.sw {
  width: 22px; height: 12px; border-radius: 999px; flex: none; margin-top: 2px;
  background: var(--raised); border: 1px solid var(--hairline); position: relative;
  transition: background 0.18s;
}
.sw::after {
  content: ""; position: absolute; top: 1px; left: 1px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--ink-mid);
  transition: transform 0.18s, background 0.18s;
}
.switch.on .sw { background: var(--ember-wash); border-color: var(--ember); }
.switch.on .sw::after { transform: translateX(10px); background: var(--ember); }
.switch .s-lb { display: block; font-size: 0.76rem; color: var(--ink-hi); }
.switch .s-ds { display: block; font-size: 0.7rem; line-height: 1.45; color: var(--ink); margin-top: 0.15rem; }
.switch.probe .sw { display: none; }
.switch.on .s-lb { color: var(--ember); }

/* the roster. Every agent, whether or not it has fired yet, because sixteen
 * of them under one checkpoint is half the claim the prototype is making. */
.roster-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 0.35rem; }
.agent-chip {
  display: flex; align-items: center; gap: 0.45rem; text-align: left;
  font-family: var(--mono); font-size: 0.66rem; color: var(--ink);
  background: transparent; border: 1px solid var(--edge-control); border-radius: 0;
  padding: 0.4rem 0.5rem; cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
  min-height: var(--hit-min);
}
.agent-chip:hover { border-color: var(--ink-mid); color: var(--ink-hi); }
.agent-chip:focus-visible { outline: 2px solid var(--steel); outline-offset: 1px; }
/* An agent's face is ember wherever it appears: the roster, the mesh, the
 * cast strip and the action card. It is the orange of the mark and of the
 * app's own controls, lightened to --ember rather than the --ember-fill the
 * phone uses, because a fill carrying light text and a 1.7px stroke on a
 * dark ground are not the same problem: the fill measures 2.7:1 as a stroke
 * here, and --ember measures 8.6:1.
 *
 * Colour says who. The frame says what happened, which is why the fired and
 * on states light the border and the id and leave the face alone. */
.agent-chip .a-face { flex: none; color: var(--ember); display: flex; }
.agent-chip .a-face .ic { width: 16px; height: 16px; }
.agent-chip .a-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.agent-chip .a-id { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agent-chip .a-trait {
  font-family: var(--sans); font-size: 0.6rem; line-height: 1.3; color: var(--ink-mid);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agent-chip .a-lvl { font-size: 0.58rem; color: var(--ink-mid); }
.agent-chip.fired { border-color: var(--steel-edge); }
.agent-chip.fired .a-id { color: var(--steel); }
.agent-chip.dead { opacity: 0.45; }
.agent-chip.dead .a-id { color: var(--ember); text-decoration: line-through; }

/* ================= the deck: where it ran ================= *
 * A third stratum under the split. Experience on the left, decisions on the
 * right, and the iron underneath both. Darker than the machine half so that
 * scrolling into it feels like going down a level rather than sideways.
 */
.deck {
  /* One ground for the whole machine side. This used to be its own value a
   * shade darker, which stopped reading as a level the moment the palette
   * moved, and two grounds 1.4 apart are worse than one. The change of level
   * is carried by the rule instead, which is what a rule is for. */
  background: var(--ground);
  border-top: 1px solid var(--rule);
  color: var(--ink-hi);
  padding: 2.6rem clamp(1.2rem, 4vw, 3.4rem) 3.4rem;
}
.deck-inner { max-width: 1680px; margin: 0 auto; }
.deck .side-label h2 { color: var(--ink-mid); }
.deck .side-dot { background: var(--steel); }
.deck-lead {
  font-family: var(--display); font-size: 1.28rem; font-style: italic;
  line-height: 1.42; color: var(--ink); max-width: 64ch; margin-bottom: 2rem;
}
.deck-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 2rem 2.4rem; }
.deck-h3 {
  font-family: var(--mono); font-size: 0.58rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--ink-hi);
  padding-bottom: 0.8rem; border-bottom: 1px solid var(--rule); margin-bottom: 0.9rem;
}

/* ---------------- the mesh ---------------- *
 * North-south runs down the page, because that is how traffic crosses the
 * perimeter. East-west is the wide band in the middle, because that is where
 * an agent estate actually fails. Between every pair of tiers there is a
 * membrane, and the membrane is drawn rather than described.
 */
.mesh { margin-bottom: 2.6rem; }

.tier {
  border: 1px solid var(--hairline); border-radius: 0;
  padding: 0.85rem 1rem 0.95rem; background: var(--surface);
  position: relative;
}
/* No accent bar down the side. The band already says it is east-west twice
 * over, in its ground and in the axis chip on its own header, and a border
 * used as an accent is the thing rule 3 of the brief rules out. */
.tier.ew { background: var(--zone-ew); }
.tier.outside { background: var(--zone-outside); border-style: dashed; }
.tier.dmz { background: var(--zone-dmz); border-color: var(--amber-edge); }
.tier.app { background: var(--surface); border-color: var(--rule); }
.tier.gate { border-color: var(--steel-edge); }
.tier.core { background: var(--raised); border-color: var(--steel-edge); }

.tier-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.2rem 0.7rem; margin-bottom: 0.7rem; }
.tier-name { font-family: var(--mono); font-size: 0.74rem; color: var(--ink-hi); letter-spacing: 0.02em; }
.tier-sub { font-size: 0.74rem; color: var(--ink-mid); flex: 1 1 auto; }
.tier-axis {
  font-family: var(--mono); font-size: 0.52rem; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-mid);
  border: 1px solid var(--hairline); border-radius: 0; padding: 0.12rem 0.4rem;
}
.tier.ew .tier-axis { color: var(--steel); border-color: var(--steel-edge); }

.nodes { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: 0.5rem; }
.znode { border: 1px solid var(--hairline); border-radius: 0; padding: 0.5rem 0.6rem; background: var(--wash-dark); }
.znode.denied { border-style: dashed; border-color: var(--ember-edge); }
.zn-top { display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; }
.zn-label { font-size: 0.78rem; color: var(--ink-hi); }
.znode.denied .zn-label { color: var(--ember); }
.zn-note { font-size: 0.7rem; line-height: 1.45; color: var(--ink); margin-top: 0.2rem; }

.tag {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.1em; padding: 0.1rem 0.3rem; border-radius: 0; white-space: nowrap;
  border: 1px solid transparent;
}
/* Maturity is carried by shape, not by hue: filled has shipped, outlined is
 * announced, dashed is a tech preview. It survives a greyscale print, and it
 * gives amber back to the one thing amber should mean. */
.tag.ga { background: var(--ink-wash); color: var(--ink-hi); }
.tag.announced { background: transparent; color: var(--ink-mid); border-color: var(--rule); }
.tag.preview { background: transparent; color: var(--ink-mid); border-color: var(--rule); border-style: dashed; }

/* the sixteen, as a mesh rather than a list */
.agent-mesh {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
  gap: 0.35rem; margin-bottom: 0.7rem;
}
.mnode {
  display: flex; align-items: center; gap: 0.4rem; text-align: left;
  background: var(--wash-dark-2); border: 1px solid var(--edge-control); border-radius: 0;
  padding: 0.35rem 0.45rem; cursor: pointer; font-family: var(--mono);
  transition: border-color 0.2s, box-shadow 0.25s;
  min-height: var(--hit-min);
}
.mnode:hover { border-color: var(--ink-mid); }
.mnode:focus-visible { outline: 2px solid var(--steel); outline-offset: 1px; }
.mn-glyph {
  font-size: 0.53rem; font-weight: 600; color: var(--ember); flex: none;
  width: 20px; height: 20px; border: 1px solid var(--hairline); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.mn-glyph .ic { width: 12px; height: 12px; }
.mn-id { font-size: 0.6rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.mnode.on { border-color: var(--steel); background: var(--steel-wash); }
.mnode.on .mn-glyph { border-color: var(--steel); }
.mnode.on .mn-id { color: var(--ink-hi); }

.served { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.6rem; }
.srv {
  font-family: var(--mono); font-size: 0.58rem; color: var(--steel);
  border: 1px solid var(--steel-edge); border-radius: 0; padding: 0.18rem 0.4rem;
}

/* the enforcement point between two tiers */
.membrane {
  margin: 0; padding: 0.55rem 1rem 0.6rem 2.2rem;
  border-left: 1px solid var(--hairline); margin-left: 1.3rem;
  position: relative;
}
.membrane::before {
  content: ""; position: absolute; left: -4px; top: 50%;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ground); border: 1px solid var(--ink-mid);
}
.membrane.has-deny { border-left-color: var(--ember-edge); }
.membrane.has-deny::before { border-color: var(--ember); }
.mem-by {
  font-family: var(--mono); font-size: 0.56rem; text-transform: uppercase;
  letter-spacing: 0.13em; color: var(--ink-mid); margin-bottom: 0.25rem;
}
.mem-rules { display: flex; flex-direction: column; gap: 0.15rem; }
.mem-rule { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.45rem; font-size: 0.68rem; }
.mem-rule b { font-family: var(--mono); font-size: 0.6rem; font-weight: 400; color: var(--ink); }
.mem-rule i {
  font-family: var(--mono); font-style: normal; font-size: 0.5rem;
  text-transform: uppercase; letter-spacing: 0.1em; padding: 0.08rem 0.3rem; border-radius: 0;
}
.mem-rule.allow i { background: var(--ink-wash); color: var(--ink); }
.mem-rule.deny i { background: var(--ember-wash); color: var(--ember); }
.mem-rule span { color: var(--ink); }
.mem-rule.deny span { color: var(--ink); }
.mem-rules.outbound { margin-top: 0.6rem; padding-top: 0.55rem; border-top: 1px dashed var(--hairline); }

/* day 2 and the SOC */
.svc { padding: 0.45rem 0 0.5rem; border-bottom: 1px solid var(--rule); }
.svc:last-of-type { border-bottom: 0; }
.svc-top { display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; }
.svc-name { font-family: var(--mono); font-size: 0.68rem; color: var(--ink-hi); }
.svc-axis {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink);
  border: 1px solid var(--rule); padding: 0.04rem 0.3rem;
}
.svc-does { font-size: 0.72rem; line-height: 1.5; color: var(--ink); margin-top: 0.18rem; }
.soc-note {
  margin-top: 0.8rem; padding-top: 0.7rem; border-top: 1px dashed var(--hairline);
  font-size: 0.73rem; line-height: 1.55; color: var(--ink);
}
.deck-h3.spaced { margin-top: 1.7rem; }

/* the CISO lens */
.ciso { border-top: 1px solid var(--rule); }
.ciso-row {
  display: grid; grid-template-columns: minmax(200px, 1.1fr) minmax(200px, 1.2fr) minmax(200px, 1.3fr);
  gap: 0.4rem 1.6rem; padding: 0.7rem 0; border-bottom: 1px solid var(--rule);
}
.ciso-q { font-family: var(--display); font-size: 1.05rem; line-height: 1.3; color: var(--ink-hi); }
.ciso-c { font-size: 0.75rem; line-height: 1.5; color: var(--ink); }
/* Element 07: the question in the display face, the control in the UI face,
 * and where to look for it in mono at --steel. The third column was never a
 * third ink, it was an accent nobody had applied yet. */
.ciso-h { font-family: var(--mono); font-size: 0.7rem; line-height: 1.5; color: var(--steel); }
@media (max-width: 860px) {
  .ciso-row { grid-template-columns: 1fr; gap: 0.25rem; }
  .ciso-q { font-size: 1.15rem; margin-bottom: 0.1rem; }
}

/* the estate */
.dom { margin-bottom: 1.1rem; }
.dom-head { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.45rem; }
.dom-name { font-size: 0.82rem; color: var(--ink-hi); }
.dom-sub { font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid); }
.clus { padding: 0.4rem 0 0.4rem 0.7rem; border-left: 1px solid var(--hairline); }
.clus-top { display: flex; align-items: center; gap: 0.6rem; }
.clus-name { font-family: var(--mono); font-size: 0.7rem; color: var(--ink); }
.host-pips { display: flex; gap: 3px; margin-left: auto; }
.hpip {
  width: 7px; height: 7px; border-radius: 1px;
  background: var(--raised); border: 1px solid var(--hairline);
  transition: background 0.3s, box-shadow 0.3s;
}
.hpip.lit {
  background: var(--steel); border-color: var(--steel);
}
.clus-kit { font-family: var(--mono); font-size: 0.6rem; color: var(--ink); margin-top: 0.2rem; }

/* what this moment used */
.place {
  padding: 0.55rem 0 0.6rem; border-bottom: 1px solid var(--hairline);
  animation: rise 0.4s ease both;
}
.place:last-child { border-bottom: 0; }

/* the boundary */
.fw {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.55rem;
  padding: 0.4rem 0; border-bottom: 1px solid var(--rule);
}
.fw-path { font-family: var(--mono); font-size: 0.63rem; color: var(--ink); }
.fw-act {
  font-family: var(--mono); font-size: 0.54rem; text-transform: uppercase;
  letter-spacing: 0.1em; padding: 0.1rem 0.35rem; border-radius: 0;
}
.fw.allow .fw-act { background: var(--ink-wash); color: var(--ink); }
.fw.deny .fw-act { background: var(--ember-wash); color: var(--ember); }
.fw.deny .fw-path { color: var(--ink-hi); }
.fw-note { font-size: 0.68rem; color: var(--ink); flex-basis: 100%; }

.egress { margin-top: 1rem; padding: 0.7rem 0.8rem; border-radius: 0; border: 1px solid; }
.egress.sealed { border-color: var(--steel-edge); background: var(--steel-wash); }
.egress.open { border-color: var(--amber-edge); background: var(--amber-wash); }
.eg-rule { font-family: var(--mono); font-size: 0.64rem; }
.egress.sealed .eg-rule { color: var(--steel); }
.egress.open .eg-rule { color: var(--amber); }
.eg-detail { font-size: 0.74rem; line-height: 1.5; color: var(--ink); margin-top: 0.35rem; }

/* ---------------- the path ---------------- *
 * A distributed trace, read the way an SRE reads one: top to bottom, one hop
 * per row, and the hops that were never reached greyed rather than hidden.
 * A refused action has to look like a route that stops.
 */
.pathwrap { margin-bottom: 2.4rem; }
.path-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.6rem 1rem; }
.path-head .deck-h3 { border: 0; padding-bottom: 0; margin-bottom: 0; flex: none; }
.path-pick { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.pchip {
  display: flex; align-items: center; gap: 0.35rem;
  background: transparent; border: 1px solid var(--edge-control); border-radius: 0;
  color: var(--ink-mid); cursor: pointer;
  font-family: var(--mono); font-size: 0.6rem; padding: 0.22rem 0.6rem;
  min-height: var(--hit-min);
  transition: border-color 0.15s, color 0.15s;
}
.pchip:hover { color: var(--ink-hi); border-color: var(--ink-mid); }
.pchip:focus-visible { outline: 2px solid var(--steel); outline-offset: 1px; }
.pchip-n { opacity: 0.55; }
.pchip.on { border-color: var(--steel); color: var(--steel); }
.pchip.bad.on { border-color: var(--ember); color: var(--ember); }

/* landscape: the zones are columns, the links between them are the arrows,
 * and the whole round trip fits on one screen instead of twelve rows */
.lanes {
  display: flex; align-items: stretch; gap: 0;
  margin-top: 1rem; overflow-x: auto; padding-bottom: 0.5rem;
  scrollbar-width: thin;
  /* the playhead scrolls the column it is in into view on a narrow window */
  scroll-behavior: smooth;
}
.lane {
  /* seven of these plus six links have to fit a 1500px screen without a
   * horizontal scroll, because the last lane is the one with the punchline
   * in it: the hops the route never reached */
  flex: 1 1 0; min-width: 146px;
  display: flex; flex-direction: column; gap: 0.4rem;
  padding: 0 0.1rem;
}
.lane-name {
  font-family: var(--mono); font-size: 0.52rem; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-hi);
  padding-bottom: 0.45rem; border-bottom: 1px solid var(--rule); margin-bottom: 0.2rem;
}
.lane.check .lane-name, .lane.core .lane-name { color: var(--steel); }
.lane-none { font-family: var(--mono); font-size: 0.58rem; color: var(--ink-pending); opacity: 0.5; }

/* The lane body is what the renderer diffs against, so the nodes are its
 * children rather than the column's. */
.lane-body { display: flex; flex-direction: column; gap: 0.4rem; }
.lhop {
  border: 1px solid var(--hairline); border-radius: 0;
  background: var(--surface); padding: 0.45rem 0.55rem;
}
/* There is no entrance animation on a hop, deliberately. It used to be here,
 * and `rise` is filled both ways, so its final opacity sat above the playhead's
 * hold-back in the cascade and nothing was ever dimmed on a first render. The
 * playhead is the entrance now: a node arrives held back and lights when the
 * route reaches it. One mechanism rather than two fighting each other. */
/* the mark and the tag are always present and usually empty */
.lhop-mark:empty, .lhop .tag:empty { display: none; }
.lhop.ok { border-left: 2px solid var(--ink-mid); }
.lhop.stop { border-left: 2px solid var(--ember); background: var(--ember-wash); }
.lhop.hold { border-left: 2px solid var(--amber); }
/* A hop the route never reached is one ink, not four behind 38% opacity.
 * The opacity was doing the dimming and taking the contrast down with it, to
 * roughly 2:1. --ink-pending is the token for exactly this and holds 5.48:1. */
.lhop.skip { border-style: dashed; }
.lhop.skip .lhop-n,
.lhop.skip .lhop-name,
.lhop.skip .lhop-where,
.lhop.skip .lhop-note { color: var(--ink-pending); }
.lhop-top { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 0.4rem; }
.lhop-n {
  font-family: var(--mono); font-size: 0.52rem; color: var(--ink);
  border: 1px solid var(--hairline); border-radius: 50%;
  width: 16px; height: 16px; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.lhop.ok .lhop-n { color: var(--ink); border-color: var(--hairline); }
.lhop.stop .lhop-n { color: var(--ember); border-color: var(--ember); }
.lhop-name { font-size: 0.75rem; line-height: 1.3; color: var(--ink-hi); }
.lhop.stop .lhop-name { color: var(--ember); }
.lhop-where { font-family: var(--mono); font-size: 0.56rem; color: var(--ink); margin-top: 0.2rem; word-break: break-word; }
.lhop-note { font-size: 0.68rem; line-height: 1.45; color: var(--ink); margin-top: 0.2rem; }

.lane-link {
  flex: 0 0 46px; align-self: center;
  display: flex; flex-direction: column; align-items: center; gap: 0.1rem;
  padding: 0 0.2rem; text-align: center;
}
.ll-axis {
  font-family: var(--mono); font-size: 0.44rem; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-mid); line-height: 1.2;
}
.ll-arrow { font-size: 0.95rem; color: var(--steel); line-height: 1; }
.ll-by { font-family: var(--mono); font-size: 0.46rem; color: var(--ink-mid); line-height: 1.2; }
.lane-link.dead .ll-arrow { color: var(--ember); }
.lane-link.dead .ll-axis, .lane-link.dead .ll-by { opacity: 0.45; }

.path-side.wide { border-left: 0; border-top: 1px solid var(--rule); padding: 1rem 0 0; margin-top: 1rem; }
.obs-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 0.4rem 1.4rem; }
.obs { padding: 0.35rem 0 0.4rem; border-bottom: 1px solid var(--hairline); }
.path-h4 {
  font-family: var(--mono); font-size: 0.54rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.16em; color: var(--ink-mid); margin-bottom: 0.6rem;
}
.path-empty { font-size: 0.8rem; color: var(--ink-pending); padding: 0.6rem 0; }

/* the standalone page */
.deck-open {
  font-family: var(--mono); font-size: 0.58rem; color: var(--steel);
  text-decoration: underline; text-underline-offset: 3px;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  border: 1px solid var(--edge-control); border-radius: 0;
  padding: 0.16rem 0.6rem; text-transform: none; letter-spacing: 0.02em;
}
.deck-open:hover { background: var(--steel-wash); }
body.solo .deck { border-top: 0; min-height: calc(100vh - 65px); }
.solo-note { font-size: 0.78rem; line-height: 1.6; color: var(--ink); max-width: 78ch; margin-bottom: 1.8rem; }
.solo-pick { display: flex; gap: 0.2rem; }
.solo-chip {
  font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid);
  border: 1px solid var(--edge-control); border-radius: 0; padding: 0.3rem 0.55rem;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  text-decoration: none;
}
.solo-chip:hover { color: var(--ink-hi); border-color: var(--ink-mid); }
.solo-chip.on { color: var(--steel); border-color: var(--steel); }

/* ---------------- the SOC ---------------- */
.soc { margin-top: 2.4rem; }
.soc-head { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 0.8rem 1.6rem; margin-bottom: 0.9rem; }
.soc-head .deck-h3 { border: 0; padding-bottom: 0; margin-bottom: 0; flex: 1 1 auto; }
.soc-stats { display: flex; gap: 0.45rem; flex-wrap: wrap; }
.soc-stat {
  border: 1px solid var(--hairline); border-radius: 0; padding: 0.4rem 0.7rem;
  display: flex; flex-direction: column; gap: 0.1rem; min-width: 84px;
}
.soc-stat b { font-family: var(--display); font-size: 1.35rem; font-weight: 400; line-height: 1; color: var(--ink-hi); }
.soc-stat span {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--ink-mid);
}
.soc-stat.hot { border-color: var(--ember-edge); }
.soc-stat.hot b { color: var(--ember); }

.soc-queue { border: 1px solid var(--hairline); border-radius: 0; overflow: hidden; }
.soc-row {
  display: grid;
  grid-template-columns: 74px 54px minmax(130px, 1fr) minmax(220px, 2.4fr) minmax(150px, 1.1fr);
  gap: 0.5rem 1rem; align-items: start;
  padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--rule);
  animation: rise 0.32s ease both;
}
.soc-row:last-child { border-bottom: 0; }
.soc-row.head {
  background: var(--surface); animation: none;
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-mid);
}
.soc-row.critical { background: var(--ember-wash); }
.sev {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase; letter-spacing: 0.1em;
  padding: 0.16rem 0.4rem; border-radius: 0; text-align: center;
}
.sev.critical { background: var(--ember); color: var(--ground); font-weight: 600; }
.sev.high { background: var(--ember-wash); color: var(--ember); }
.sev.medium { background: var(--amber-wash); color: var(--amber); }
.sev.low { background: var(--ink-wash); color: var(--ink); }
.soc-t { font-family: var(--mono); font-size: 0.64rem; color: var(--ink-mid); }
.soc-sensor { font-family: var(--mono); font-size: 0.62rem; color: var(--ink-mid); line-height: 1.4; }
.soc-sig { min-width: 0; }
.soc-title { display: block; font-size: 0.8rem; color: var(--ink-hi); }
.soc-detail { display: block; font-size: 0.72rem; line-height: 1.5; color: var(--ink-mid); margin-top: 0.15rem; }
.soc-dis { min-width: 0; }
.dis-state {
  display: inline-block; font-family: var(--mono); font-size: 0.52rem;
  text-transform: uppercase; letter-spacing: 0.1em; padding: 0.12rem 0.38rem; border-radius: 0;
}
.soc-dis.contained .dis-state { background: var(--ink-wash); color: var(--ink); }
.soc-dis.with-a-person .dis-state { background: var(--amber-wash); color: var(--amber); }
.soc-dis.open .dis-state { background: var(--ember-wash); color: var(--ember); }
.dis-by { display: block; font-size: 0.68rem; color: var(--ink-mid); margin-top: 0.2rem; line-height: 1.4; }
.soc-quiet { padding: 1.1rem 0.9rem; font-size: 0.78rem; line-height: 1.55; color: var(--ink-mid); }
/* The same class carries two meanings: an empty queue, and the count of
 * signals below the cut. Only the first is pending, and it is the only one
 * that is ever the child straight after the head row. */
.soc-queue > .soc-quiet:nth-child(2) { color: var(--ink-pending); }

.soc-sensors { margin-top: 1.3rem; }
.sensor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 0.5rem; }
.sensor { border: 1px solid var(--hairline); border-radius: 0; padding: 0.5rem 0.6rem; }
.svc.hot .svc-name { color: var(--steel); }

@media (max-width: 900px) {
  .path-side { border-left: 0; border-top: 1px solid var(--hairline); padding-left: 0; padding-top: 1rem; }
  .soc-row { grid-template-columns: 74px 1fr; gap: 0.3rem 0.8rem; }
  .soc-row.head { display: none; }
  .soc-t, .soc-sensor { grid-column: 2; }
  .soc-sig, .soc-dis { grid-column: 1 / -1; }
}

/* ---------------- live mode ---------------- *
 * Three of the four actions become real, the keypad types, and the CTA
 * submits an envelope through the same checkpoint as everything else.
 */
.ph-welcome {
  flex: 1 1 auto; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; padding: 2rem 1.5rem;
}
.pw-mark {
  width: 46px; height: 46px; border-radius: 50%; margin-bottom: 1.3rem;
  border: 2px solid var(--ph-accent); position: relative;
}
.pw-mark::after { content: ""; position: absolute; inset: 13px; border-radius: 50%; background: var(--ph-accent); }
.ph-welcome h3 { font-family: var(--display); font-weight: 400; font-size: 1.7rem; margin-bottom: 0.6rem; }
.ph-welcome p { font-size: 0.82rem; line-height: 1.6; color: var(--ph-dim); margin-bottom: 1.6rem; }
.pw-cta {
  width: 100%; border: 0; border-radius: 14px; cursor: pointer;
  background: var(--ph-accent); color: var(--ph-accent-ink);
  font-family: inherit; font-size: 0.9rem; font-weight: 500; padding: 0.85rem 0;
}
/* Live mode asks who is driving. The field belongs to the phone, so it wears
 * the phone's ramp rather than the console's. */
.pw-field { width: 100%; display: block; text-align: left; margin-bottom: 1.1rem; }
.pw-label {
  display: block; font-family: var(--mono); font-size: 0.6rem;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--ph-dim);
  margin-bottom: 0.45rem;
}
.pw-input {
  width: 100%; box-sizing: border-box;
  background: var(--ph-lift); color: var(--ph-ink);
  border: 1px solid var(--ph-line); border-radius: 12px;
  font-family: inherit; font-size: 0.95rem; padding: 0.7rem 0.8rem;
  min-height: var(--hit-min);
}
.pw-input::placeholder { color: var(--ph-dim); opacity: 0.7; }
.pw-input:focus { outline: none; border-color: var(--ph-accent); }
.pw-input:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 2px; }
.pw-cta[disabled] { opacity: 0.4; cursor: default; }
.pw-cta:hover { filter: brightness(1.08); }
.pw-cta[disabled]:hover { filter: none; }
.pw-cta:focus-visible { outline: 2px solid var(--ph-ink); outline-offset: 2px; }
.pw-foot { font-size: 0.66rem; color: var(--ph-dim); margin-top: 1.4rem; opacity: 0.8; }

.ph-act.live { background: none; border: 0; cursor: pointer; font-family: inherit; padding: 0; }
.ph-act.live:hover .pa-ring { background: var(--ph-accent); color: var(--ph-accent-ink); }
.ph-act.live:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 3px; border-radius: 10px; }

.ph-payees { display: flex; flex-direction: column; gap: 0.3rem; padding: 0 1.05rem; }
.ph-payee.pick {
  display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left;
  background: var(--ph-lift); border: 1px solid transparent; border-radius: 14px;
  padding: 0.5rem 0.6rem; cursor: pointer; font-family: inherit; color: var(--ph-ink);
}
.ph-payee.pick:hover { border-color: var(--ph-line); }
.ph-payee.pick.on { border-color: var(--ph-accent); }
.ph-payee.pick:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: 1px; }

.ph-amount.over .pa-whole, .ph-amount.over .pa-cents { color: var(--ph-bad); }
.ph-quick { border: 0; cursor: pointer; font-family: inherit; }
.ph-quick:hover { background: rgba(209, 70, 42, 0.16); color: var(--ph-accent); }
.pad-key { border: 0; cursor: pointer; font-family: inherit; }
.pad-key:hover { background: rgba(209, 70, 42, 0.14); }
.pad-key:focus-visible { outline: 2px solid var(--ph-accent); outline-offset: -2px; }
.ph-cta.live {
  border-color: var(--ph-accent); background: var(--ph-accent); color: var(--ph-accent-ink);
  cursor: pointer; font-family: inherit; font-weight: 500;
}
.ph-cta.live:hover { filter: brightness(1.08); }
.ph-cta.live:focus-visible { outline: 2px solid var(--ph-ink); outline-offset: 2px; }
.moment.live { cursor: default; width: 100%; }
.btn:disabled { opacity: 0.35; cursor: not-allowed; }
.btn:disabled:hover { background: var(--ink-hi); }
.btn.ghost:disabled:hover { background: transparent; color: var(--ink); border-color: var(--hairline); }

/* ================= drawer ================= */
.drawer {
  position: fixed; inset: 0; z-index: 90;
  background: var(--scrim);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: none; align-items: center; justify-content: center; padding: 1.2rem;
}
.drawer.open { display: flex; }
.drawer-card {
  background: var(--surface); color: var(--ink-hi);
  border: 1px solid var(--hairline); border-radius: 4px;
  width: min(760px, 100%); max-height: 84vh; display: flex; flex-direction: column;
  animation: rise 0.28s ease both;
}
.drawer-head { display: flex; align-items: center; gap: 1rem; padding: 0.9rem 1.1rem 0.6rem; }
.drawer-head h3 { font-family: var(--mono); font-size: 0.78rem; font-weight: 500; color: var(--steel); }
.note-line { padding: 0 1.1rem 0.8rem; font-size: 0.78rem; line-height: 1.55; color: var(--ink); }
.drawer-card pre {
  font-family: var(--mono); font-size: 0.68rem; line-height: 1.6; color: var(--ink);
  background: var(--ground); border-top: 1px solid var(--hairline);
  padding: 1rem 1.1rem; overflow: auto; white-space: pre-wrap; word-break: break-word;
}

/* ================= narrow ================= */
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; grid-template-rows: auto; min-height: 0; }
  .split::before { display: none; }
  .human { grid-column: 1; grid-row: auto; }
  .machine { grid-column: 1; grid-row: auto; border-top: 1px solid var(--steel-fill); }
  .spine { top: 0; position: static; }
  .topbar { flex-wrap: wrap; position: static; }
  .transport { width: 100%; }
  .moment { min-width: 130px; }
  .gate-row { flex-wrap: wrap; }
  .gate-row .g-name { width: auto; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* correlated-signal count, appended by the SOC queue */
.soc-x {
  font-family: var(--mono); font-size: 0.56rem; color: var(--ink-mid);
  border: 1px solid var(--hairline); border-radius: 0;
  padding: 0.04rem 0.26rem; margin-left: 0.4rem;
}
.cast {
  display: flex; align-items: center; gap: 0.4rem;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: 999px;
  padding: 0.22rem 0.6rem 0.22rem 0.24rem; cursor: pointer;
  font-family: var(--mono); color: var(--ink);
  transition: border-color 0.15s, color 0.15s;
}
.cast:hover { border-color: var(--steel); color: var(--ink-hi); }
.cast:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }
.cast-glyph .ic { width: 12px; height: 12px; }
.am-dom {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--ink-mid);
}
.am-lvl {
  font-family: var(--mono); font-size: 0.5rem; letter-spacing: 0.08em;
  border: 1px solid var(--hairline); border-radius: 0; padding: 0.04rem 0.26rem; color: var(--ink-mid);
}
.am-lvl.L3 { color: var(--steel); border-color: var(--steel-edge); }
.am-pin { font-family: var(--mono); font-size: 0.5rem; color: var(--ink-mid); opacity: 0.75; }

/* hop numbering stays honest: the number is the step, the mark is the state */
.lhop-mark {
  font-family: var(--mono); font-size: 0.48rem; text-transform: uppercase;
  letter-spacing: 0.1em; margin-left: auto; white-space: nowrap;
}
.lhop-mark.stop { color: var(--ember); font-size: 0.8rem; letter-spacing: 0; }
.lhop-mark.skip { color: var(--ink-pending); }
.clus-k8s { font-family: var(--mono); font-size: 0.56rem; color: var(--steel); opacity: 0.75; margin-top: 0.14rem; }

/* the PayNow handle, because a Singaporean customer pays by number */
.ph-paynow { display: block; font-family: var(--mono); font-size: 0.56rem; color: var(--ph-dim); margin-top: 0.14rem; }
.ph-from.sub { font-size: 0.62rem; opacity: 0.8; margin-top: 0.2rem; }

/* ---------------- getting around without a mouse ---------------- *
 * The spine is eight controls deep and the deck is long, so a keyboard user
 * lands on a skip link first. It is only invisible until it is focused.
 */
.skip {
  position: absolute; left: 0.6rem; top: -3rem; z-index: 100;
  background: var(--steel); color: var(--ground);
  font-family: var(--mono); font-size: 0.72rem;
  padding: 0.5rem 0.9rem; border-radius: 0; text-decoration: none;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  transition: top 0.15s;
}
.skip:focus { top: 0.6rem; }
.tgroup { display: flex; gap: 0.4rem; }
.transport { gap: 0.9rem; }
.btn[aria-pressed="true"] { border-color: var(--steel); color: var(--steel); }

/* numbers that are design parameters rather than measurements say so */
.s-stats .modelled { color: var(--amber); opacity: 0.85; }

/* an armed fault only changes what happens next, so the panel says so */
.fault-hint {
  margin-top: 0.6rem; padding: 0.5rem 0.6rem;
  border: 1px dashed var(--amber-edge); border-radius: 0;
  font-size: 0.72rem; line-height: 1.5; color: var(--amber);
}
/* in live mode three actions work and one does not, so it says which */
.ph-act.inert { opacity: 0.4; }

/* jumping around a deck that is four screens tall */
.deck-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.4rem; margin-bottom: 0.9rem; }
.dn {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.03em;
  color: var(--ink-mid); text-decoration: none;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  border-bottom: 1px solid transparent;
}
.dn:hover { color: var(--steel); border-bottom-color: var(--steel); }
.dn:focus-visible { outline: 2px solid var(--steel); outline-offset: 3px; }
.dn-sep { color: var(--ink-mid); opacity: 0.5; font-size: 0.62rem; }
/* the topbar and the spine are sticky, so an anchor must clear them */
#sec-ran, #sec-path, #sec-arch, #sec-detail, #sec-soc, #sec-ciso { scroll-margin-top: 136px; }
body.solo #sec-path, body.solo #sec-arch, body.solo #sec-detail,
body.solo #sec-soc, body.solo #sec-ciso { scroll-margin-top: 72px; }

/* ---------------- the architecture, and taking it away ----------------
 * A diagram that only exists inside one web page cannot go in front of a
 * risk committee, so the heading carries the four ways out of here.
 */
.arch-head {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.5rem 1.2rem;
  margin-top: 1.7rem; padding-bottom: 0.8rem; margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
}
.arch-head .deck-h3 { border: 0; padding-bottom: 0; margin-bottom: 0; flex: 1 1 auto; }
.arch-lead { font-size: 0.78rem; line-height: 1.6; color: var(--ink); max-width: 84ch; margin-bottom: 1.1rem; }

.exporter { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem; }
.xbtn {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.02em;
  color: var(--ink); background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; min-height: var(--hit-min);
  border: 1px solid var(--edge-control); border-radius: 0; padding: 0.22rem 0.7rem;
  transition: color 0.18s, border-color 0.18s;
}
.xbtn:hover { color: var(--steel); border-color: var(--steel); }
.xbtn:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }
.x-status {
  font-family: var(--mono); font-size: 0.56rem; color: var(--ink-mid);
  margin-left: 0.5rem; letter-spacing: 0.02em;
}

/* ---------------- printing the architecture ----------------
 * The console is press black and browsers drop background colours when they
 * print, which would leave light text on white paper and nothing else. So
 * the print path prints one generated SVG on paper and hides the site.
 */
.printonly { display: none; }
@media print {
  @page { size: A3 portrait; margin: 8mm; }
  html, body { background: var(--print-paper); }
  body > *:not(.printonly) { display: none !important; }
  .printonly { display: block !important; }
  .printonly svg { width: 100%; height: auto; }
}

/* availability, stated on every cluster because it is true of every cluster */
.clus-ha { display: flex; align-items: baseline; gap: 0.4rem; margin-top: 0.2rem; flex-wrap: wrap; }
.ha-tag {
  font-family: var(--mono); font-size: 0.5rem; text-transform: uppercase;
  letter-spacing: 0.1em; padding: 0.1rem 0.3rem; white-space: nowrap;
  background: var(--ink-wash); color: var(--ink);
}
.ha-store { font-family: var(--mono); font-size: 0.56rem; color: var(--ink-mid); }

/* ---------------- the playhead ----------------
 * A trace drawn all at once says where the transaction has been. It does not
 * say which part of the estate is carrying it now, which is the thing a
 * reader watching a bank work wants to know. So the route plays, and the
 * three states are: reached, carrying it right now, and not yet.
 *
 * Transitions rather than keyframes on purpose. The hop is not decorating
 * itself, it is changing state, and a state change should ease rather than
 * blink.
 */
.lhop {
  transition: border-color 0.26s ease, background-color 0.26s ease,
              opacity 0.26s ease, transform 0.26s ease;
}
.lhop.waiting { opacity: 0.26; }
.lhop.skip.waiting { opacity: 0.18; }

.lhop.live {
  border-color: var(--steel); border-left-width: 3px; border-left-color: var(--steel);
  background: var(--steel-wash);
  transform: translateY(-2px);
}
.lhop.live .lhop-n {
  color: var(--ground); background: var(--steel); border-color: var(--steel);
}
.lhop.live .lhop-name { color: var(--ink-hi); }
.lhop.live .lhop-where { color: var(--steel); }

.lhop.stop.live {
  border-color: var(--ember); border-left-color: var(--ember);
  background: var(--ember-wash);
}
.lhop.stop.live .lhop-n {
  color: var(--ground); background: var(--ember); border-color: var(--ember);
}
.lhop.stop.live .lhop-where { color: var(--ember); }

/* Where it got to, kept after the route stops moving, so the diagram still
 * answers the question when nothing is animating. */
.lhop.end .lhop-n { color: var(--ground); background: var(--ink); border-color: var(--ink); }
.lhop.stop.end .lhop-n { color: var(--ground); background: var(--ember); border-color: var(--ember); }

/* the arrow moves as the playhead crosses it */
.lane-link { transition: opacity 0.26s ease; }
.lane-link.waiting { opacity: 0.22; }
.lane-link.live .ll-arrow { animation: cross 0.4s ease both; }
.lane-link.live .ll-axis, .lane-link.live .ll-by { color: var(--steel); }
@keyframes cross {
  from { transform: translateX(-6px); opacity: 0.35; }
  to { transform: none; opacity: 1; }
}

/* Somebody who has asked not to be moved is not asking for a slower sweep,
 * they are asking for the finished picture. */
@media (prefers-reduced-motion: reduce) {
  .lhop, .lane-link { transition: none; }
  .lane-link.live .ll-arrow, .node, .soc-row, .ph-row.fresh { animation: none; }
  .ml-flow { animation: none; opacity: 0; }
  .lhop.live { transform: none; }
}

/* ---------------- the receipt ----------------
 * The claim at the top of the deck, as numbers, before anything is
 * described. Figures are set in the display face because that is how a
 * statement prints a figure, and the denominator is the point: three hosts
 * is not interesting, three of twenty four is a blast radius.
 */
.ranwrap { margin-bottom: 2.6rem; }
.ran-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 1rem; margin-bottom: 1rem; }
.ran-head .deck-h3 { border: 0; padding-bottom: 0; margin-bottom: 0; flex: none; }
.ran-scope { font-size: 0.72rem; color: var(--ink-mid); }

.ran { display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); gap: 1.4rem 2.2rem; }
.ran-stat { border-top: 1px solid var(--rule); padding-top: 0.7rem; }
.ran-k {
  display: block; font-family: var(--mono); font-size: 0.5rem;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--ink-mid);
  margin-bottom: 0.5rem;
}
.ran-v { font-family: var(--display); font-size: 1.85rem; line-height: 1; color: var(--ink-hi); }
.ran-v small {
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.04em;
  color: var(--ink-mid); margin-left: 0.35rem;
}
.ran-note { font-size: 0.7rem; line-height: 1.5; color: var(--ink-mid); margin-top: 0.5rem; }
/* only the exception is pigmented, as everywhere else on this page */
.ran-stat.flag { border-top-color: var(--ember); }
.ran-stat.flag .ran-v, .ran-stat.flag .ran-note { color: var(--ember); }
.ran-gap {
  grid-column: 1 / -1; font-size: 0.7rem; line-height: 1.55; color: var(--amber);
  border-top: 1px dashed var(--amber-edge); padding-top: 0.6rem;
}

/* two balanced rows rather than three columns of very different lengths */
.deck-grid.two { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); }
.deck-grid + .deck-grid { margin-top: 2.4rem; }

/* ---------------- the colophon ----------------
 * Three centred lines, the shape the blog's own footer uses: what this is,
 * who made it and where it is written up, then the honest sentence last and
 * quietest. It was three paragraphs of prose once, which is a log of text
 * and not a colophon.
 */
.foot {
  background: var(--ground);
  border-top: 1px solid var(--hairline);
  padding: 2.8rem clamp(1.2rem, 4vw, 3.4rem) 3.2rem;
  text-align: center;
}
.foot-inner { max-width: 70ch; margin: 0 auto; }
/* the masthead face, so the last line of the page answers the first */
.foot-id {
  font-family: var(--display); font-style: italic;
  font-size: 1.12rem; line-height: 1.35; color: var(--ink-hi);
}
.foot-bar { font-style: normal; color: var(--ink-mid); margin: 0 0.45rem; }
.foot-links { font-size: 0.8rem; line-height: 1.6; color: var(--ink); margin-top: 0.75rem; }
.foot-link {
  color: var(--steel); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.foot-link:hover { color: var(--ink-hi); }
.foot-link:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }
.foot-note {
  font-size: 0.7rem; line-height: 1.6; color: var(--ink-mid);
  max-width: 62ch; margin: 1.9rem auto 0;
}

/* ---------------- the primer ----------------
   Orientation for a first visit, in the same grammar as the rest of the page:
   a mono eyebrow, a display serif line, a note under it. It is a native
   details, so closing it needs no script and no stored state, and the page
   below it is exactly what it was before. */
.primer {
  background: var(--ground);
  border-bottom: 1px solid var(--rule);
}
/* It is reached by one button and closed by two, so it needs no bar of its own.
   The bar it had was a third stacked band and a second way in to the same
   thing. */
.primer:focus { outline: none; }

.primer-inner {
  max-width: 1680px; margin: 0 auto;
  padding: 0.2rem 1.4rem 1.9rem;
}
.primer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: 1.5rem 2.2rem;
}
.pstep { border-top: 1px solid var(--rule); padding-top: 0.7rem; }
.pstep h3 {
  font-family: var(--display); font-weight: 400;
  font-size: 1.12rem; line-height: 1.25; letter-spacing: -0.01em;
  color: var(--ink-hi); margin: 0 0 0.5rem;
}
.pstep p { font-size: 0.78rem; line-height: 1.6; color: var(--ink); margin: 0; }

.primer-how { margin-top: 1.8rem; border-top: 1px solid var(--rule); padding-top: 0.7rem; }
.primer-how ol {
  margin: 0; padding: 0; list-style: none;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: 0.55rem 2.2rem;
  counter-reset: how;
}
.primer-how li {
  counter-increment: how;
  font-size: 0.78rem; line-height: 1.6; color: var(--ink);
  padding-left: 1.6rem; position: relative;
}
.primer-how li::before {
  content: counter(how, decimal-leading-zero);
  position: absolute; left: 0; top: 0.05rem;
  font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid);
}
/* the control names, so they are findable in the toolbar above */
.primer-how b { font-weight: 500; color: var(--ink-hi); }

/* ---------------- the toolbar, ranked ----------------
   Seven controls doing four jobs. Nothing is removed, because a demo uses all
   of them; they are ordered by how often a first visit needs them, and the
   three at the right are quietened rather than hidden. Every one keeps the full
   hit target: this is a change of emphasis, not of reach. */
.tgroup.minor { margin-left: 0.2rem; gap: 0.25rem; }
.tgroup.minor .btn {
  font-size: 0.64rem;
  padding: 0.42rem 0.6rem;
  color: var(--ink-mid);
  border-color: transparent;
}
.tgroup.minor .btn:hover { color: var(--ink-hi); border-color: var(--edge-control); }
.tgroup.minor .btn[aria-pressed="true"] { color: var(--steel); border-color: var(--steel); }

/* The way in for somebody who has never seen this. The dot is the one the
   section labels use, so it reads as a starting point rather than an alert. */
.btn.help {
  background: transparent; color: var(--ink);
  border-color: var(--edge-control); gap: 0.45rem;
}
.btn.help .side-dot { background: var(--ember); }
.btn.help:hover { color: var(--ink-hi); border-color: var(--ember); background: transparent; }
.btn.help.on { border-color: var(--ember); color: var(--ink-hi); }

.primer-close { margin-top: 1.6rem; }

/* ---------------- the estate explains itself on request ----------------
   The zone names, products and release tags are what the diagram is for and
   they are always on. The note behind each one is the argument for building it
   that way, which is worth reading once and not thirteen times at once. */
.mesh-bar { display: flex; justify-content: flex-end; padding-bottom: 0.7rem; }
.mesh-notes { font-size: 0.62rem; }

button.zn-top {
  width: 100%; text-align: left; background: none; border: 0; padding: 0;
  font-family: inherit; cursor: pointer; color: inherit;
  min-height: var(--hit-min);
}
button.zn-top::after {
  content: "\25B8"; font-size: 0.6rem; color: var(--ink-mid);
  margin-left: auto; transition: transform 0.15s;
}
button.zn-top[aria-expanded="true"]::after { transform: rotate(90deg); color: var(--ink-mid); }
button.zn-top:hover .zn-label { color: var(--steel); }
button.zn-top:hover::after { color: var(--steel); }
button.zn-top:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }
.znode.denied button.zn-top:hover .zn-label { color: var(--ember); }

/* ================= the action timeline =================
   One action, one row: the bank's clock, who asked, what for, the ten gates,
   the answer. Five of them fit where two cards used to. */
.ln {
  display: grid;
  /* the action column gets what is left, and the gates are a fixed block so
     they cannot squeeze it */
  grid-template-columns: 3.2rem max-content minmax(11rem, 1fr) 88px auto;
  align-items: baseline; gap: 0 0.8rem;
  padding: 0.6rem 0.7rem; border-top: 1px solid var(--hairline);
}
.ln:last-child { border-bottom: 1px solid var(--hairline); }
.ln-t {
  font-family: var(--mono); font-size: 0.62rem; color: var(--ink-mid);
  font-variant-numeric: tabular-nums;
}
.ln-who {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: inherit; text-align: left; min-height: var(--hit-min);
}
.ln-face {
  width: 20px; height: 20px; flex: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--ember);
  font-family: var(--mono); font-size: 0.5rem;
}
.ln-face .ic { width: 13px; height: 13px; }
.ln-id { font-family: var(--mono); font-size: 0.68rem; color: var(--ink-hi); }
.ln-who:hover .ln-id { color: var(--ember); }
.ln-who:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }
.ln-act { font-size: 0.78rem; color: var(--ink); line-height: 1.4; }

.ln .pips { display: flex; gap: 2px; align-self: center; }
.ln .chip { align-self: center; }

/* the why and the consequence sit under the row, spanning the columns that
   carry the words rather than starting at the clock */
.ln-why, .ln-out, .ln-more, .ln .receipt { grid-column: 3 / -1; }
.ln-why {
  font-size: 0.74rem; line-height: 1.5; color: var(--ink);
  margin-top: 0.4rem;
}
.ln-out {
  font-family: var(--mono); font-size: 0.6rem; color: var(--ink-mid);
  margin-top: 0.3rem;
}
.ln-out::before { content: "\2192  "; }
.ln-more {
  justify-self: start; margin-top: 0.35rem;
  background: none; border: 0; padding: 0.2rem 0;
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.06em;
  /* --ink-mid, not --ink-pending: a receipt is not pending, it is just
     secondary, and that token means empty or not-yet-run only. */
  color: var(--ink-mid); cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px; min-height: var(--hit-min);
}
.ln-more:hover { color: var(--ink); }
.ln-more:focus-visible { outline: 2px solid var(--steel); outline-offset: 2px; }

/* only the exception carries a pigment, here as everywhere */
.ln.block, .ln.failed { background: var(--ember-wash); box-shadow: inset 2px 0 0 var(--ember-fill); }
.ln.block .ln-why, .ln.failed .ln-why { color: var(--ink-hi); }
.ln.escalate, .ln.hold { box-shadow: inset 2px 0 0 var(--amber-edge); }

.rc-who { display: flex; flex-wrap: wrap; gap: 0.4rem; padding-bottom: 0.5rem; }
.ln .receipt { margin-top: 0.5rem; }

@media (max-width: 900px) {
  .ln { grid-template-columns: 3.2rem 1fr; }
  .ln-act { grid-column: 2; }
  .ln .pips, .ln .chip { grid-column: 2; justify-self: start; margin-top: 0.3rem; }
  .ln-why, .ln-out, .ln-more, .ln .receipt { grid-column: 2; }
}

/* .pip is width:100% for the full-bleed row it used to live in. In a grid cell
   sized to its content that collapses to nothing, so the row sizes its own. */
/* the old rule indents the pips 3.25rem to line up under a card that no
   longer exists, which inside an 88px cell leaves room for about three */
.ln .pips { gap: 2px; padding: 0; }
.ln .pip { width: 7px; }
