/* ============================================================
   WHERE ASKPILOT SITS — the execution-layer map.

   Three bands (agents, Askpilot, tools) joined by wires, with
   dots travelling them so the traffic is visible rather than
   described.

   Two rules shaped the build.

   1. Every word is real HTML. The chips and the stage cards are
      list items, not SVG text and not JavaScript output, so a
      crawler reading the raw page gets the whole diagram. The
      wires are empty spans and the dots are empty spans; take
      the CSS away and nothing readable is lost.

   2. No JavaScript, and no fixed pixel canvas. The wires are laid
      out on the same six-column grid as the chips above them, so
      a stub is always under its chip at any width. The only fixed
      dimensions are vertical, which is the one axis that does not
      need to flex.
   ============================================================ */

.xm {
    padding: 88px 0 96px;
    background: var(--cream);
    border-top: 1px solid var(--line);
}
.xm .sec-eyebrow { color: var(--brand-magenta); }
.xm-map {
    --g: 14px;                       /* the gap the grid and the bus share */
    --wire: #E0D9E4;
    --dot-up: var(--brand-blue);     /* something arriving */
    --dot-down: var(--brand-magenta);/* something being done */
    --dot-wait: #C98A1B;             /* stopped, waiting for a person */
    margin-top: 44px;
}

/* ---------------------------------------------------------- bands */
.xm-band-label {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 12px;
    /* a label above a band is fine at the top, where nothing runs into it;
       below the tools it would sit between the stubs and the boxes and cut
       the wires, so that one gets --under and sits after its row */
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted);
}
.xm-band-label--under { margin: 14px 0 0; }
.xm-row {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: var(--g);
    margin: 0;
    padding: 0;
    list-style: none;
}
.xm-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    min-height: 56px;
    padding: 0 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 14px;
    font-size: 0.9375rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--ink);
}
.xm-chip img {
    width: 20px;
    height: 20px;
    flex: none;
    object-fit: contain;
}

/* ---------------------------------------------------------- wires */
/* Two grid rows with a bus between them. Because the rows use the
   same six columns as the chips, every stub lands under its chip
   without a single hard-coded x. */
.xm-wires { position: relative; }
.xm-lane {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: var(--g);
    height: 30px;
}
.xm-lane span {
    position: relative;
    justify-self: center;
    width: 1px;
    height: 100%;
    background: var(--wire);
}
.xm-lane span.is-dashed {
    background: none;
    border-left: 1px dashed var(--wire);
}
.xm-lane span.is-blank { background: none; }

.xm-bus {
    position: relative;
    height: 1px;
    background: var(--wire);
    /* stop at the centre of the first and last column, so the bus
       reads as joining the stubs rather than running off the edge */
    margin: 0 calc((100% - 5 * var(--g)) / 12);
}

/* ---------------------------------------------------------- the layer */
.xm-layer {
    position: relative;
    padding: 24px 24px 26px;
    background: var(--surface);
    /* the same ink border and lift the workflow cards carry, so the layer
       and the cards read as one family. Matches .pl-card in
       how-it-works.css: 1.5px, 22px radius, the same two-part shadow. */
    border: 1.5px solid var(--ink);
    border-radius: 22px;
    box-shadow: 0 1px 2px rgba(22, 18, 26, 0.04), 0 18px 44px -26px rgba(22, 18, 26, 0.20);
}
.xm-layer-name { margin: 0; line-height: 0; }
.xm-layer-name img { height: 26px; width: auto; display: inline-block; }
.xm-layer-kicker {
    margin: 2px 0 20px;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted);
}
.xm-pipe {
    --gp: 34px;                      /* the gap the stage centres are derived from */
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: var(--gp);
    margin: 0;
    padding: 0;
    list-style: none;
}
.xm-stage {
    position: relative;
    padding: 15px 16px 16px;
    background: #FCFBFC;
    border: 1px solid var(--line);
    border-radius: 14px;
}
/* the arrow that makes it a pipeline rather than five tiles */
.xm-stage + .xm-stage::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -30px;
    width: 26px;
    height: 1px;
    background: var(--wire);
}
.xm-stage + .xm-stage::after {
    content: "";
    position: absolute;
    top: 50%;
    left: -10px;
    width: 6px;
    height: 6px;
    border-top: 1px solid var(--wire);
    border-right: 1px solid var(--wire);
    transform: translateY(-50%) rotate(45deg);
}
/* The five stages are a sequence, not five features, so they are numbered.
   An icon per stage said "these are different"; a number says "these happen
   in this order", which is the thing the diagram is for. */
