/*
 * The in-flow sections between the scenes.
 *
 * A scene is held while the scroll drives it; these simply scroll. That is the
 * whole distinction, and it decides which stylesheet a rule lives in.
 *
 * `[data-rise]` is the only thing hidden here, and only under `html.scenes` - the
 * same contract the scenes keep. With no JavaScript the class never lands, nothing
 * is hidden, and every section below reads in full.
 */

.flow { padding: var(--banx-section) var(--banx-gutter); }

.flow-inner {
  display: grid;
  gap: var(--banx-space-6);
  width: min(100%, var(--banx-content));
  margin-inline: auto;
}

.flow-head { max-width: 56ch; }

.flow-kicker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--banx-space-3);
  align-items: center;
  margin-bottom: var(--banx-kicker-gap);
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

.flow-kicker .n {
  padding-right: var(--banx-space-3);
  color: var(--banx-accent-text);
  border-right: 1px solid var(--banx-line);
}

.flow-lede {
  max-width: 62ch;
  margin-top: var(--banx-space-4);
  color: var(--banx-muted);
  font-size: var(--banx-text-lg);
  line-height: 1.6;
}

.flow-note {
  max-width: 62ch;
  margin-top: var(--banx-space-4);
  color: var(--banx-subtle);
  font-size: var(--banx-text-xs);
  line-height: 1.7;
}

.flow-h4 {
  margin-bottom: var(--banx-space-4);
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  font-weight: 400;
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

/* ------------------------------------------------------------- applications
 * A 1px-gap grid: one background showing through the gaps rather than a border
 * per cell, which doubles up wherever two cells meet.
 */
.flow-apps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--banx-line);
}

.flow-app {
  display: grid;
  align-content: start;
  gap: var(--banx-space-3);
  padding: var(--banx-space-5);
  color: inherit;
  background: var(--banx-bg);
  transition: background var(--banx-fast) var(--banx-ease);
}

.flow-app:hover { background: var(--banx-surface-2); }