.xm-stage-n {
    display: block;
    margin-bottom: 9px;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    color: var(--brand-magenta);
    font-variant-numeric: tabular-nums;
}

.xm-stage b {
    display: block;
    font-size: 0.9375rem;
    font-weight: 800;
    letter-spacing: -0.015em;
    color: var(--ink);
}
.xm-stage span {
    display: block;
    margin-top: 5px;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.45;
    color: var(--muted);
}
/* A label riding its own wire, positioned rather than in flow — in flow it
   pushed the layer down and left the wire hanging in mid-air. */
.xm-lane--tall { height: 46px; }
.xm-lane em {
    position: absolute;
    display: flex;
    align-items: center;
    gap: 6px;
    left: 13px;
    top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    font-style: normal;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--muted);
}
.xm-lane em.is-right { left: auto; right: 13px; }
.xm-band-label svg, .xm-lane em svg {
    width: 14px;
    height: 14px;
    flex: none;
    opacity: 0.85;
}
/* ---------------------------------------------------------- the circuit */
/* One job, followed the whole way round, rather than dots decorating each
   wire on their own clock. It is a relay: every leg is its own element in
   its own container, but they share one 14s timeline and each is only
   visible during its slice, so the baton passes exactly where one wire
   meets the next.

     1  an event fires in CallSwitch One and climbs its stub
     2  along the bus to the layer's inlet
     3  up into Events in
     4  through the pipeline, waiting at the approval
     5  down out of Actions out
     6  along the bus
     7  into WhatsApp, where the work actually lands
     8  meanwhile a summary leaves through the gate
     9  along the bus
    10  up into Claude

   The colour is the state, not decoration: blue arriving, amber stopped,
   magenta being done. The summary is small, because it is only a summary. */
.xm-map { --cycle: 14s; }
.xm-pipe {
    position: relative;
    --s1: calc(10% - 0.4 * var(--gp));
    --s2: calc(30% - 0.2 * var(--gp));
    --s3: 50%;
    --s4: calc(70% + 0.2 * var(--gp));
    --s5: calc(90% + 0.4 * var(--gp));
}

.xm-leg {
    position: absolute;
    /* the stage cards are position:relative and come later in the DOM, so
       without this the job paints behind them and gets clipped in half */
    z-index: 3;
    width: 8px;
    height: 8px;
    /* pull back by half the dot, so top/left 0% and 100% land its CENTRE on
       the end of the wire rather than its leading edge. Without this every
       job hangs half a dot past the layer's border instead of straddling it. */
    margin: -4px 0 0 -4px;
    border-radius: 50%;
    opacity: 0;
    background: var(--dot-up);
    box-shadow: 0 0 0 4px rgba(76, 107, 238, 0.15);
    animation-duration: var(--cycle);
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}
/* a second job, half a cycle behind, so the map is never empty */
.xm-leg.is-b { animation-delay: calc(var(--cycle) / -2); }

/* on a stub or a pipe, the dot rides the centre line */
.xm-lane .xm-leg { left: 50%; }
/* on a bus, it rides the length */
.xm-bus .xm-leg { top: 50%; }

.xm-leg.L5, .xm-leg.L6, .xm-leg.L7 {
    background: var(--dot-down);
    box-shadow: 0 0 0 4px rgba(213, 59, 213, 0.15);
}
.xm-leg.L8, .xm-leg.L9, .xm-leg.L10 {
    width: 6px; height: 6px; margin: -3px 0 0 -3px;
    box-shadow: 0 0 0 3px rgba(76, 107, 238, 0.13);
}

.xm-leg.L1  { animation-name: xm-l1; }
.xm-leg.L2  { animation-name: xm-l2; }
.xm-leg.L3  { animation-name: xm-l3; }
.xm-leg.L4  { animation-name: xm-l4; }
.xm-leg.L5  { animation-name: xm-l5; }
.xm-leg.L6  { animation-name: xm-l6; }
.xm-leg.L7  { animation-name: xm-l7; }
.xm-leg.L8  { animation-name: xm-l8; }
.xm-leg.L9  { animation-name: xm-l9; }
.xm-leg.L10 { animation-name: xm-l10; }
.xm-leg.B1  { animation-name: xm-b1; }
.xm-leg.B2  { animation-name: xm-b2; }
.xm-leg.C1  { animation-name: xm-c1; }
.xm-leg.C2  { animation-name: xm-c2; }
.xm-leg.C3  { animation-name: xm-c3; }

/* The instruction going the other way. Only the report leg was animated up
   here, so the wire under "describe what to automate" was drawn and never
   used. These are magenta like the down-spine on the Front page, and small
   like the rest of the top row. Placed after the size and colour rules
   above so both land, rather than half of each. */
.xm-leg.B1, .xm-leg.B2,
.xm-leg.C1, .xm-leg.C2, .xm-leg.C3 {
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    background: var(--dot-down);
    box-shadow: 0 0 0 3px rgba(213, 59, 213, 0.13);
}

/* 1 — the event climbs out of the tool it happened in */
@keyframes xm-l1 {
    0%       { top: 100%; opacity: 0; }
    1%       { top: 92%;  opacity: 1; }
    7%       { top: 0%;   opacity: 1; }
    7.6%, 100% { top: 0%; opacity: 0; }
}
/* 2 — along the bus to the inlet. The stop is the third of eight chips,
   which is 2/7 of the way along a bus that runs centre to centre; the old
   round 40% was left over from a shorter row and dropped the job 115px
   away from the stub it had just climbed. */