.flow-app small {
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

.flow-app h3 {
  display: flex;
  gap: var(--banx-space-3);
  align-items: center;
  color: var(--banx-text);
  font-size: var(--banx-text-lg);
}

.flow-app h3 .ex-ico { color: var(--banx-accent-text); }
.flow-app p { color: var(--banx-muted); font-size: var(--banx-text-base); line-height: 1.6; }

/* ------------------------------------------------------------------- table */

/* ================================================================ tokenomics
 * One ring, its legend beside it, and the whole allocation on one screen.
 *
 * WHY THIS IS A FLOW SECTION WITH A SCREEN'S HEIGHT AND NOT A PINNED SCENE.
 * `min-height: 100svh` with the content centred gives a reader the whole section
 * in one view, which is what was asked for, and it degrades in the one direction
 * that matters: on a viewport too short to hold it the section simply grows and
 * the page scrolls. A pinned stage CLIPS instead, and that failure has cost this
 * project two rewrites - see the roadmap, which measured 836px of content into a
 * 747px stage before it was unpinned.
 *
 * The ring's geometry is NOT here. Every dasharray and every rotation is computed
 * in Tokenomics.jsx and shipped as SVG presentation attributes, so there is no
 * second copy of the percentages in this file. What is here is colour, size and
 * layout - the things a stylesheet should own.
 */
/* The height budget, measured rather than chosen. At 1440x900 the first attempt
 * came to 1178px against a 900px viewport, and the padding `.flow` gives every
 * other section was 264 of it. A section that promises one screen has to buy that
 * promise from somewhere, and its own margins are the right place: the centring
 * below does the work the padding was doing. */
.tok {
  display: grid;
  align-content: center;
  min-height: 100svh;
  /* 3.5rem here and the section measured 913px against a 900px viewport. Its own
   * margins are what a one-screen promise is bought with. */
  padding-block: var(--banx-space-5);
}

.tok-inner {
  display: grid;
  gap: var(--banx-space-5);
}

.tok-head { max-width: 54ch; }

/* Two lines, not three: sized against the viewport's height because that is the
 * budget it is competing for. */
.tok-head h2 {
  max-width: 24ch;
  font-size: clamp(1.5rem, 3.6svh, 2.5rem);
}

.tok-lede {
  margin: var(--banx-space-3) 0 0;
  color: var(--banx-muted);
  font-size: var(--banx-text-sm);
  line-height: 1.55;
}

/* ---- the ring and the legend, side by side ------------------------------
 * `minmax(0, ...)` on both tracks: the legend's longest PKL figure is mono and
 * will not wrap, so without it the grid resolves the ring's column against that
 * intrinsic width and the ring grows past the viewport. */
.tok-chart {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
  gap: var(--banx-space-7);
  align-items: center;
}

/* The ring is square and bounded by the STAGE's height as well as its column, or
 * a wide viewport gives it a 600px diameter and pushes the legend off the screen.
 * 46svh leaves room for the head, the four group totals and the footer inside one
 * screen; measured rather than chosen. */
.tok-ring {
  position: relative;
  width: 100%;
  max-width: min(100%, 41svh);
  margin-inline: auto;
  aspect-ratio: 1;
}

.tok-ring svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The un-drawn ring. It is a full circle at one hairline, so the shape exists
 * before any wedge does and the wedges read as filling a track rather than as
 * assembling a disc out of nothing. */
.tok-track {
  fill: none;
  stroke: var(--banx-line);
  stroke-width: 13;
}

/* `butt` and not `round`: a rounded cap adds half the stroke width to each end of
 * every wedge, which at 13 units of stroke is 6.5 units of arc a wedge has not
 * been allocated - the 2% wedge would draw about 40% too long. */
.tok-wedge {
  fill: none;
  stroke-width: 13;
  stroke-linecap: butt;
}

/* ---- the wedge colours, and the only place they are declared -----------
 *
 * FOUR HUES, TWO STEPS EACH, and the step is what tells two members of a group
 * apart. Twelve steps were tried first and do not fit a black ground: contrast
 * against #0a0a0b runs out before the twelfth, and measured, the darkest two came
 * to 3.21:1 and 2.40:1 where a non-text graphic needs 3:1. The 4% market wedge was
 * under the floor and the 5% one was standing on it.
 *
 * Two steps is enough because a group's members ALTERNATE, so every boundary
 * inside a group is a colour change as well as a 0.6-unit gap.
 *
 * Contrast on the ground, computed rather than judged: mint 12.05:1 and 7.66:1,
 * cyan 6.83:1 and 3.76:1, amber 9.50:1 and 6.50:1, violet 6.73:1 and 3.67:1.
 *
 * FOUR HUES AND NO GREYS. It was two greys once and they were indistinguishable,
 * because six steps of lightness do not fit this ground: the darkest of one family
 * against the lightest of the other came to 1.79:1, no more than one step inside a
 * pair. Hue carries all four now.
 *
 * The cyan is the tightest of them, and worth stating: at 198 degrees it is 43
 * from the mint, and the two are ADJACENT on the ring - users then ecosystem. 198
 * is the most separated cyan that still reads as cyan; the alternatives at 191 and
 * 194 came to 36 and 39. The gap between wedges and the group's own heading in the
 * legend are what carry the boundary where hue is thinnest.
 * The step WITHIN each pair is only about 1.5:1, which is a visible difference and
 * not a strong one - it does not have to be, because the gap between two wedges
 * already separates them and the legend is in the same order.
 *
 * Declared once as custom properties and consumed twice, by the wedge and by its
 * legend dot, so a row and its arc cannot disagree about which colour they are. */
.tok {
  --tok-users-a: var(--banx-mint);
  --tok-users-b: #10b874;
  --tok-build-a: var(--banx-group-build);
  --tok-build-b: #17739f;
  --tok-insider-a: var(--banx-amber);
  --tok-insider-b: #c98600;
  /* A violet, not a fourth grey and not the slate this was first. See the note on
   * --banx-group-market in tokens.css for the hue separations that decided it. */
  --tok-market-a: #9d8ec9;
  /* The same value the token carries, said through the token: a literal here
   * would have left --banx-group-market declared and used by nothing. */
  --tok-market-b: var(--banx-group-market);
}

.k-community { stroke: var(--tok-users-a); }
.k-public { stroke: var(--tok-users-b); }
.k-abx { stroke: var(--tok-users-a); }
.k-loyalty { stroke: var(--tok-users-b); }

.k-builders { stroke: var(--tok-build-a); }
.k-treasury { stroke: var(--tok-build-b); }
.k-liquidity { stroke: var(--tok-build-a); }
.k-security { stroke: var(--tok-build-b); }

.k-contributors { stroke: var(--tok-insider-a); }
.k-investors { stroke: var(--tok-insider-b); }

.k-pol { stroke: var(--tok-market-a); }
.k-mm { stroke: var(--tok-market-b); }

.tok-key-row.k-community .tok-key-dot { background: var(--tok-users-a); }
.tok-key-row.k-public .tok-key-dot { background: var(--tok-users-b); }
.tok-key-row.k-abx .tok-key-dot { background: var(--tok-users-a); }
.tok-key-row.k-loyalty .tok-key-dot { background: var(--tok-users-b); }
.tok-key-row.k-builders .tok-key-dot { background: var(--tok-build-a); }
.tok-key-row.k-treasury .tok-key-dot { background: var(--tok-build-b); }
.tok-key-row.k-liquidity .tok-key-dot { background: var(--tok-build-a); }
.tok-key-row.k-security .tok-key-dot { background: var(--tok-build-b); }
.tok-key-row.k-contributors .tok-key-dot { background: var(--tok-insider-a); }
.tok-key-row.k-investors .tok-key-dot { background: var(--tok-insider-b); }
.tok-key-row.k-pol .tok-key-dot { background: var(--tok-market-a); }
.tok-key-row.k-mm .tok-key-dot { background: var(--tok-market-b); }

/* ---- the middle of the ring -------------------------------------------- */
.tok-ring-mid {
  position: absolute;
  left: 50%;
  top: 50%;
  display: grid;
  gap: 2px;
  margin: 0;
  text-align: center;
  transform: translate(-50%, -50%);
}

.tok-ring-mid b {
  color: #ffffff;
  font-family: var(--banx-font-mono);
  font-size: clamp(.8rem, 2.1svh, 1.15rem);
  font-weight: 500;
  letter-spacing: -.01em;
}

.tok-ring-mid span {
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

/* ---- the legend -------------------------------------------------------- */
.tok-side {
  display: grid;
  gap: var(--banx-space-3);
  min-width: 0;
}

/* Four lists, one per group, each headed by its own total. A 2px rule in the
 * group's colour runs down the whole set, so a block of rows is tied to the arc
 * that draws it without repeating the colour on every line. */
.tok-keys {
  display: grid;
  margin: 0;
  padding-left: var(--banx-space-3);
  border-left: 2px solid var(--banx-line);
  list-style: none;
}

.tok-keys.is-users { border-left-color: var(--tok-users-a); }
.tok-keys.is-build { border-left-color: var(--tok-build-a); }
.tok-keys.is-insider { border-left-color: var(--tok-insider-a); }
.tok-keys.is-market { border-left-color: var(--tok-market-a); }

.tok-key-head {
  display: flex;
  gap: var(--banx-space-3);
  align-items: baseline;
  padding-bottom: 2px;
}

.tok-key-head b {
  color: #ffffff;
  font-family: var(--banx-font-display);
  font-size: clamp(.95rem, 2.2svh, 1.25rem);
  font-weight: 700;
  letter-spacing: var(--banx-tracking-display);
}

.tok-key-head span {
  color: var(--banx-muted);
  font-size: clamp(.72rem, 1.45svh, .82rem);
  line-height: 1.25;
}

/* A hairline per row rather than a border on the list: twelve rows with no rule
 * between them read as a paragraph of numbers. */
.tok-key-row {
  display: grid;
  grid-template-columns: 9px 2.6rem minmax(0, 1fr) auto;
  gap: var(--banx-space-3);
  align-items: baseline;
  padding: clamp(2px, .42svh, 6px) 0;
  border-bottom: 1px solid var(--banx-line);
}

.tok-keys > .tok-key-row:last-child { border-bottom: 0; }

.tok-key-dot {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  transform: translateY(-1px);
}

.tok-key-pct {
  color: #ffffff;
  font-size: clamp(.74rem, 1.5svh, .85rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Sized against the viewport's height, like everything else competing for it:
 * twelve rows at a fixed rem were the one part of this section that would not
 * shrink, and they are half its height. */
.tok-key-name {
  color: var(--banx-text);
  font-size: clamp(.74rem, 1.5svh, .85rem);
  line-height: 1.3;
}

.tok-key-pkl {
  color: var(--banx-subtle);
  font-size: var(--banx-text-2xs);
  font-variant-numeric: tabular-nums;
}

/* ---- the footer strip -------------------------------------------------- */
.tok-foot {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--banx-space-3) var(--banx-space-6);
  padding-top: var(--banx-space-4);
  border-top: 1px solid var(--banx-line);
}

.tok-foot-cell { display: grid; align-content: start; gap: 2px; min-width: 0; }

.tok-foot-n {
  margin: 0;
  color: var(--banx-accent-text);
  font-family: var(--banx-font-display);
  font-size: clamp(1.1rem, 2.6svh, 1.7rem);
  font-weight: 700;
  letter-spacing: var(--banx-tracking-display);
  line-height: 1;
}

.tok-foot-l {
  margin: 0;
  color: var(--banx-muted);
  font-size: var(--banx-text-sm);
  line-height: 1.45;
}

.tok-foot-l b { color: var(--banx-text); font-weight: 600; }

.tok-foot-note {
  grid-column: 1 / -1;
  max-width: 96ch;
  margin: 0;
  color: var(--banx-subtle);
  font-size: var(--banx-text-2xs);
  line-height: 1.55;
}

/* A shorter viewport buys its 32px back from the spacing, not from the type.
 * At 1024x720 the section measured 745px, so it grew past the screen and scrolled
 * 25px - which is the right failure and still worth closing. Only the section's
 * own padding and the gaps between its three parts move; every figure and every
 * label keeps the size it has at 900px. */
@media (max-height: 780px) {
  .tok { padding-block: var(--banx-space-4); }
  .tok-inner { gap: var(--banx-space-4); }
}

/* ---- below a desktop --------------------------------------------------- */
/* The ring goes above the legend and the section stops promising one screen: two
 * columns of a round chart and a twelve-row table is a desktop composition, and
 * `min-height` is released rather than fought - twelve rows, four group totals
 * and three footer cells cannot be a phone screen at a legible size, and shrinking
 * them until they are is how the last two versions of this section went wrong. */
@media (max-width: 1023px) {
  .tok { min-height: 0; }
  .tok-chart { grid-template-columns: minmax(0, 1fr); gap: var(--banx-space-6); }
  .tok-ring { max-width: min(100%, 22rem); }
  .tok-foot { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 639px) {
  /* The PKL figure drops to its own line: at 360px it and the allocation name
   * cannot share one without the name wrapping to three. */
  .tok-key-row {
    grid-template-columns: 9px 2.6rem minmax(0, 1fr);
    row-gap: 2px;
  }

  .tok-key-pkl { grid-column: 3; }
}

/* ============================================================== for builders
 * What a builder gets, and nothing about what the chain takes.
 *
 * The headline number sits beside a drawn version of the same claim, because
 * "90%" and a bar that is nine tenths one colour say the same thing to two
 * different readers. The bar grows on arrival through [data-grow] in
 * web/lib/scenes/runtime.js; its rest state is the full width, so with no
 * JavaScript it is simply a filled bar.
 */
.build-keep {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: var(--banx-space-6) var(--banx-space-7);
  align-items: start;
  padding-bottom: var(--banx-space-7);
  border-bottom: 1px solid var(--banx-line);
}

/* Both columns need this, not as a formality: a grid item's default minimum is
 * its content, so a long word in the note or a wide figure would push the track
 * past its share and blow the two-column layout out. */
.build-keep-figure,
.build-keep-body { min-width: 0; }

.build-big {
  margin: 0;
  color: var(--banx-accent-text);
  font-family: var(--banx-font-display);
  font-size: clamp(3.4rem, 8vw, 6rem);
  font-weight: 700;
  letter-spacing: var(--banx-tracking-display);
  line-height: .92;
}

.build-keep-sub {
  max-width: 22ch;
  margin: var(--banx-space-3) 0 0;
  color: var(--banx-muted);
  font-size: var(--banx-text-sm);
  line-height: 1.55;
}

/* Two segments, nine to one, on one hairline track. `transform-origin: left`
 * matters: the grow animation scales these, and scaling from the centre would
 * have the bar open outwards from its middle. */
.build-bar {
  display: grid;
  grid-template-columns: 9fr 1fr;
  gap: 2px;
  height: 10px;
  overflow: clip;
}

.build-bar-fill,
.build-bar-take {
  display: block;
  transform-origin: left center;
}

.build-bar-fill { background: var(--banx-mint); }
.build-bar-take { background: rgb(255 255 255 / 22%); }

.build-bar-legend {
  display: flex;
  gap: var(--banx-space-5);
  margin: var(--banx-space-3) 0 0;
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

.build-bar-legend span::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  vertical-align: 1px;
}

.build-bar-legend .is-keep::before { background: var(--banx-mint); }
.build-bar-legend .is-take::before { background: rgb(255 255 255 / 22%); }

.build-keep-note {
  max-width: 62ch;
  margin: var(--banx-space-4) 0 0;
  color: var(--banx-muted);
  font-size: var(--banx-text-sm);
  line-height: 1.7;
}

/* The four things, as cells on the signature 1px-gap grid. */
.build-gets {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-top: var(--banx-space-7);
  background: var(--banx-line);
  border: 1px solid var(--banx-line);
  border-radius: var(--banx-radius);
  overflow: clip;
}

.build-get {
  display: grid;
  align-content: start;
  gap: var(--banx-space-3);
  padding: var(--banx-space-5);
  background: var(--banx-surface-1);
}

.build-get-figure {
  display: grid;
  gap: 2px;
  margin: 0;
  color: var(--banx-accent-text);
  font-family: var(--banx-font-display);
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1;
}

.build-get-figure small {
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  font-weight: 400;
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

.build-get h3 { font-size: var(--banx-text-base); }

.build-get p {
  margin: 0;
  color: var(--banx-muted);
  font-size: var(--banx-text-sm);
  line-height: 1.6;
}

.build-foot {
  max-width: 60ch;
  margin: var(--banx-space-5) 0 0;
  color: var(--banx-subtle);
  font-size: var(--banx-text-sm);
  line-height: 1.6;
}

@media (max-width: 1023px) {
  .build-keep { grid-template-columns: minmax(0, 1fr); }
  .build-gets { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 639px) {
  .build-gets { grid-template-columns: minmax(0, 1fr); }
}

.flow-table { overflow-x: auto; border: 1px solid var(--banx-line); }
.flow-table table { width: 100%; min-width: 40rem; border-collapse: collapse; }

.flow-table th {
  padding: var(--banx-space-4) var(--banx-space-5);
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  font-weight: 400;
  letter-spacing: var(--banx-tracking-caps);
  text-align: left;
  text-transform: uppercase;
  border-bottom: 1px solid var(--banx-line);
}

.flow-table td {
  padding: var(--banx-space-4) var(--banx-space-5);
  color: var(--banx-muted);
  font-size: var(--banx-text-base);
  vertical-align: top;
  border-bottom: 1px solid var(--banx-line);
}

.flow-table tr:last-child td { border-bottom: 0; }
.flow-table td + td { color: var(--banx-text); border-left: 1px solid var(--banx-line); }

/* --------------------------------------------------------------- migration */

.flow-split {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: var(--banx-space-7);
}

.flow-big {
  color: var(--banx-accent-text);
  font-family: var(--banx-font-display);
  font-size: clamp(3rem, 7vw, 5rem);
  font-weight: 700;
  letter-spacing: var(--banx-tracking-display);
  line-height: 1;
}

.flow-sub {
  margin-top: var(--banx-space-2);
  color: var(--banx-subtle);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
  letter-spacing: var(--banx-tracking-caps);
  text-transform: uppercase;
}

.flow-steps { margin: 0; padding: 0; list-style: none; }

.flow-steps li {
  position: relative;
  padding: var(--banx-space-4) 0 var(--banx-space-4) 3rem;
  color: var(--banx-muted);
  font-size: var(--banx-text-base);
  line-height: 1.6;
  border-bottom: 1px solid var(--banx-line);
}

.flow-steps li .n {
  position: absolute;
  top: var(--banx-space-4);
  left: 0;
  color: var(--banx-accent-text);
  font-family: var(--banx-font-mono);
  font-size: var(--banx-text-2xs);
}

/* --------------------------------------------------------------------- cta */

.flow-cta { text-align: center; }
.flow-cta .flow-inner { justify-items: center; gap: var(--banx-space-5); }
.flow-cta h2 { max-width: 24ch; }
.flow-cta .flow-lede { margin-top: 0; }

.flow-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--banx-space-4);
  justify-content: center;
}

.flow-actions .ex-btn { min-height: 52px; padding-inline: 26px; }

/* The community row, under the two product actions rather than beside them. Four
 * buttons on one line read as four equal choices; these two are a different kind
 * of thing, so they get their own row and a hairline above it. */
.flow-social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--banx-space-3);
  justify-content: center;
  width: min(100%, 44rem);
  margin: var(--banx-space-6) auto 0;
  padding-top: var(--banx-space-6);
  border-top: 1px solid var(--banx-line);
}

.flow-social .ex-btn {
  gap: var(--banx-space-2);
  min-height: 46px;
  padding-inline: 20px;
}

/* ---------------------------------------------------------------- reveals */

html.scenes [data-rise] { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html.scenes [data-rise] { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------- responsive */

@media (max-width: 1023px) {
  .flow-apps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-split { grid-template-columns: minmax(0, 1fr); gap: var(--banx-space-6); }
}

@media (max-width: 699px) {
  .flow-apps { grid-template-columns: minmax(0, 1fr); }
  .flow { padding-block: var(--banx-section-sm); }

  /* The table becomes labelled pairs. `min-width: 40rem` made it a 640px
   * horizontal scroller inside a 375px screen, which is a table nobody reads. */
  .flow-table { overflow-x: visible; border: 0; }
  .flow-table table { min-width: 0; }
  .flow-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .flow-table tr { display: grid; gap: var(--banx-space-3); margin-bottom: var(--banx-space-3); padding: var(--banx-space-4); border: 1px solid var(--banx-line); }
  .flow-table td { display: grid; gap: 2px; padding: 0; border: 0; }
  .flow-table td + td { border-left: 0; }

  .flow-table td::before {
    content: attr(data-label);
    color: var(--banx-subtle);
    font-family: var(--banx-font-mono);
    font-size: var(--banx-text-2xs);
    letter-spacing: var(--banx-tracking-caps);
    text-transform: uppercase;
  }
}