@keyframes xm-l2 {
    0%, 7%      { left: calc(200% / 7); opacity: 0; }
    7.6%        { left: calc(200% / 7); opacity: 1; }
    15%         { left: 0%;  opacity: 1; }
    15.6%, 100% { left: 0%;  opacity: 0; }
}
/* 3 — up into the layer */
@keyframes xm-l3 {
    0%, 15%     { top: 100%; opacity: 0; }
    15.6%       { top: 100%; opacity: 1; }
    21%         { top: 0%;   opacity: 1; }
    21.6%, 100% { top: 0%;   opacity: 0; }
}
/* 4 — through the pipeline, stage by stage, pausing longest at the approval */
@keyframes xm-l4 {
    0%, 21%   { left: var(--s1);    opacity: 0; background: var(--dot-up);   box-shadow: 0 0 0 4px rgba(76, 107, 238, 0.15); }
    22%       { left: var(--s1);    opacity: 1; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
    29%, 33%  { left: var(--s2); opacity: 1; background: var(--dot-up);   animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
    38%, 44%  { left: var(--s3); opacity: 1; background: var(--dot-up);   box-shadow: 0 0 0 4px rgba(76, 107, 238, 0.15); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
    49%       { left: var(--s4); opacity: 1; background: var(--dot-wait); box-shadow: 0 0 0 5px rgba(201, 138, 27, 0.22); }
    58%       { left: var(--s4); opacity: 1; background: var(--dot-wait); box-shadow: 0 0 0 5px rgba(201, 138, 27, 0.22); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
    63%       { left: var(--s5);   opacity: 1; background: var(--dot-down); box-shadow: 0 0 0 4px rgba(213, 59, 213, 0.15); }
    64%, 100% { left: var(--s5);   opacity: 0; background: var(--dot-down); box-shadow: 0 0 0 4px rgba(213, 59, 213, 0.15); }
}
/* 5 — the action drops out of the layer */
@keyframes xm-l5 {
    0%, 64%     { top: 0%;   opacity: 0; }
    64.6%       { top: 0%;   opacity: 1; }
    70%         { top: 100%; opacity: 1; }
    70.6%, 100% { top: 100%; opacity: 0; }
}
/* 6 — along the bus to the tool it lands in: the fifth of eight chips,
   4/7 along. 80% sat between two chips and handed off 230px short. */
@keyframes xm-l6 {
    0%, 70%     { left: 100%; opacity: 0; }
    70.6%       { left: 100%; opacity: 1; }
    76%         { left: calc(400% / 7); opacity: 1; }
    76.6%, 100% { left: calc(400% / 7); opacity: 0; }
}
/* 7 — into the tool */
@keyframes xm-l7 {
    0%, 76%     { top: 0%;   opacity: 0; }
    76.6%       { top: 0%;   opacity: 1; }
    83%         { top: 92%;  opacity: 1; }
    84%, 100%   { top: 100%; opacity: 0; }
}
/* 8 — the summary leaves, once the approval has cleared */
@keyframes xm-l8 {
    0%, 60%     { top: 100%; opacity: 0; }
    60.6%       { top: 100%; opacity: 1; }
    68%         { top: 0%;   opacity: 1; }
    68.6%, 100% { top: 0%;   opacity: 0; }
}
/* 9 — along the bus */
@keyframes xm-l9 {
    0%, 68%     { left: 60%; opacity: 0; }
    68.6%       { left: 60%; opacity: 1; }
    76%         { left: 0%;  opacity: 1; }
    76.6%, 100% { left: 0%;  opacity: 0; }
}
/* 10 — and up into the agent, where the person sees it */
@keyframes xm-l10 {
    0%, 76%     { top: 100%; opacity: 0; }
    76.6%       { top: 100%; opacity: 1; }
    83%         { top: 8%;   opacity: 1; }
    84%, 100%   { top: 0%;   opacity: 0; }
}

/* B — an instruction from ChatGPT, whose chip sits directly over the wire
   down to the layer, so it never has to touch the bus */
@keyframes xm-b1 {
    0%, 36%     { top: 0%;   opacity: 0; }
    36.6%       { top: 0%;   opacity: 1; }
    42%         { top: 100%; opacity: 1; }
    42.6%, 100% { top: 100%; opacity: 0; }
}
@keyframes xm-b2 {
    0%, 42%     { top: 0%;   opacity: 0; }
    42.6%       { top: 0%;   opacity: 1; }
    50%         { top: 100%; opacity: 1; }
    50.6%, 100% { top: 100%; opacity: 0; }
}

/* C — the same instruction from OpenClaw at the far end, which does have
   the bus to cross. Six chips, so a column sits every 20%. */
@keyframes xm-c1 {
    0%, 44%     { top: 0%;   opacity: 0; }
    44.6%       { top: 0%;   opacity: 1; }
    50%         { top: 100%; opacity: 1; }
    50.6%, 100% { top: 100%; opacity: 0; }
}
@keyframes xm-c2 {
    0%, 50%     { left: 100%; opacity: 0; }
    50.6%       { left: 100%; opacity: 1; }
    57%         { left: 20%;  opacity: 1; }
    57.6%, 100% { left: 20%;  opacity: 0; }
}
@keyframes xm-c3 {
    0%, 57%     { top: 0%;   opacity: 0; }
    57.6%       { top: 0%;   opacity: 1; }
    63%         { top: 100%; opacity: 1; }
    63.6%, 100% { top: 100%; opacity: 0; }
}

/* ---------------------------------------------------------- narrow */
/* The pipeline is five stages wide, so past this the dot's stage centres
   stop meaning anything and the run inside the layer is dropped. */
@media (max-width: 1000px) {
    .xm-pipe { grid-template-columns: repeat(3, 1fr); gap: 30px 34px; }
    .xm-stage:nth-child(4)::before, .xm-stage:nth-child(4)::after { display: none; }
    .xm-leg.L4 { display: none; }
}

/* Below this the horizontal wiring stops working: six chips will not sit on
   one row, so a stub can no longer point at its own chip and a bus has
   nothing to join. Rather than leave rules floating with nothing attached,
   the whole thing turns vertical — one line down the middle, with the labels
   sitting on it. Same story, told in the one direction a phone has room for. */
@media (max-width: 760px) {
    .xm { padding: 60px 0 64px; }
    .xm-map { --g: 10px; }
    .xm-row { grid-template-columns: repeat(2, 1fr); gap: var(--g); }
    .xm-chip { min-height: 50px; padding: 0 11px; font-size: 0.875rem; gap: 7px; }
    .xm-chip img { width: 17px; height: 17px; }

    .xm-lane, .xm-bus, .xm-leg { display: none; }

    .xm-wires {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 9px;
        padding: 18px 0;
    }
    /* the line the labels sit on */
    .xm-wires::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 50%;
        width: 1px;
        margin-left: -0.5px;
        background: var(--wire);
    }
    /* display:contents lifts the labels out of their columns so they can
       stack on the line instead of being positioned against a stub */
    .xm-lane--tall { display: contents; }
    .xm-lane--tall span {
        position: static;
        display: block;
        width: auto;
        height: auto;
        background: none;
        border: 0;
    }
    .xm-lane--tall span.is-blank { display: none; }
    .xm-lane em,
    .xm-lane em.is-right {
        position: static;
        transform: none;
        left: auto;
        right: auto;
        background: var(--cream);
        padding: 0 9px;
    }

    .xm-pipe { grid-template-columns: 1fr; gap: 10px; }
    .xm-stage { padding: 13px 14px 14px; }
    .xm-stage + .xm-stage::before,
    .xm-stage + .xm-stage::after { display: none; }
    .xm-stage-n { margin-bottom: 6px; }
    .xm-layer { padding: 18px 16px 20px; }
    .xm-layer-name img { height: 22px; }
}

/* The tools row holds two per row all the way down, so the agents row does
   too: one wide box per line read as a different component from the grid
   underneath it. The agent names are the short ones in the set, so they fit
   where "CallSwitch One" already does. */
@media (max-width: 480px) {
    .xm-chip { min-height: 46px; }
    .xm-wires { padding: 15px 0; gap: 8px; }
    .xm-lane em, .xm-lane em.is-right { font-size: 0.625rem; letter-spacing: 0.1em; }
}

/* ==========================================================================
   THE LAYER, IN DETAIL
   Moved here from css/front-proposal.css so the home page and the proposal
   page draw the same diagram from one source instead of two copies.
   ========================================================================== */

@keyframes fp-spine-down { from { top: -4%; } to { top: 104%; } }

@keyframes fp-spine-up   { from { top: 104%; } to { top: -4%; } }

/* Chips on this page centre their contents. With one chip on top and seven
   below, left-aligned marks made a ragged edge down the row. */
.xm .xm-chip { justify-content: center; }

/* A brace under the five stages saying they are one thing, not five. The
   ticks rise toward the cards so it reads as gathering them up. */
.fp-span {
    position: relative;
    margin: 20px 0 0;
    text-align: center;
}

.fp-span::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 50%;
    height: 9px;
    border: 1px solid var(--wire);
    border-top: 0;
}

.fp-span span {
    position: relative;
    background: var(--surface);
    padding: 0 14px;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--muted);
}


@media (max-width: 760px) {
    .fp-span { margin-top: 16px; }
    .fp-span span { font-size: 0.625rem; letter-spacing: 0.1em; }
}

/* ---------------------------------------------------------- eight boxes *//* Scheduled run joins the row as a box: it is a way in, like the tools, so
   it should look like one. Eight columns, first in line beside the events
   pipe. It carries a clock instead of a logo, because it is the clock. */
.xm-row--8,
.xm-lane--8 { grid-template-columns: repeat(8, 1fr); }

.xm-bus--8 { margin: 0 calc((100% - 7 * var(--g)) / 16); }

.xm-row--8 .xm-chip {
    font-size: 0.75rem;
    padding: 0 8px;
    gap: 6px;
    line-height: 1.25;
}

.xm-row--8 .xm-chip img { width: 17px; height: 17px; }

.fp-chip-alt { color: var(--body); }

.fp-chip-ico {
    display: grid;
    place-items: center;
    width: 17px;
    height: 17px;
    flex: none;
    color: var(--muted);
}

.fp-chip-ico svg { width: 15px; height: 15px; display: block; }


@media (max-width: 760px) {
    .xm-row--8 { grid-template-columns: repeat(2, 1fr); }
}

/* A band over the five, so they read as one workflow rather than five
   separate things. Paired with the brace underneath: the band names it,
   the brace closes it. */
.fp-band {
    position: relative;
    margin: 0 0 14px;
    padding: 9px 14px;
    background: var(--pink-wash);
    border: 1px solid var(--pink-surface);
    border-radius: 12px;
    text-align: center;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--brand-magenta);
}

/* One tick per card rather than one from the band: a single centred tick
   read as "this band belongs to column two". Each card draws its own, so
   it stays centred on that card at any width. */
.fp-tick {
    position: absolute;
    left: 50%;
    top: -14px;
    width: 1px;
    height: 14px;
    background: var(--pink-surface);
}

/* ------------------------------------------------- the session, expanded *//* Approvals, integrations, tools and events are not steps after the session;
   they happen inside it. Nesting them makes that relationship explicit. */
.xm-pipe--nest {
    grid-template-columns: minmax(0, 290px) 1fr;
    gap: 26px;
    align-items: stretch;
}

.xm-pipe--nest > .xm-stage:last-child {
    display: flex;
    flex-direction: column;
    background: #FBFAFC;
}

.fp-sub {
    position: relative;
    display: grid;
    --sg: 12px;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--sg);
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
}

.fp-sub-card {
    background: var(--surface);
    border-color: var(--line);
}

/* they are two things the session does, not a sequence, so no arrow */
.fp-sub .xm-stage + .xm-stage::before,
.fp-sub .xm-stage + .xm-stage::after { display: none; }

/* The run, stepping the whole sequence: trigger, session, then each thing
   the session uses, then done. Seven markers on one 14s clock, each lit for
   its own two seconds. A single moving dot could not do this — the outer
   row and the nested row are separate coordinate systems, so it could only
   ever travel one of them. Colour carries the state: blue arriving, amber
   waiting on a person, magenta acting, green finished. */
.fp-mark {
    position: absolute;
    top: -5px;
    left: 50%;
    width: 10px;
    height: 10px;
    margin-left: -5px;
    border-radius: 50%;
    background: var(--c);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 18%, transparent);
    opacity: 0;
    animation: fp-mark 14s linear infinite;
    animation-delay: calc(var(--i) * 2s - 14s);
}

@keyframes fp-mark {
    0%        { opacity: 0; transform: scale(0.5); }
    3%        { opacity: 1; transform: scale(1); }
    14%       { opacity: 1; transform: scale(1); }
    17%, 100% { opacity: 0; transform: scale(0.5); }
}


@media (prefers-reduced-motion: reduce) {
    /* park on the approval, the one moment the run deliberately stops */
    .fp-mark { animation: none; opacity: 0; }
    .fp-mark[style*="--i:2"] { opacity: 1; transform: none; }

    /* the relay parks too, rather than vanishing: one job resting on each
       wire still says the wires carry something. */
    .xm-leg { animation: none; opacity: 1; }
    .xm-lane .xm-leg { top: 50%; }
    .xm-bus .xm-leg { left: 50%; }
    /* the twins, and the second job on a shared wire, would park in exactly
       the same spot as the first */
    .xm-leg.is-b,
    .xm-leg.L6,
    .xm-leg.C2,
    .xm-leg.C3 { display: none; }
}


@media (max-width: 900px) {
    .xm-pipe--nest { grid-template-columns: 1fr; gap: 14px; }
}


@media (max-width: 1100px) {
    .fp-sub { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
    .fp-sub { grid-template-columns: 1fr; }
}

/* the nested pair are not steps in a sequence, so they carry a word rather
   than a number */
.fp-sub-card .xm-stage-n { text-transform: uppercase; }

/* a third column for the end state: the session closes and moves to Done.
   The two end columns share a cap, so the step that opens the run and the
   step that closes it read as a matched pair around the session. */
.xm-pipe--nest { grid-template-columns: minmax(0, 180px) 1fr minmax(0, 180px); }

.fp-done { align-self: stretch; }


@media (max-width: 900px) {
    .xm-pipe--nest { grid-template-columns: 1fr; }
}

/* the nested pair sit a level down, so their titles sit back a shade too */
.fp-sub-card b { color: var(--muted); }

/* ==========================================================================
   NARROW
   Three things break when the room goes: the two wires run their labels off
   both edges, the ticks point up at a band that is no longer above them, and
   a horizontal brace cannot gather a column of stacked cards.
   ========================================================================== */
@media (max-width: 900px) {
    /* the cards stack, so the brace turns and runs down their left side */
    .xm-layer {
        display: grid;
        grid-template-columns: 22px 1fr;
        column-gap: 12px;
    }
    .xm-layer-name,
    .xm-layer-kicker,
    .fp-band { grid-column: 1 / -1; }
    .xm-pipe { grid-column: 2; grid-row: 4; }
    .fp-span {
        grid-column: 1;
        grid-row: 4;
        margin: 0;
        writing-mode: vertical-rl;
        transform: rotate(180deg);
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .fp-span::before {
        left: auto;
        right: 0;
        top: 0;
        bottom: 0;
        width: 9px;
        height: auto;
        border: 1px solid var(--wire);
        /* the label is rotated 180deg, which mirrors its borders: dropping
           the LEFT one is what leaves the ticks pointing right, at the cards */
        border-left: 0;
    }
    .fp-span span { background: var(--surface); padding: 12px 0; }
    /* the band sits above a stack now, so per-card ticks point at nothing */
    .fp-tick { display: none; }
}

/* Stacked, the eight boxes read as a loose pile; a border gathers them back
   into one band, which is what the horizontal row did on its own. */
@media (max-width: 760px) {
    .xm .xm-tools,
    .xm .xm-agents:not(.xm-row--one) {
        padding: 12px;
        border: 1px solid var(--line);
        border-radius: 16px;
    }
}

/* "MCP" set beside the wordmark rather than inside it: the logo is a fixed
   asset, so the word rides next to it at the mark's own optical size. */
.xm-layer-name { display: flex; align-items: center; gap: 9px; }

.fp-mcp {
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--ink);
    line-height: 1;
    position: relative;
    /* the wordmark's baseline sits a hair above the box centre, so the word
       beside it comes up to meet it */
    top: -1px;
}


@media (max-width: 760px) {
    .fp-mcp { font-size: 1.0625rem; }
}

/* the layer's own name sits centred over the row it heads */
.xm .xm-layer-name { justify-content: center; }

.xm .xm-layer-kicker { text-align: center; }

/* The Events in / Actions out pair, given the same treatment as the two
   wires above the layer: one down each side rather than both stacked on a
   single spine. In on the left, out on the right, top and bottom alike. */
@media (max-width: 760px) {
    .xm .xm-wires:not(.xm-wires--v) {
        flex-direction: row;
        align-items: stretch;
        justify-content: center;
        gap: 0;
        padding: 0;
    }
    .xm .xm-wires:not(.xm-wires--v)::before { display: none; }
    .xm .xm-wires:not(.xm-wires--v) .xm-lane--tall span:not(.is-blank) {
        position: relative;
        display: block;
        flex: 1;
        width: auto;
        height: 92px;
        background: none;
        border: 0;
    }
    .xm .xm-wires:not(.xm-wires--v) .xm-lane--tall span:not(.is-blank)::before {
        content: "";
        position: absolute;
        left: 50%;
        top: 0;
        bottom: 0;
        width: 1px;
        background: var(--wire);
    }
    .xm .xm-wires:not(.xm-wires--v) em,
    .xm .xm-wires:not(.xm-wires--v) em.is-right {
        position: absolute;
        top: 50%;
        left: 50%;
        right: auto;
        transform: translate(-50%, -50%);
        /* left:50% with no right leaves only half the lane as available
           width, so the label shrank to 86px and broke over four lines.
           max-content asks for the whole label, then max-width reins it
           back to the lane, less a hair so the pair never touch. */
        width: max-content;
        max-width: 96%;
        white-space: normal;
        text-align: center;
        justify-content: center;
        flex-wrap: wrap;
        line-height: 1.4;
        background: var(--cream);
        padding: 4px 6px;
    }
}

/* the travelling dot; the .fp-mark anchors go quiet once it exists */
.has-runner .fp-mark { visibility: hidden; animation: none; }

.fp-runner {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 4;
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    border-radius: 50%;
    background: var(--brand-blue);
    box-shadow: 0 0 0 4px rgba(22, 18, 26, 0.06);
    pointer-events: none;
}
