/* Invoicing & Receivables (/platform/accounts-receivable) — page-specific graphic styles.
   Hero is NOT 100vh on this page — the source file's `.hero.hero-100vh` block is deliberately
   NOT carried over. */


/* =============================================================
   HERO ILLO 1 — the Aion dashboard's Receivables card, recreated
   in HTML/CSS, and NOTHING AROUND IT: `.arv-screen` is the card,
   not a screen holding one, so there is no app top bar and no
   sparkle FAB. `.bkv` / `.crv` frame a whole app screen and keep
   their chrome; this illo is one card, deliberately. Construction
   is still theirs: `container-type: inline-size` on `.arv` + a
   cqi-driven root font-size on `.arv-screen` — the CHILD, never the
   container itself; see the note on that rule — every dimension in
   `em`, so the card scales with the hero column instead of being
   cropped by object-fit.

   Structure mirrors aion-react Dashboard/Cards/ARAging.js —
   CardHeader (icon, Receivables / Outstanding invoices, the
   outstanding total and a View invoices link), then ARAgingChart
   (five age bands) and ARAgingCustomer (largest balances).

   THE CARD CAME FROM #how's INVOICE-BUILDER LOOP, whose fourth
   phase handed off to it before that phase was removed. Same
   composition as there — chart left, customer list right, hairline
   between — and close to the same aspect (~1.7:1). What is NOT the
   same is the construction: there it was absolutely placed on a
   95em x 55.5em stage, and here it is flow/flex all the way down,
   because absolute `em` coordinates would overflow as the hero
   column changes width — the root font-size clamps at 7.6px, so
   this card measures ~76em wide at a 1440 viewport and ~99em once
   the hero stacks at 1024.

   Values, band colours and the outstanding total are the ported
   card's, unchanged. Bar heights are value / 211.6k, the scale
   the original's hand-placed bar heights encoded.
   ============================================================= */
  /* ---- HERO COLUMN — left at the shared-head default, deliberately.
     It was widened to `1fr 1.1736fr` with a 40px `var(--s-10)` gap on 2026-08-10
     (a 621.95px illo column) and REVERTED the same day. The column is back to the
     shared head's own `1fr 1.05fr` + 64px `var(--s-16)`: 577.75px at 1440, 48.5%
     of the 1192px content box — the "50% width" this hero was designed around. This
     illo always filled its column, so the revert costs it the least of the three
     (it had gained only 7.7%).

     WHAT IS NOT REVERTED IS THE EQUALITY. All three illos are `width: 100%` of that
     column, so banking / accounts-receivable / lending-overview stay exactly the
     same width as each other at every width — which is why `.bkv`/`.crv` keep the
     `width: 100%` that replaced their `clamp(360px, 36vw, 548px)`, and why none of
     the three has a stacked max-width. Restoring one would re-break it.

     Widening the column was tried as the way to make these illos read better and
     is NOT it — the type scale is, and here it was genuinely too small: see the
     font-size note below, which is where this page's actual legibility fix lives.
     instruction.md, "Bigger section-1 illos", records the rejected widths. ---- */
  /* ---- ...and the stacked path needs this to keep the three illos equal.
     `.hero` is `display: flex`, so the hero `.container` is a SHRINK-TO-FIT flex
     item: with no definite width it sizes to its own max-content. Above 1080 that
     is invisible, because all three pages' content wants more than the 1240px
     max-width and every container clamps to 1240. Below 1080, where the grid is a
     single column, each page shrink-wrapped to a DIFFERENT width — measured at
     1080: banking 1032px, lending 972.36px, and THIS page just 795.02px, which
     then pinned at 720px from 960 down while the other two tracked the viewport.
     Since each illo is `width: 100%` of that container, they inherited the
     disagreement. `width: 100%` gives the container a definite width so all three
     agree at every stacked width; only ≤768px matched before.

     NOTE THE SIDE EFFECT ON THIS PAGE: its stacked hero was the narrowest of the
     three, so this widens the hero text measure on tablet (up to 1032px at 1080)
     rather than leaving it shrink-wrapped at 768. That is the cost of the illos
     being the same width at every width, and it was accepted deliberately. ---- */
  @media (max-width: 1080px) {
    .hero-grid { width: 100%; }
  }

  .arv {
    container-type: inline-size;
    /* Unchanged — this illo always filled its column, which is why widening the
       column is the whole of its size change. Now 621.95px at 1440. */
    width: 100%;
    font-family: var(--font-data), 'IBM Plex Sans', system-ui, sans-serif;
    line-height: 1.4;
    color: var(--dark-text, #E8E8F0);
    -webkit-font-smoothing: antialiased;
  }
  /* Chrome, radius, padding and hover are copied verbatim from `.bkv-screen` /
     `.crv-screen` so the three hero illos read as the same window.

     NO SHARED ILLO HEIGHT — deliberate, and the one place this illo parts from
     `.bkv-screen` / `.crv-screen`, which both carry
     `min-height: calc(100cqw * 0.926)` so the three heroes are the same box at
     every width. Those two frame a whole app SCREEN, which is as tall as the
     viewport gives it. This one is a single CARD, and the card has proportions
     of its own: ~1.7:1, the shape it had inside the builder loop. Forcing it to
     0.926 of its width made a near-square box that nothing in it wanted to
     fill — the chart stretched to a portrait, the customer rows spread to a
     ~61px pitch, and the card read as mostly air. Height now comes from the
     content, so the card lands at its own aspect and the hero column keeps the
     slack instead. */
  /* ---- THE OUTER CARD (2026-08-10) ----------------------------------------
     The framed surface both cards sit inside — same frame as `.crv-screen`
     (lending-overview) and `.bkv-frame` (banking), so the three hero illos are one
     family: gradient, hairline, 1.2em radius, the deep drop shadow, and a flex
     column whose `gap` is the rhythm between the two cards. `.arv-kpi`'s own
     `margin-bottom: 1.15em` was removed in favour of that gap — keeping both
     double-spaced the pair.

     THE TYPE SCALE LIVES HERE, which retires a trap rather than moving it: the
     declaration used to read `.arv-screen, .arv-kpi`, naming the KPI card only
     because it is a SIBLING of `.arv-screen` and inherited nothing from it. Both are
     children of the frame now, so they inherit like anything else. `cqi` still
     resolves against `.arv`, the `container-type` element, so the scale is
     unchanged — verified 11.5550px before and after. See the long note on
     `.arv-screen` for why it can never sit on `.arv` itself. */
  /* ============================================================================
     THE 3D CARD STACK (2026-08-20) — replaces `.arv-frame` and `.arv-screen`
     ============================================================================
     WHAT THIS REPLACED. `.arv-frame` was an outer card holding a full-width
     `.arv-kpi` strip above `.arv-screen`, which was itself an `.arv-dgrid` of the
     AR Aging chart and the customer list separated by an `.arv-dvr` hairline. The
     KPI and the chart are now ONE card and the customer list is a SECOND card
     resting on its bottom-right — the third page to take this treatment, after
     banking's `.bkv` and lending-overview's `.crv`.

     THE MAPPING TO banking IS EXACT, which is why the split fell this way: its
     front card is a KPI over a chart and its back card is a four-row list. Here the
     base card is the outstanding balance over the aging chart and the top card is
     the four largest customers. Nothing was invented and nothing was cut.

     THE LAYERS. Four things want to transform the same card, so each owns one:
       .arv-stack  the scene: position context, height, THE TYPE SCALE, the 50em box
       .arv-pos    absolute placement                            (`transform` on hover)
       .arv-float  RETIRED — was the continuous idle drift        (`transform`)
       .arv-card   the pointer-follow 3D tilt                    (`transform`)
                   the reveal entrance                           (`translate`)
                   the hover grow                                (`scale`)
     `perspective()` is a FUNCTION inside `.arv-card`'s own transform rather than a
     property on an ancestor, so each card's 3D is self-contained and the two
     2D wrappers above it cannot flatten it. No `transform-style: preserve-3d`.

     THE CARDS DO NOT ROTATE. banking and lending both dropped their resting 2D
     rotation, their standing 3D tilt and the drift's rotate term on 2026-08-20;
     this illo never had them. Depth is the overlap, the shadows and the surface
     brightness. `--rx`/`--ry` are still declared at 0 and `transform` is still
     declared — see the note on `.arv-card`.
     ============================================================================ */
  .arv-stack {
    /* THE TYPE SCALE, moved here from `.arv-frame`. Unchanged in value, and it still
       has to live one level inside `.arv`: `cqi` on the `container-type` element
       ITSELF resolves against the next container out, and with none, the viewport.
       This page's long note on that bug is above; the shape is the same. */
    font-size: clamp(7px, 2cqi, 12.5px);
    position: relative;
    /* THE 50em BOX IS DECLARED, NOT ASSUMED — the same load-bearing line
       `.bkv-stack` and `.crv-stack` carry. `2cqi` makes the box a constant 50em
       only while the coefficient governs; above a 625px container it passes the
       12.5px ceiling and the type pins, so at the 1080 and 768 stacked widths `.arv`
       measures 82.56em and 57.60em. A `width: 100%` card did not care — extra width
       was just room. A composition whose every offset is `em` cares completely: the
       cards would draw at their designed size and leave the rest as dead space on
       one side. Not self-referential: the font-size resolves against `.arv`'s inline
       size, not against this width. */
    width: 50em; max-width: 100%; margin-inline: auto;
    /* 39em = 451px at 1440, against the 370.39px the framed version measured. The
       hero column has ~420px here — much less than banking's 519 or lending's 653,
       because this page's text column is short (a 2-line headline and four lines of
       body). `.hero` is still `min-height: 100vh` at 813px, so the grid can grow to
       ~700px before the hero does; 31em stays under the current 420px anyway and
       leaves the page height untouched. Set by the top card's bottom edge. */
    height: 39em;
  }
  /* the depth wash — cards.html's `.hc-glow`. Two dark cards on a dark hero read as
     flat cutouts without something behind them. */
  .arv-glow {
    position: absolute; inset: 5% 3% 8%;
    background: radial-gradient(58% 58% at 44% 50%,
      rgba(108,92,231,0.28), rgba(64,110,255,0.12) 48%, transparent 74%);
    filter: blur(2.6em);
    z-index: 0; pointer-events: none;
  }

  /* ---- LAYER 1 — placement -------------------------------------------------
     No rotation, so each card's bounding box IS its card box and the geometry reads
     straight off these declarations:
       back  main 33   x 26.3em -> x  0.90..33.90, y 12.40..38.69
       front list 22.5 x 17.8em -> x 26.60..49.10, y  1.00..18.83
     Both clear 0 and 50 in x, and 38.69 set the stack height.

     THE CUSTOMER CARD IS ON TOP, sitting over the chart card's UPPER-RIGHT — and
     that spot is the reason this arrangement gives a large overlap for free.

     THE CHART CARD'S TOP-RIGHT QUADRANT IS EMPTY. Its content is the KPI label
     (ends x 18.93), the KPI value (ends x 16.56) and the chart title, all
     left-aligned, and then the plot — which starts 11.84em below the card's top
     edge. So `x 26.60..33.90` down to the plot is bare card: no text, and not even a
     gridline, since the first sits a further 2.75em down. That is where the customer
     card lands, and it is why the overlap costs nothing.

     THE OVERLAP IS 7.3 x 6.43em — 24.5% OF THE BACK CARD'S HEIGHT, and that ceiling
     is the spec: no more than a quarter. It was 13.13em (50%) for one build, which
     buried half the chart card behind the list. `top: 1.0em` on the list and
     `12.4em` on the chart is the pair that lands 6.43 of 26.29em.
     THE WHOLE COMPOSITION MOVED UP 4.5em WITH IT. Raising only the list card would
     have left 5.5em of dead space above the stack, since the list is the topmost
     thing in it; both cards shifted so the composition still starts at y 1.0.

     Every aging band, tick and value label is clear at every width, and so are all
     four customer rows — verified in both directions. That matters most for the
     chart: `.arv-kpi-v` must equal the five `.arv-bv` labels summed, so hiding one
     band would leave four totalling $391,100 under a $412,600 headline, which a
     reader can see is wrong. (The four customer balances sum to $320,750 and that
     figure appears nowhere, so the list is the cheaper card to cover — but here
     neither has to be.)

     TWO NUMBERS BIND, and they pull in opposite directions:
       * the overlap must stay under 25% of the back card's height — 6.57em;
       * the customer card's bottom (y 18.83) must clear the plot's top (y 24.24),
         and it does by 5.41em, with the first gridline a further 2.75em below.
     Re-derive both if the KPI grows, the chart title changes or `.arv-plot`'s 11em
     height moves — all three shift the plot relative to the card's top edge.

     A measurement note for whoever re-checks it: measure the tick's GLYPH rect, not
     its element box. A tick is a 1/5 flex column with centred text, so its box is
     ~6em wide against 1.71em of glyphs, and a box-based check reports it covered
     when the text is nowhere near. ---- */
  .arv-pos {
    position: absolute;
    transition: transform .55s cubic-bezier(.22,.61,.36,1);
  }
  .arv-pos-main { top: 12.4em; left:  0.9em; width: 33em;   z-index: 1; }
  .arv-pos-list { top:  1.0em; left: 26.6em; width: 22.5em; z-index: 2; }
  .arv-pos:hover { z-index: 20; }
  .arv-pos:hover { transform: translateY(-1.1em); }

  /* ---- LAYER 2 — RETIRED (2026-09-21) --------------------------------------
     THE IDLE DRIFT IS GONE, here and on the other five hero illos, in one pass.
     It was two out-of-phase cycles with no rotate term, paused under the cursor
     so the pointer tilt had a still target:
       .arv-float    arv-floatA  6.0s               translateY(-0.90em)
       .arv-float-b  arv-floatB  7.2s, delay -2.4s  translateY(-1.30em)
     THE WRAPPERS STAY IN THE MARKUP and now declare nothing, so restoring the
     drift is re-adding this block and its keyframes and nothing else. Do not
     fold them out of the DOM: layer 3 owns `transform` for the tilt and layer 1
     for the hover lift, so a returning drift has nowhere else to live. ---- */

  /* ---- LAYER 3 — the card itself ------------------------------------------- */
  .arv-card {
    position: relative;
    /* the glow pseudos and the sheen are all `inset` on a rounded box */
    overflow: hidden;
    border-radius: 1.2em;
    padding: 1.3em 1.4em;
    display: flex; flex-direction: column;
    /* `perspective()` in em keeps the foreshortening proportional — 62em is 716px at
       1440, cards.html's 720px. `transform` is the TILT and nothing else; the
       entrance rides `translate` and the hover `scale`. */
    transform: perspective(62em) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
    transition: transform .18s ease-out,
                scale .35s cubic-bezier(.22,1,.36,1),
                box-shadow .4s ease, border-color .4s ease;
    will-change: transform;
  }
  /* THE RESTING TILT IS ZERO and stays DECLARED, exactly as on banking and lending.
     The pointer script reads both properties once at init and returns to them on
     mouseleave, so a standing tilt is a one-line change back. More importantly,
     `transform` is what makes `.arv-card` a stacking context, which is what gives
     `.arv-sheen`'s `z-index: -1` its meaning — delete the declaration rather than
     zeroing the angles and the sheen drops behind the card background and vanishes. */
  .arv-main     { --rx: 0deg; --ry: 0deg; }
  .arv-listcard { --rx: 0deg; --ry: 0deg; }

  /* Surfaces differ by DEPTH: the base card keeps the brighter surface and the
     shallower shadow because it is the hero and it is the thing on the table; the
     top card gets the longer shadow, which is what says it is above. Same call as
     lending's funds/side pair. */
  .arv-main {                                  /* z 1 — behind, bottom-left */
    background: linear-gradient(158deg, #201D42 0%, #191635 55%, #14112A 100%);
    border: 1px solid rgba(255,255,255,0.13);
    box-shadow: 0 1.5em 3.0em rgba(0,0,0,0.42), 0 0.4em 1.0em rgba(0,0,0,0.26);
  }
  .arv-listcard {                              /* z 2 — on top, upper-right */
    background: linear-gradient(158deg, #1C1940 0%, #161335 55%, #121029 100%);
    border: 1px solid rgba(255,255,255,0.115);
    box-shadow: 0 2.8em 5.6em rgba(0,0,0,0.62), 0 0.7em 1.6em rgba(0,0,0,0.42);
  }
  .arv-pos:hover .arv-card {
    scale: 1.025;
    border-color: rgba(167,139,250,0.34);
    box-shadow: 0 3.2em 6.4em rgba(0,0,0,0.60), 0 0 3.4em rgba(108,92,231,0.20);
  }

  /* Cursor-tracking glows, from cards.html's `.hc-card::after/::before`. `::after`
     is a soft wash under the pointer; `::before` a rim lighting the border nearest
     it via a two-layer mask that xors the padding box out of the border box. */
  .arv-card::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%),
      rgba(196,181,253,0.09) 0%, transparent 52%);
    opacity: 0; transition: opacity .4s ease; pointer-events: none; z-index: 4;
  }
  .arv-card::before {
    content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%),
      rgba(167,139,250,0.65) 0%, transparent 55%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: 0; transition: opacity .4s ease; pointer-events: none; z-index: 5;
  }
  .arv-pos:hover .arv-card::after,
  .arv-pos:hover .arv-card::before { opacity: 1; }

  /* ---- THE PERIODIC SHEEN — identical to `.bkv-sheen` / `.crv-sheen`; keep the
     three in step. A soft band crosses each card once every 7s, the base card first
     and the top card 1.1s behind, so the pair reads as one slow wave. Four things
     are load-bearing and they are documented in full under banking in
     instruction.md ("THE PERIODIC SHEEN — both card stacks"): it passes BEHIND the
     content on `z-index: -1` (which needs the card's `transform` for its stacking
     context); the band is LIGHT because these cards are dark; the travel is LINEAR
     over 30% of the cycle; and it RESTS OFF the card, which is the whole of the
     reduced-motion story. A real span, not a pseudo, because both pseudos are spent
     on the cursor glows. ---- */
  .arv-sheen {
    position: absolute; z-index: -1; inset: -40% -12%;
    pointer-events: none;
    background: linear-gradient(105deg,
      rgba(196,181,253,0) 30%, rgba(196,181,253,0.10) 50%, rgba(196,181,253,0) 70%);
    transform: translateX(-130%);
  }
  @media (prefers-reduced-motion: no-preference) {
    .arv-sheen { animation: arv-sheen-sweep 7s linear infinite; }
    /* the wave runs left to right, so the chart card (x 0.90) leads the list card
       (x 26.60) — spatial order, not DOM order */
    .arv-main     .arv-sheen { animation-delay: 0s; }
    .arv-listcard .arv-sheen { animation-delay: 1.1s; }
  }
  @keyframes arv-sheen-sweep {
    0%   { transform: translateX(-130%); }
    30%  { transform: translateX(130%); }
    100% { transform: translateX(130%); }
  }

  /* THE KPI LOST ITS SURFACE (2026-08-20). It was a CARD — its own gradient,
     hairline, 1.2em radius, drop shadow and 1.3em padding — because it sat as a
     separate strip above `.arv-screen` inside `.arv-frame`. It is now the top block
     of the base card's own content, so a second bordered box inside that card just
     drew a frame around the number for no reason. What is left is the stacking and
     the rhythm to the chart under it. */
  .arv-kpi {
    display: flex; flex-direction: column;
    margin-bottom: 1.5em;
  }
  .arv-kpi-l { font-size: 0.86em; text-transform: uppercase; letter-spacing: 0.11em;
    color: var(--dark-text-tertiary, #8A8FA8); }
  /* 3.375em is the SAME COMPUTED SIZE as banking's `.bkv-total` and lending's
     `.crv-hero` at every width — all three hero illos sit in the same 1.05fr column
     on the same `clamp(7px, 2cqi, 12.5px)` root over a declared 50em box, so their
     big KPI reads at one size across the three pages. It was 2.45em (28.3px at 1440)
     against their 39.0px. NOTE lending reaches 3.375 as `2.5em` inside a card that
     carries `font-size: 1.35em`; here, as on banking, there is no card scale and the
     3.375 is spent directly. Do not "align" this to lending's 2.5em. */
  .arv-kpi-v { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-size: 3.375em; font-weight: 700; letter-spacing: -0.032em; line-height: 1.08;
    margin-top: 0.3em; font-variant-numeric: tabular-nums; white-space: nowrap;
    color: var(--dark-text, #E8E8F0); }

  /* GONE WITH THE HEADER (2026-08-10), markup and CSS: `.arv-dh` (CardHeader row),
     `.arv-dic` (the neutral icon chip — it was deliberately NOT purple, per
     AION_ICONOGRAPHY reserving purple icons for the sparkle system), `.arv-dh-t`,
     `.arv-dh-r`, `.arv-cap-t`, `.arv-cap-s`, `.arv-dkpi`, `.arv-dkpi-v`,
     `.arv-dlink`, `.arv-drule`, and `.arv-ph` — the Phosphor helper, whose only two
     users were that icon and the link's arrow. (`.arv-ph`'s note is worth keeping
     if any Phosphor glyph returns here: Phosphor Regular is NOT stroked, it is a
     FILLED compound path on a 256 viewBox, so `fill:none; stroke:…` renders
     nothing at all.) The `@container (max-width:470px)` block's `.arv-dh-r`
     hide is gone with them, which empties that rule of everything but the layout
     switch. */
  /* the two panes side by side, as the ported card had them, with the hairline
     between them as a 1px grid TRACK so it spans whatever the taller pane is.
     minmax(0,…) on both so a long customer name ellipsises instead of widening
     its column and squeezing the chart. The grid takes the card's leftover
     height, and each pane stretches to it. */
  /* Customer track 0.82fr → 0.90fr → 0.96fr. The first step, with the row text
     going 1.12em → 1.06em, is what let the card adopt banking's larger root
     font-size (the longest name went from −10px to +11.2px against its track).
     0.96fr was measured then and REJECTED for making the list nearly as wide as the
     chart — reversed on 2026-08-10 because `.arv-frame` changed the arithmetic:
     the outer card's padding took ~37px off this grid and the name went to −7.2px.
     Trimming this card's doubled padding plus 0.96fr puts it at **+10.0px**, and
     the chart pane is still the wider of the two (1fr vs 0.96fr), which was the
     actual objection. Measured alternatives: 0.90fr at the same padding is −0.7px,
     and 1.02fr is +13.5px but makes the list wider than the chart. */
  /* `.arv-dgrid` and `.arv-dvr` are GONE (2026-08-20) — they were the two-column
     grid and the hairline that divided the chart from the customer list inside one
     card. The list is its own card now, and two cards need no rule between them.

     THE CHART IS FULL WIDTH, and the BASE CARD is what gives way instead. It was
     capped at `max-width: 19em` for one build so the five bands cleared the top
     card's corner inside a 33em base card. Asked to run full width, the cap could
     not simply be dropped: a 30.2em plot puts the "90+" tick's right edge at x 30.34
     and the top card needs ~21.5em of the 50em box, so there was nowhere left to put
     it. The base card went 33 -> 28em instead. That is the same amount of chart the
     cap was allowing (25.2em of plot against 19em), spent on a narrower card rather
     than clipped inside a wider one.
     WHAT MAKES THE SMALL OVERLAP SAFE is that a bar column is mostly empty: bars are
     28% of their column and centred, so in a 25.2em plot the last column runs to
     x 27.5 but its bar and its "90+" tick end at ~25.8. The top card starts at 26.4,
     so it covers the tail of the gridlines and the axis rule — hairlines — and no
     bar, no value and no tick. Re-derive that if the plot's column count or the
     bar width changes. */
  .arv-chart { flex: 0 0 auto; }
  .arv-dsec { display: flex; flex-direction: column; min-height: 0; }
  .arv-dct { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-size: 1.2em; font-weight: 600; color: var(--dark-text, #E8E8F0); }

  /* ---- AR Aging (ARAgingChart) — an ORDINAL scale (age bands), so one hue
          stepped light -> dark, not five unrelated hues. Validated on this
          surface: monotone L, all adjacent gaps >= 0.06, light end 2.08:1,
          9deg hue spread. Each bar carries its own value, so there is no y
          axis to read; the four dashed lines are quarters of the scale. ---- */
  /* 25em, fixed — NOT `flex: 1 1 auto`. Filling the pane is what made the
     chart a portrait: the ported card's plot was 36em x 29em (1.24:1) and this
     pane is ~37em wide, so ~25em keeps that shape with the band labels and key
     below it. It also sets the card's height, since it is the tallest thing in
     either pane. */
  /* 25em → 16em → 11em (2026-08-10). With the customer rows hugging their content,
     THIS is the only thing that sets the card's height, so it is the dial that
     bottom-aligns the two panes: at 11em the list ends within ~10px of the chart,
     where at 16em the chart overhung it by ~70px and the gap was the main thing
     wrong with the card.

     WHAT ACTUALLY LIMITS IT IS THE TOP GRIDLINE, AND THAT COST A WRONG ANSWER FIRST.
     The tallest bar is 88% of the plot and its `$186.2k` label sits in the remaining
     12%, so as the plot shrinks the label rises out of the plot box: measured
     label-to-plot-top is +0.2px at 16em, −5.3px at 12em, −8.1px at 10em. The first
     read of that was "16em is the floor, below it the label collides with the AR
     Aging title" — wrong on the second half. Label-to-TITLE stays +12 to +15px right
     down to 9em, because `margin-top: 1.8em` sits between them. The thing the label
     actually hit was `.arv-gl`'s **top:0 gridline**, which is why that gridline is
     gone (see the markup) and 11em is now safe. Three dashed lines at 25/50/75% plus
     the axis is plenty of structure.

     So: if this ever needs to be shorter still, the next constraint is the 25%
     gridline, and the fix is to move the value labels inside the bars. */
  .arv-plot { position: relative; flex: 0 0 auto; height: 11em; margin-top: 1.5em; }
  .arv-gl { position: absolute; left: 0; right: 0; height: 0;
    border-top: 1px dashed rgba(255,255,255,0.075); }
  .arv-axis { position: absolute; left: 0; right: 0; bottom: 0; height: 0;
    border-top: 1px solid rgba(255,255,255,0.16); }
  .arv-bars { position: absolute; inset: 0; display: flex; }
  .arv-bcol { position: relative; flex: 1 1 0; }
  /* width in %, not `em`, so the bars widen with the hero. 28% is the ported
     card's own ratio (a 2em bar in a 7.2em column) and it applies again now the
     plot is landscape — the 40% this needed while the plot filled a portrait
     pane would draw slabs here. */
  .arv-bwrap { position: absolute; bottom: 0; left: 50%; translate: -50% 0; width: 28%; }
  .arv-bb { display: block; height: 100%; border-radius: 0.34em 0.34em 0 0;
    transform-origin: 50% 100%; }
  .arv-bv { position: absolute; bottom: 100%; left: 50%; translate: -50% 0;
    margin-bottom: 0.5em; font-variant-numeric: tabular-nums;
    color: var(--dark-text, #E8E8F0); white-space: nowrap; }
  .arv-bticks { display: flex; margin-top: 0.65em; }
  .arv-btick { flex: 1 1 0; text-align: center; font-size: 0.95em;
    color: var(--dark-text-tertiary, #8A8FA8); white-space: nowrap; }
  /* THE LEGEND IS GONE (2026-08-10), markup and CSS (`.arv-legend` / `.arv-lg-i` /
     `.arv-lg-sw`). It was added under "identity is never colour-alone: the ramp gets
     a key", which is the right rule but was already satisfied without it: this is a
     single-series chart where every bar sits directly above its own `.arv-btick`,
     and the legend's five labels were character-for-character the five axis ticks —
     "Current / 0 - 30 / 30 - 60 / 60 - 90 / 90+" twice on one chart. A legend earns
     its space when it disambiguates series that share an axis; here it only
     restated it, and it cost ~29px of card height (1.5em margin + its own row) in a
     card being shortened on purpose. Removing it is most of the difference between
     385px and 355px.
     If it ever comes back, it belongs BELOW `.arv-bticks` with `margin-top: 1.5em`,
     and the `@container (max-width:470px)` block used to hide it alongside
     `.arv-dh-r` — that mention is gone too. */

  /* ---- largest balances (ARAgingCustomer). THE ROWS HUG THEIR CONTENT and the
          list ends where it ends — it no longer stretches to bottom-align with the
          chart pane. That was the previous rule ("the chart pane sets the height
          and the rows share it out"), and with 7 rows it gave a 4.61em pitch, which
          was fine. At 4 rows it shared the same height between fewer rows and blew
          the pitch out to 8.05em — a third of the card was gaps between hairlines.
          Rows are `flex: 0 0 auto` on a 2.8em floor instead, so the pitch is
          constant no matter how many rows there are, and shortening `.arv-plot` is
          what reduces the card height now. ---- */
  .arv-dlist { flex: 0 0 auto; display: flex; flex-direction: column; min-height: 0;
    margin-top: 0.3em; }
  .arv-crow { flex: 0 0 auto; display: flex; align-items: center; gap: 0.7em;
    /* Now the actual row height, not a floor to grow from: content (a 2.15em
       avatar) is shorter than this, so this IS the pitch. Putting `flex: 1 1 auto`
       back re-couples the pitch to the chart's height — the thing that made 4 rows
       look like 7 rows' worth of air.
       2.8em → 3.27em (2026-08-10) = banking's `.bkv-acct-row` height, measured, so
       the two cards' lists share one rhythm as well as one type size. It is also
       what closed most of the gap under this list: 4 rows went 116px → 151px, which
       is 35 of the ~70px the chart pane used to overhang by. */
    min-height: 3.27em; border-bottom: 1px solid rgba(255,255,255,0.05); }
  .arv-crow:last-child { border-bottom: none; }
  .arv-crow > .arv-name { flex: 1 1 auto; min-width: 0; }
  .arv-crow > .arv-bal { flex: 0 0 auto; }
  .arv-av { flex: 0 0 auto; width: 2.15em; height: 2.15em; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.92em; font-weight: 600; letter-spacing: 0.02em; }
  /* one neutral tint only: the customer initials must not compete with the
     age ramp, which is the one place colour carries meaning here (the retired
     list screen's -pu/-am/-bl/-rt tints went with it) */
  .arv-av-ne { background: rgba(255,255,255,0.08);  color: #B0B5D0; }
  /* 1.12em → 1.06em (2026-08-10): banking's `.bkv-acct-name` / `.bkv-acct-amt` size,
     so the two cards' list rows read at the same 12.25px. This was ALSO what made
     banking's root font-size reachable here — at 1.12em the longest customer name
     overflowed its track by 10px, and the ~5% narrower text is most of what bought
     it back (see the note on `.arv-screen`). Don't nudge it back up without
     re-measuring "Raytheon Technologies" against its track. */
  .arv-name { font-size: 1.06em; font-weight: 500; color: var(--dark-text, #E8E8F0);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .arv-bal { font-size: 1.06em; font-weight: 600; font-variant-numeric: tabular-nums;
    color: var(--dark-text, #E8E8F0); }


  /* ---- staggered entrance — animates `translate`, never `transform`, because
          the tilt handler owns `transform` on .arv-screen. `.arv-bv` and
          `.arv-bwrap` are centred WITH `translate`, so they may only ever be
          faded — animating translate on them would un-centre the label. ---- */
  /* The CARDS glide in first (`translate`, never `transform` — the tilt owns that),
     then the bars and rows stagger inside cards that have already landed. `.arv-kpi`
     left the list: it is part of the base card's own content, so animating it
     separately was the same move played twice. */
  /* ---- the entrance — DIAGONAL ASSEMBLY (2026-09-22) ------------------------
     Each card arrives from ITS OWN side of the composition instead of all of
     them rising straight up together, so the stack assembles itself rather than
     sliding in as one block. Every card still RISES — `--tx` only adds the
     horizontal component, and it is DERIVED, not eyeballed:
         --tx = (cardCentreX - 25em) / 25em * 2.4em        (the stack is 50em)
     The base card is bottom-left and the customer card upper-right, so the two
     arrive on opposite diagonals and close into the overlap.
     A card left of centre enters from the lower-left, one right of centre from
     the lower-right, and one near the middle from very nearly straight below.
     The values below are that formula evaluated against the placements above; if
     a card moves, re-evaluate it rather than nudging the number.
     STILL `translate`, NEVER `transform` — the tilt handler owns `transform` on
     each card. `--tx` is read inside the keyframe, so one keyframe serves every
     card and the per-card difference is one custom property.
     0.8s on the same curve with a 0.14s stagger, replacing the old 0.7s / 0.12s: the longer
     travel wants the longer settle. DEPTH ORDER IS UNCHANGED.
     `--tx` is zeroed in the stacked phone layout below, where the cards are
     full-width in flow and a horizontal offset would mean nothing. ---- */
  .arv-card { opacity: 0; translate: var(--tx, 0) 1.9em; }
  .arv-main     { --tx: -0.75em; --cd: 0s;   }   /* centre x 17.40em, ratio -0.304 — the back card lands first */
  .arv-listcard { --tx:  1.25em; --cd: .14s; }   /* centre x 37.85em, ratio +0.514 — then the customer card over it */
  .arv.is-shown .arv-card { animation: arv-cardin .8s cubic-bezier(0.22,1,0.36,1) var(--cd, 0s) both; }
  @keyframes arv-cardin {
    from { opacity: 0; translate: var(--tx, 0) 1.9em; }
    to   { opacity: 1; translate: 0 0; }
  }
  .arv-crow { opacity: 0; translate: 0 0.5em; }
  .arv-bb { scale: 1 0; }
  .arv-bv { opacity: 0; }
  /* the KPI card leads and the chart card follows 0.09s behind (its `--d`, set
     inline), so the hero number lands first rather than the two arriving as one
     block. Both use the same curve and duration. */
  .arv.is-shown .arv-crow { animation: arv-in .5s cubic-bezier(0.22,1,0.36,1) var(--d, 0s) both; }
  .arv.is-shown .arv-bb { animation: arv-grow .62s cubic-bezier(0.22,1,0.36,1) var(--d, 0s) both; }
  .arv.is-shown .arv-bv { animation: arv-fade .38s linear var(--d, 0s) both; }
  @keyframes arv-in { to { opacity: 1; translate: 0 0; } }
  @keyframes arv-grow { to { scale: 1 1; } }
  @keyframes arv-fade { to { opacity: 1; } }
  @media (prefers-reduced-motion: reduce) {
    .arv-card, .arv-crow { opacity: 1 !important;
      translate: none !important; animation: none !important; }
    .arv-bb { scale: 1 1 !important; animation: none !important; }
    .arv-bv { opacity: 1 !important; animation: none !important; }
    /* Reduced motion kills MOTION, not the composition: the stagger, the drift, the
       hover lift and the hover grow go; the placement stays. The cards have no
       resting rotation to restore. The tilt script bails out on its own. */
    .arv-pos { transition: none; }
    .arv-pos:hover { transform: none; }
    .arv-card { transition: box-shadow .4s ease, border-color .4s ease; }
    .arv-pos:hover .arv-card { scale: none; }
  }
  /* narrow container: 470px rather than the 430px the retired list screen used — by
     ~460px the two panes are too narrow to sit side by side at all.
     THIS RULE NOW ONLY SWITCHES THE LAYOUT. It used to hide two things as well, and
     both are gone from the illo entirely rather than merely hidden here:
     `.arv-legend` (removed outright — "the tick row already names every band" was
     true at every width, not just narrow ones) and `.arv-dh-r`, the card header's
     right-hand KPI + link stack, which is now its own `.arv-kpi` card above. Nothing
     is conditionally hidden on this illo any more. */
  /* ---- narrow card — THE STACK UN-STACKS (2026-08-20) -----------------------
     The 3D composition needs no breakpoint: every offset is `em` off the `2cqi` root
     and the box is a declared 50em, so it is the same picture at 1440 and at 500.
     What breaks is the `clamp()` FLOOR — `2cqi` reaches 7px at a 350px container and
     below that the type stops shrinking while the geometry keeps going. 380px is
     that limit with a margin, the same threshold `.bkv` and `.crv` use. Past it the
     cards go to plain vertical flow: static, full width, no drift, no glow. The base
     card is already first in the DOM, so nothing needs reordering.
     ONE rule for all three selectors — split apart they have equal specificity and
     the reset would depend on source order. */
  @container (max-width: 380px) {
    .arv-stack { width: 100%; height: auto; display: flex; flex-direction: column; gap: 1.15em; }
    .arv-glow { display: none; }
    .arv-pos, .arv-pos-main, .arv-pos-list {
      position: static; transform: none; top: auto; left: auto; width: 100%;
    }
    /* the diagonal is the desktop composition's; in flow there is no left or
       right side to arrive from, so the cards simply rise */
    .arv-card { --tx: 0; }
    .arv-chart { max-width: none; }
  }

  /* THE `@container (max-width: 470px)` BLOCK IS GONE (2026-08-20). Everything in it
     existed to rescue the two-pane grid at narrow widths: it collapsed
     `.arv-dgrid` to one column with `auto auto 1fr` rows (so the stretched chart
     pane did not leave a hole under its fixed-height plot) and gave `.arv-plot` a
     taller 15em to fill the single column. There is no grid and there are no panes
     any more — the chart and the list are separate cards, and the whole composition
     is `em` off the `2cqi` root inside a declared 50em box, so it is the SAME
     PICTURE at every width and has nothing to rescue. The un-stack that does matter
     is at 380px, above, where the `clamp()` floor binds.
     `.arv-plot`'s 11em and `.arv-bwrap`'s 28% now hold at every width; that is the
     point, not an oversight.
     Also recorded when this block was last touched, and still true: NOTHING HIDES
     CUSTOMER ROWS. It used to carry `.arv-crow:nth-child(n+5){display:none}` to cut
     the list from 7 rows to 4 at narrow widths plus a companion
     `:nth-child(4){border-bottom:none}`. The list is 4 rows at EVERY width as of
     2026-08-10, so both were dead — and a dead `display:none` on a row is exactly
     the kind of rule someone later "fixes" by re-adding rows to match. */


  /* ============================================================
     #credit invoice-to-repayment illustration (.arf-*)
     Replaces a "Collateral / Borrowing Base" product screenshot, which showed
     the end state but not how a receivable gets there.

     Construction is lending-overview.html's `.crf` credit-cycle illo, reused
     wholesale so the two diagrams read as one system: one authored SVG viewBox
     with hand-placed coordinates, each connector drawn TWICE (a hairline that
     draws in once + a packet overlay that loops), and pathLength="100" so the
     dash maths is geometry-independent.

     PALETTE IS LIGHT, not `.crf`'s dark. This section is `.seo-content.is-light`,
     so the panel and node boxes take this page's own light vocabulary — the
     `.seo-card` surface (#FFFFFF, --neutral-200 hairline, --r-md, the same 4px
     shadow) that the three cards directly above it use, with --neutral-900 /
     --neutral-500 type. The travelling packets follow the light precedent set by
     instant-payments.html's `.mf-pulse-*`: a saturated stroke plus a drop-shadow
     glow, since a hairline-thin packet reads as nothing on white.

     No max-width (unlike the .seo-image-window it replaces, which capped at
     920px): the panel fills .container so its edges line up with the
     .seo-cards-grid above it — the same reasoning as `.crf`.

     As in `.crf`, the nodes carry no icons. Credit's icons sit on its three
     ENTITY nodes (Invoices / Contracts / Inventory); every node here is a
     process STAGE already labelled with a title and two helper lines, so an
     icon would be decorative, which AION_ICONOGRAPHY.md forbids.

     The one addition over `.crf` is the return leg: the repayment travels back
     from stage 5 to the accent node, which is the whole argument of this page.
     It takes the green of value arriving (`.mf-pulse-in`) against the purple of
     the forward stage links, and the accent node flashes twice per cycle: once
     when the sent invoice lands on it, once when the repayment returns to it.

     The accent node is `Available funds`, NOT `Borrowing base` — so it maps to
     .crf's `Available funds` node, not its `Borrowing base` one. Deliberate:
     this page's reader cares what a sent invoice does to the number they can
     draw, and it is the node the return leg's caption names ("The repayment
     restores your available funds"), so labelling it anything else made the
     loop point at a node whose title the caption never mentioned. Because of
     that, its helper lines carry AVAILABILITY language ("raise what you can
     draw"), not the borrowing-base language they used to ("become eligible
     collateral") — on lending-overview those are two distinct stages and this
     node is only ever the second one. `eligible collateral` still appears, in
     the aria-label, which has room to describe both steps as prose.
     ============================================================ */
  .arf {
    margin: var(--s-12) auto 0;
    padding: var(--s-6);
    background: #FFFFFF;
    border: 1px solid var(--neutral-200);
    border-radius: var(--r-md);
    box-shadow: 0 4px 14px rgba(13, 11, 24, 0.04);
  }
  .arf-illo svg { width: 100%; height: auto; display: block; overflow: visible; }

  /* --- nodes --- */
  .arf-box { fill: var(--neutral-50); stroke: var(--neutral-200); stroke-width: 1; }
  .arf-box-accent { fill: rgba(108,92,231,0.08); stroke: rgba(108,92,231,0.45); }
  .arf-t { font-family: var(--font-heading); font-size: 17px; font-weight: 600; fill: var(--neutral-900); }
  .arf-s { font-family: var(--font-heading); font-size: 14px; font-weight: 400; fill: var(--neutral-500); }
  /* opacity 0 like .arf-node: the caption explains the loop, so it must not be
     on screen before the loop is. Revealed by the .is-shown rule below at the
     moment the hairline finishes drawing. */
  .arf-back-t { font-family: var(--font-heading); font-size: 14px; font-weight: 400;
    fill: var(--neutral-500); text-anchor: middle; opacity: 0; }

  /* --- connectors: solid strokes, never gradients. A perfectly horizontal path
         has zero objectBoundingBox height, so a gradient renders nothing. --- */
  .arf-line { fill: none; stroke-width: 1.25; stroke-linecap: round;
    stroke-dasharray: 100; stroke-dashoffset: 100; }
  .arf-line-mid  { stroke: rgba(108,92,231,0.45); }
  /* 0.40, not the 0.45 of the purple links: #137A3A is a darker hue, so it
     reads at the same weight a step lighter */
  .arf-line-back { stroke: rgba(19,122,58,0.40); }

  /* --- packets: the gap must exceed pathLength (100) so only ONE dash is ever
         on the path; otherwise it wraps and re-draws at the start on exit --- */
  .arf-packet { fill: none; stroke-width: 4; stroke-linecap: round;
    stroke-dasharray: 12 188; stroke-dashoffset: 0; opacity: 0; }
  .arf-packet-mid  { stroke: var(--purple-primary, #6C5CE7); filter: drop-shadow(0 0 3px rgba(108,92,231,0.55)); }
  .arf-packet-back { stroke: #34D399; filter: drop-shadow(0 0 3px rgba(52,211,153,0.85)); }
  .arf-node { opacity: 0; }
  .arf-flash { fill: none; stroke: rgba(108,92,231,0.85); stroke-width: 1.5; opacity: 0; }

  /* --- choreography, gated on .is-shown by the observer below --- */
  .arf.is-shown .arf-node   { animation: arf-in .5s var(--ease-default, ease) var(--d, 0s) both; }
  .arf.is-shown .arf-line   { animation: arf-draw var(--dur, .5s) cubic-bezier(0.22,1,0.36,1) var(--d, 0s) both; }
  .arf.is-shown .arf-packet { animation: arf-fly 5.8s cubic-bezier(0.42,0,0.2,1) var(--d, 0s) infinite; }
  .arf.is-shown .arf-flash  { animation: arf-flash 5.8s var(--ease-default, ease) 0s infinite; }
  /* reuses arf-in, the node fade — same .5s/`both` shape, its own --d */
  .arf.is-shown .arf-back-t { animation: arf-in .5s var(--ease-default, ease) var(--d, 0s) both; }
  @keyframes arf-in   { from { opacity: 0 } to { opacity: 1 } }
  @keyframes arf-draw { from { stroke-dashoffset: 100 } to { stroke-dashoffset: 0 } }
  /* 5.8s period, matching `.crf` and `.mf-*`: the ~0.55s traverse is compressed
     into the first 9.5% and every later keyframe holds the end state, so the
     per-path --d stagger repeats identically on every cycle. */
  @keyframes arf-fly  { 0% { stroke-dashoffset: 0; opacity: 0 }
                        1.2% { opacity: 1 } 8% { opacity: 1 }
                        9.5% { stroke-dashoffset: -100; opacity: 0 }
                        100% { stroke-dashoffset: -100; opacity: 0 } }
  /* two peaks: ~1.5s as the sent invoice lands on the base, ~3.3s as the
     repayment packet returns to it */
  @keyframes arf-flash { 0%, 24% { opacity: 0 } 26.5% { opacity: .85 } 31% { opacity: 0 }
                         55% { opacity: 0 } 57.5% { opacity: .85 } 62%, 100% { opacity: 0 } }

  /* End state with no motion. Resetting dashoffset is load-bearing: without it
     the draw-in parks at its START state and every connector vanishes. */
  @media (prefers-reduced-motion: reduce) {
    .arf-line { stroke-dashoffset: 0 !important; animation: none !important; }
    /* .arf-back-t is here for the same reason .arf-line's dashoffset is: both
       park at a hidden start state, so without the reset they never appear. */
    .arf-node, .arf-back-t { opacity: 1 !important; animation: none !important; }
    .arf-packet, .arf-flash { animation: none !important; opacity: 0 !important; }
  }

  /* --- mobile swap: in-SVG type is illegible below 1040px --- */
  .arf-m { display: none; }
  @media (max-width: 1040px) {
    .arf { padding: var(--s-4); }
    .arf-illo { display: none; }
    .arf-m { display: block; }
    .arf-m-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px;
      background: var(--neutral-50); border: 1px solid var(--neutral-200);
      border-radius: var(--r-md); }
    .arf-m-accent { background: rgba(108,92,231,0.08); border-color: rgba(108,92,231,0.45); }
    .arf-m-t { font-family: var(--font-heading); font-size: 14px; font-weight: 600; color: var(--neutral-900); }
    .arf-m-s { font-family: var(--font-heading); font-size: 12.5px; color: var(--neutral-500); margin-top: 2px; }
    .arf-m-ar { text-align: center; color: var(--purple-primary, #6C5CE7); font-size: 17px; line-height: 1; margin: 8px 0; }
    .arf-m-back { display: flex; align-items: center; justify-content: center; gap: 8px;
      margin-top: 10px; font-family: var(--font-heading); font-size: 12.5px;
      color: var(--neutral-500); }
    .arf-m-back span { color: var(--success, #137A3A); font-size: 15px; line-height: 1; }
  }


  /* ============================================================
     #how invoice-builder illustration (.ib-*)
     A cursor drags template sections out of the section list and drops them
     onto a live invoice preview — which is exactly what the real editor is:
     aion-react's Receivables/Invoices/Template/EditTemplate.js renders
     <InvoicePreview> on the LEFT (width 60%) beside a panel of collapsible
     SECTIONS on the right ("Toggle to show/hide section", "Make any
     customizations to your template here"). Hence preview left, controls right.

     THE SHEET IS LAID OUT TO MATCH <InvoicePreview>, block for block:
       1. header row: company name + address LEFT, logo RIGHT (h 48px)
       2. contact row: Phone | Email | Website, pipe-separated, left aligned
       3. full-width neutral-200 divider
       4. "Invoice #" as a left-aligned labelled field (width 180), NOT a big
          right-aligned number
       5. three 33% address columns: Bill to | Ship to | Invoice details — with
          Ship to still in the palette, Invoice details takes the second column,
          which is what the real component does when that section is hidden
       6. line items, columns in the component's own push order:
          Name | Description | Price | Qty | Amount  (price BEFORE qty)
       7. totals stack, right-aligned 200px rows with FULL-width hairlines
          between: Subtotal / Discount / Taxes / Total
       8. payment details: "label:" at a fixed 176px column, then the value
     Every section name and field label is the real one from that file.

     ONE cursor, deliberately: it reads as the reader's own hand building their
     own template. Two would read as collaborative editing, a different claim.

     Scaling follows the hero illos (.arv / .bkv / .crv): `container-type` on the
     panel, a cqw-driven root font-size on the stage, every coordinate in `em`.
     The stage is 95em x 55.5em, so the root is 100cqw/95 and it always exactly
     fills the panel.

     POSITIONING UNIT TRAP: `top`/`left`/`width`/`translate` in `em` resolve
     against the element's OWN font-size, so a positioned element that also set
     a font-size landed at (coord x its font-size) — the Save button at 36.5em
     rendered at 43.8em on a 42em stage. Every positioned element here stays
     font-size-neutral (1em == the stage root) and all type scale lives on inner
     spans: .ib-chip-t / .ib-slot-t / .ib-save-t / .ib-fld-v.

     THREE PHASES ON ONE LOOP (period 15.5s), all on ONE shared period so the
     phases can never drift apart:
       build   (0.0-8.2s)  four sections dragged in, then Save template
       summary (8.6-10.8s) the sheet crossfades to the send view — the real
                           drawer's "Emailing Invoice 1005" / TO / Subject plus
                           a Send invoice button (SendInvoiceDrawer.js)
       sent    (11.3-13.6s) AlertModal success, verbatim: title "Invoice sent",
                           "Your invoice 1005 has been sent to Boeing
                           Commercial (ap@boeingcommercia.com)"
     and then `sent` hands straight back to `build`, which is what closes the
     loop: the confirmation CROSSFADES into a fresh template (13.25-14.4s) while
     the sheet glides from centre back to its editing position (13.4-14.5s), and
     the panel fades in beside it. Nothing blanks, and the sheet never travels
     empty — a bare white sheet crossing the stage is louder than the phase it
     replaced, which is why the template starts rising at 12.79s, BEFORE the
     sheet moves, and the modal holds until 13.64s so the two genuinely cross
     (neither `.ib-layer` has a background, so overlapping layers read as a
     crossfade, the same way summary -> sent already does). The state reset —
     empty drop slots, undimmed section chips, hidden fills — sits at
     12.48-12.71s, UNDER a still-opaque modal and behind a `build` layer that is
     still transparent, so the snap stays hidden even though the travel is now on
     screen. Anything that moves that reset later has to stay ahead of
     `ib-l-build`'s 82.5%.

     There was a FOURTH phase until 2026-08-03: the sheet handed off to a wide
     dark dashboard Receivables card (ARAging chart + top balances by customer)
     from 13.9s to 17.35s on an 18.5s period. Removed — `sent` now hands back to
     `build` directly. Retimed by keeping every event before the handoff at
     its exact second and pulling the reset tail 3.0s earlier (18.5 -> 15.5s),
     so build/summary/sent still play at their authored pace; only the tail
     percentages moved (92.7% -> 91.29%, 97.03% -> 96.46%, and so on). Gone with
     it: `.ib-dashcard` / `.ib-dash`, keyframes ib-l-dash / ib-grow* / ib-blin* /
     ib-crin*, and the chart primitives (.ib-plot/.ib-grid/.ib-bar*/.ib-tick/
     .ib-axis/.ib-key*/.ib-row/.ib-init/.ib-ch-ic/.ib-link) which nothing else
     used. `.ib-num`, `.ib-hd`, `.ib-rule`, `.ib-sub` and `.ib-cap` stayed —
     the sheet and the send view use them too.

     EVERY animation shares the one loop period with NO delay, its whole timeline encoded in keyframe
     percentages. That is deliberate: `animation-delay` + a short duration cannot
     express "visible BEFORE my event in every cycle" — with a delay, iteration 2
     onwards holds the previous iteration's tail through the early part of the
     cycle, so the empty drop slots would vanish on the second loop. Absolute
     percentages make every hold trivial. Ghosts and drop rings are the only
     exceptions (invisible both before and after), so they share one keyframe.
     ============================================================ */
  .ib {
    container-type: inline-size;
    padding: var(--s-6);
    margin-top: var(--s-12);
    background: var(--dark-card);
    border: 1px solid var(--dark-card-border);
    border-radius: var(--r-lg);
  }
  .ib-stage {
    position: relative;
    font-family: var(--font-data), 'IBM Plex Sans', system-ui, sans-serif;
    font-size: clamp(7px, calc(100cqw / 95), 13px);
    width: 95em; height: 55.5em;
    line-height: 1.4;
    -webkit-font-smoothing: antialiased;
  }
  .ib-stage > * { position: absolute; }
  .ib-ph { fill: currentColor; stroke: none; display: block; flex: 0 0 auto; }

  /* ---- right-hand controls panel (the real editor's customisation column).
         Once Save template is clicked the panel fades out and the sheet glides
         to the centre of the stage, so the finished invoice is the only thing
         on screen for the send step — then both reverse, in view, for the next
         cycle. ---- */
  .ib-panel { left: 62em; top: 0; width: 33em; height: 100%; }
  .ib-panel > * { position: absolute; }
  .ib.is-shown .ib-panel { animation: ib-panel-out 15.5s var(--ease-default, ease) 0s infinite; }
  @keyframes ib-panel-out { 0%,53.22% { opacity: 1 } 58.07%,88% { opacity: 0 } 94.5%,100% { opacity: 1 } }
  /* 18.5em == (95em stage - 58em sheet) / 2 */
  .ib.is-shown .ib-sheet { animation: ib-sheet-centre 15.5s cubic-bezier(0.22,1,0.36,1) 0s infinite; }
  /* The sheet NEVER fades: it rides out to the centre for the send step and
     rides back to its editing position for the next cycle, so the last step and
     the first are one continuous move rather than two states either side of a
     blank frame. 0% and 100% are the same place, which is what makes the loop
     seamless. What used to be here faded the sheet out at 89.68%, snapped it
     home invisibly, then faded it back — the snap was hidden, but so was the
     connection. */
  @keyframes ib-sheet-centre {
    0%,53.54%   { translate: 0 0 }
    59.36%      { translate: 18.5em 0 }
    86.45%      { translate: 18.5em 0 }
    93.5%,100%  { translate: 0 0 }
  }
  .ib-help { left: 0; top: 0; width: 33em; color: var(--dark-text-tertiary, #8A8FA8); }
  .ib-help-t { font-size: 1.1em; }
  .ib-cap-d { font-size: 1em; text-transform: uppercase; letter-spacing: 0.12em;
    color: var(--dark-text-tertiary, #8A8FA8); }
  /* a read-only stand-in for the editor's LabeledInput fields */
  .ib-fld { left: 0; width: 33em; }
  .ib-fld-box {
    margin-top: 0.5em; height: 3.2em; padding: 0 0.9em;
    display: flex; align-items: center;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: 0.6em;
    color: var(--dark-text, #E8E8F0);
  }
  .ib-fld-v { font-size: 1.15em; }

  .ib-chip {
    left: 0; width: 33em; height: 3.3em;
    display: flex; align-items: center; gap: 0.7em;
    padding: 0 0.9em;
    background: rgba(255,255,255,0.055);
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: 0.7em;
    color: var(--dark-text, #E8E8F0);
    white-space: nowrap;
  }
  .ib-chip-t { font-size: 1.15em; }
  .ib-grip { width: 1.25em; height: 1.25em; color: var(--dark-text-tertiary, #8A8FA8); }
  .ib-grip .ib-ph { width: 100%; height: 100%; }
  /* a row dims once its section has been placed on the invoice */

  .ib-save {
    left: 0; width: 33em; height: 3.6em;
    display: flex; align-items: center; justify-content: center;
    border-radius: 0.6em;
    background: var(--purple-primary, #6C5CE7); color: #FFFFFF;
    font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-weight: 600; white-space: nowrap;
  }
  .ib-save-t { font-size: 1.2em; }

  /* ---- the invoice preview ---- */
  .ib-sheet {
    left: 0; top: 0; width: 58em; height: 55.5em;
    background: #FFFFFF;
    border-radius: 0.9em;
    box-shadow: 0 2em 4.5em rgba(0,0,0,0.45);
    overflow: hidden;
  }
  /* three stacked layers inside the sheet; each phase crossfades to the next */
  .ib-layer { position: absolute; inset: 0; }
  .ib-layer > * { position: absolute; }
  .ib-build, .ib-summary, .ib-sent { opacity: 0; }

  .ib.is-shown .ib-build   { animation: ib-l-build   15.5s linear 0s infinite; }
  .ib.is-shown .ib-summary { animation: ib-l-summary 15.5s linear 0s infinite; }
  .ib.is-shown .ib-sent    { animation: ib-l-sent    15.5s linear 0s infinite; }
  @keyframes ib-l-build   { 0%,55.49% { opacity: 1 } 59.03%,82.5% { opacity: 0 } 90%,100% { opacity: 1 } }
  @keyframes ib-l-summary { 0%,55.49% { opacity: 0 } 59.03%,71.94% { opacity: 1 } 74.84%,100% { opacity: 0 } }
  @keyframes ib-l-sent    { 0%,71.94% { opacity: 0 } 74.84%,83.23% { opacity: 1 } 88%,100% { opacity: 0 } }

  .ib-t   { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
            font-weight: 700; color: var(--neutral-900, #1A1A1A); }
  .ib-sub { color: var(--neutral-500, #6B6B80); }
  .ib-hd  { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
            font-weight: 600; color: var(--neutral-900, #1A1A1A); }
  .ib-num { font-variant-numeric: tabular-nums; }
  .ib-rule { height: 1px; background: var(--neutral-200, #DCD9E3); }
  .ib-pipe { color: var(--neutral-300, #C9C6D4); }
  .ib-ic { width: 1.15em; height: 1.15em; color: var(--neutral-500, #6B6B80); }
  .ib-ic .ib-ph { width: 100%; height: 100%; }

  /* ---- summary / send view (SendInvoiceDrawer.js) ---- */
  .ib-amt { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-weight: 700; color: var(--neutral-900, #1A1A1A);
    font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
  .ib-send {
    left: 3em; top: 43.5em; width: 18em; height: 4em;
    display: flex; align-items: center; justify-content: center;
    border-radius: 0.6em;
    background: var(--purple-primary, #6C5CE7); color: #FFFFFF;
    font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-weight: 600; white-space: nowrap;
  }
  .ib-send-t { font-size: 1.25em; }
  .ib-dl { font-family: var(--font-heading), 'DM Sans', system-ui, sans-serif;
    font-weight: 600; font-size: 1.1em; color: var(--purple-primary, #6C5CE7);
    text-decoration: underline; text-underline-offset: 0.25em; }
  .ib.is-shown .ib-send { animation: ib-send-click 15.5s linear 0s infinite; }
  @keyframes ib-send-click {
    0%,68.71%   { scale: 1;   box-shadow: 0 0 0 0 rgba(108,92,231,0.55); }
    69.55%      { scale: .968; box-shadow: 0 0 0 1.1em rgba(108,92,231,0); }
    70.32%,100% { scale: 1;   box-shadow: 0 0 0 0 rgba(108,92,231,0); }
  }
  /* ---- sent confirmation ---- */
  .ib-check { display: inline-flex; width: 5.5em; height: 5.5em;
    color: var(--success, #137A3A); }
  .ib-check .ib-ph { width: 100%; height: 100%; }
  .ib.is-shown .ib-check { animation: ib-check-in 15.5s linear 0s infinite; }
  @keyframes ib-check-in {
    0%,71.94% { scale: .55; animation-timing-function: cubic-bezier(0.34,1.5,0.64,1) }
    74.13%    { scale: 1.08 }
    75.29%,100% { scale: 1 }
  }

  /* ---- drop slots and the blocks that replace them ---- */
  .ib-slot {
    border: 1px dashed rgba(108,92,231,0.5);
    background: rgba(108,92,231,0.05);
    border-radius: 0.5em;
    display: flex; align-items: center; justify-content: center;
    color: rgba(108,92,231,0.9);
    white-space: nowrap;
  }
  .ib-slot-t { font-size: 1.1em; }

  .ib-fill { opacity: 0; }

  .ib-drop {
    border-radius: 0.5em; border: 1.5px solid rgba(108,92,231,0.9);
    opacity: 0; pointer-events: none;
  }

  /* ---- the section being dragged: a condensed pill, the way a drag preview
          narrows out of a full-width row ---- */
  .ib-ghost {
    left: 0; top: 0; width: 20em; height: 3.3em;
    display: flex; align-items: center; gap: 0.7em;
    padding: 0 0.9em;
    background: #1E1B33;
    border: 1px solid rgba(167,139,250,0.6);
    border-radius: 0.7em;
    color: var(--dark-text, #E8E8F0);
    white-space: nowrap;
    opacity: 0;
    z-index: 3;
  }
  .ib.is-shown .ib-ghost1 { animation: ib-drag1 15.5s linear 0s infinite; }
  @keyframes ib-drag1 {
    0%,6.46% { translate: 68.50em 18.40em; opacity: 0; scale: 1; rotate: 0deg;
      box-shadow: 0 0.2em 0.5em rgba(0,0,0,0.2); }
    7.29% { opacity: 1; scale: 1.03; rotate: -1.5deg; box-shadow: 0 1.3em 2.6em rgba(0,0,0,0.5); }
    6.46% { translate: 68.50em 18.40em; }
    7.16% { translate: 67.67em 17.48em; }
    7.48% { translate: 66.59em 16.48em; }
    7.75% { translate: 65.30em 15.45em; }
    7.94% { translate: 64.06em 14.56em; }
    8.13% { translate: 62.57em 13.59em; }
    8.26% { translate: 61.44em 12.91em; }
    8.39% { translate: 60.22em 12.21em; }
    8.52% { translate: 58.91em 11.49em; }
    8.64% { translate: 57.53em 10.77em; }
    8.77% { translate: 56.09em 10.05em; }
    8.9% { translate: 54.60em 9.34em; }
    9.04% { translate: 53.10em 8.65em; }
    9.17% { translate: 51.59em 7.98em; }
    9.29% { translate: 50.11em 7.35em; }
    9.42% { translate: 48.66em 6.75em; }
    9.55% { translate: 47.27em 6.19em; }
    9.68% { translate: 45.96em 5.69em; }
    9.81% { translate: 44.75em 5.23em; }
    10% { translate: 43.12em 4.65em; }
    10.19% { translate: 41.76em 4.18em; }
    10.46% { translate: 40.37em 3.74em; }
    10.84% { translate: 39.12em 3.40em; }
    11.94% { translate: 38.50em 3.35em; }
    11.1% { opacity: 1; scale: 1; rotate: 0deg; box-shadow: 0 0.25em 0.6em rgba(0,0,0,0.25); }
    12.32%,100% { opacity: 0; scale: 1; rotate: 0deg; }
  }
  .ib.is-shown .ib-ghost2 { animation: ib-drag2 15.5s linear 0s infinite; }
  @keyframes ib-drag2 {
    0%,16.45% { translate: 68.50em 22.30em; opacity: 0; scale: 1; rotate: 0deg;
      box-shadow: 0 0.2em 0.5em rgba(0,0,0,0.2); }
    17.29% { opacity: 1; scale: 1.03; rotate: -1.5deg; box-shadow: 0 1.3em 2.6em rgba(0,0,0,0.5); }
    16.45% { translate: 68.50em 22.30em; }
    17.22% { translate: 67.23em 22.67em; }
    17.49% { translate: 65.82em 22.89em; }
    17.68% { translate: 64.21em 23.04em; }
    17.81% { translate: 62.83em 23.12em; }
    17.94% { translate: 61.18em 23.19em; }
    18.07% { translate: 59.26em 23.23em; }
    18.19% { translate: 57.05em 23.25em; }
    18.26% { translate: 55.85em 23.25em; }
    18.32% { translate: 54.57em 23.24em; }
    18.39% { translate: 53.24em 23.23em; }
    18.45% { translate: 51.84em 23.20em; }
    18.51% { translate: 50.38em 23.17em; }
    18.58% { translate: 48.86em 23.14em; }
    18.64% { translate: 47.30em 23.10em; }
    18.71% { translate: 45.68em 23.05em; }
    18.77% { translate: 44.03em 22.99em; }
    18.83% { translate: 42.34em 22.93em; }
    18.91% { translate: 40.62em 22.86em; }
    18.97% { translate: 38.88em 22.79em; }
    19.04% { translate: 37.12em 22.71em; }
    19.1% { translate: 35.35em 22.64em; }
    19.16% { translate: 33.57em 22.55em; }
    19.23% { translate: 31.80em 22.47em; }
    19.29% { translate: 30.04em 22.38em; }
    19.36% { translate: 28.30em 22.29em; }
    19.42% { translate: 26.57em 22.20em; }
    19.48% { translate: 24.88em 22.11em; }
    19.55% { translate: 23.22em 22.02em; }
    19.61% { translate: 21.61em 21.93em; }
    19.68% { translate: 20.04em 21.84em; }
    19.74% { translate: 18.52em 21.76em; }
    19.8% { translate: 17.06em 21.68em; }
    19.87% { translate: 15.66em 21.60em; }
    19.93% { translate: 14.33em 21.52em; }
    20% { translate: 13.06em 21.45em; }
    20.12% { translate: 10.73em 21.32em; }
    20.25% { translate: 8.70em 21.21em; }
    20.39% { translate: 6.97em 21.12em; }
    20.52% { translate: 5.52em 21.05em; }
    20.71% { translate: 3.86em 20.98em; }
    20.97% { translate: 2.48em 20.94em; }
    21.94% { translate: 1.50em 21.00em; }
    21.1% { opacity: 1; scale: 1; rotate: 0deg; box-shadow: 0 0.25em 0.6em rgba(0,0,0,0.25); }
    22.32%,100% { opacity: 0; scale: 1; rotate: 0deg; }
  }
  .ib.is-shown .ib-ghost3 { animation: ib-drag3 15.5s linear 0s infinite; }
  @keyframes ib-drag3 {
    0%,26.45% { translate: 68.50em 26.20em; opacity: 0; scale: 1; rotate: 0deg;
      box-shadow: 0 0.2em 0.5em rgba(0,0,0,0.2); }
    27.28% { opacity: 1; scale: 1.03; rotate: -1.5deg; box-shadow: 0 1.3em 2.6em rgba(0,0,0,0.5); }
    26.45% { translate: 68.50em 26.20em; }
    27.68% { translate: 67.39em 26.71em; }
    27.94% { translate: 65.72em 26.93em; }
    28.13% { translate: 63.84em 27.11em; }
    28.26% { translate: 62.28em 27.23em; }
    28.38% { translate: 60.47em 27.37em; }
    28.51% { translate: 58.42em 27.50em; }
    28.65% { translate: 56.15em 27.64em; }
    28.7% { translate: 54.94em 27.71em; }
    28.78% { translate: 53.69em 27.78em; }
    28.84% { translate: 52.40em 27.85em; }
    28.91% { translate: 51.08em 27.92em; }
    28.97% { translate: 49.73em 27.98em; }
    29.03% { translate: 48.35em 28.05em; }
    29.1% { translate: 46.96em 28.12em; }
    29.16% { translate: 45.55em 28.19em; }
    29.23% { translate: 44.14em 28.26em; }
    29.29% { translate: 42.72em 28.32em; }
    29.35% { translate: 41.32em 28.39em; }
    29.42% { translate: 39.92em 28.45em; }
    29.48% { translate: 38.55em 28.51em; }
    29.55% { translate: 37.19em 28.57em; }
    29.61% { translate: 35.87em 28.63em; }
    29.67% { translate: 34.58em 28.69em; }
    29.74% { translate: 33.33em 28.75em; }
    29.8% { translate: 32.12em 28.80em; }
    29.93% { translate: 29.84em 28.91em; }
    30.07% { translate: 27.78em 29.01em; }
    30.2% { translate: 25.95em 29.10em; }
    30.33% { translate: 24.36em 29.18em; }
    30.45% { translate: 23.02em 29.26em; }
    30.65% { translate: 21.44em 29.36em; }
    30.9% { translate: 20.07em 29.47em; }
    31.94% { translate: 19.00em 29.65em; }
    31.09% { opacity: 1; scale: 1; rotate: 0deg; box-shadow: 0 0.25em 0.6em rgba(0,0,0,0.25); }
    32.32%,100% { opacity: 0; scale: 1; rotate: 0deg; }
  }
  .ib.is-shown .ib-ghost4 { animation: ib-drag4 15.5s linear 0s infinite; }
  @keyframes ib-drag4 {
    0%,36.45% { translate: 68.50em 30.10em; opacity: 0; scale: 1; rotate: 0deg;
      box-shadow: 0 0.2em 0.5em rgba(0,0,0,0.2); }
    37.29% { opacity: 1; scale: 1.03; rotate: -1.5deg; box-shadow: 0 1.3em 2.6em rgba(0,0,0,0.5); }
    36.45% { translate: 68.50em 30.10em; }
    37.36% { translate: 67.44em 30.84em; }
    37.61% { translate: 66.12em 31.41em; }
    37.81% { translate: 64.56em 31.99em; }
    37.93% { translate: 63.20em 32.45em; }
    38.06% { translate: 61.58em 32.97em; }
    38.19% { translate: 59.69em 33.55em; }
    38.32% { translate: 57.52em 34.19em; }
    38.38% { translate: 56.34em 34.53em; }
    38.46% { translate: 55.09em 34.89em; }
    38.52% { translate: 53.79em 35.25em; }
    38.58% { translate: 52.43em 35.63em; }
    38.65% { translate: 51.01em 36.02em; }
    38.71% { translate: 49.55em 36.42em; }
    38.78% { translate: 48.04em 36.83em; }
    38.84% { translate: 46.49em 37.24em; }
    38.9% { translate: 44.91em 37.66em; }
    38.97% { translate: 43.31em 38.09em; }
    39.03% { translate: 41.68em 38.52em; }
    39.1% { translate: 40.04em 38.95em; }
    39.16% { translate: 38.39em 39.39em; }
    39.22% { translate: 36.74em 39.82em; }
    39.29% { translate: 35.09em 40.25em; }
    39.35% { translate: 33.46em 40.68em; }
    39.42% { translate: 31.84em 41.11em; }
    39.48% { translate: 30.25em 41.53em; }
    39.55% { translate: 28.69em 41.94em; }
    39.61% { translate: 27.16em 42.34em; }
    39.67% { translate: 25.68em 42.74em; }
    39.75% { translate: 24.24em 43.12em; }
    39.8% { translate: 22.86em 43.50em; }
    39.88% { translate: 21.53em 43.86em; }
    39.94% { translate: 20.26em 44.21em; }
    40% { translate: 19.06em 44.54em; }
    40.13% { translate: 16.85em 45.17em; }
    40.26% { translate: 14.91em 45.74em; }
    40.39% { translate: 13.25em 46.24em; }
    40.52% { translate: 11.86em 46.68em; }
    40.71% { translate: 10.27em 47.23em; }
    40.96% { translate: 8.94em 47.77em; }
    41.94% { translate: 8.00em 48.45em; }
    41.09% { opacity: 1; scale: 1; rotate: 0deg; box-shadow: 0 0.25em 0.6em rgba(0,0,0,0.25); }
    42.32%,100% { opacity: 0; scale: 1; rotate: 0deg; }
  }
  /* ---- the cursor ---- */
  .ib-cursor {
    left: 0; top: 0; width: 2.3em; height: 2.3em;
    color: #FFFFFF; z-index: 4; opacity: 0;
    /* white fill + a dark shadow, so it reads on the dark panel AND on the
       white sheet — the same trick a real OS pointer uses */
    filter: drop-shadow(0 0.12em 0.25em rgba(0,0,0,0.65));
  }
  .ib-cursor .ib-ph { width: 100%; height: 100%; }
  .ib.is-shown .ib-cursor { animation: ib-move 15.5s linear 0s infinite; }
  /* Sampled every 1.2em of travel along the spline through the control
     points, with linear interpolation between samples, so no chord is long
     enough to read as a straight run. The raised-cosine ease inside each
     segment reaches every control point with zero velocity AND zero
     acceleration, which is what removes the start-stop feel. */
  @keyframes ib-move {
    0% { translate: 85.00em 50.00em; opacity: 0; }
    1.16% { opacity: 1; }
    1.61% { translate: 85.00em 50.00em; }
    2.45% { translate: 84.79em 48.73em; }
    2.77% { translate: 84.63em 47.34em; }
    3.03% { translate: 84.50em 45.75em; }
    3.22% { translate: 84.38em 44.27em; }
    3.41% { translate: 84.25em 42.55em; }
    3.54% { translate: 84.15em 41.29em; }
    3.68% { translate: 84.04em 39.94em; }
    3.81% { translate: 83.91em 38.53em; }
    3.94% { translate: 83.76em 37.08em; }
    4.07% { translate: 83.58em 35.59em; }
    4.19% { translate: 83.37em 34.10em; }
    4.32% { translate: 83.14em 32.62em; }
    4.45% { translate: 82.88em 31.17em; }
    4.58% { translate: 82.59em 29.77em; }
    4.71% { translate: 82.27em 28.44em; }
    4.83% { translate: 81.93em 27.19em; }
    4.97% { translate: 81.57em 26.03em; }
    5.16% { translate: 81.00em 24.49em; }
    5.36% { translate: 80.43em 23.18em; }
    5.61% { translate: 79.72em 21.82em; }
    5.93% { translate: 78.99em 20.70em; }
    6.9% { translate: 78.18em 19.68em; }
    7.29% { translate: 77.30em 18.77em; }
    7.54% { translate: 76.31em 17.89em; }
    7.75% { translate: 75.30em 17.10em; }
    7.94% { translate: 74.06em 16.21em; }
    8.13% { translate: 72.57em 15.24em; }
    8.26% { translate: 71.44em 14.56em; }
    8.39% { translate: 70.22em 13.86em; }
    8.52% { translate: 68.91em 13.14em; }
    8.64% { translate: 67.53em 12.42em; }
    8.77% { translate: 66.09em 11.70em; }
    8.9% { translate: 64.60em 10.99em; }
    9.04% { translate: 63.10em 10.30em; }
    9.17% { translate: 61.59em 9.63em; }
    9.29% { translate: 60.11em 9.00em; }
    9.42% { translate: 58.66em 8.40em; }
    9.55% { translate: 57.27em 7.84em; }
    9.68% { translate: 55.96em 7.34em; }
    9.81% { translate: 54.75em 6.88em; }
    10% { translate: 53.12em 6.30em; }
    10.19% { translate: 51.76em 5.83em; }
    10.46% { translate: 50.37em 5.39em; }
    10.84% { translate: 49.12em 5.05em; }
    12.26% { translate: 48.52em 5.03em; }
    12.9% { translate: 49.69em 5.70em; }
    13.09% { translate: 50.80em 6.25em; }
    13.3% { translate: 52.42em 7.04em; }
    13.42% { translate: 53.80em 7.70em; }
    13.55% { translate: 55.41em 8.47em; }
    13.68% { translate: 57.23em 9.35em; }
    13.81% { translate: 59.23em 10.32em; }
    13.94% { translate: 61.36em 11.37em; }
    14% { translate: 62.46em 11.91em; }
    14.06% { translate: 63.58em 12.47em; }
    14.13% { translate: 64.70em 13.04em; }
    14.19% { translate: 65.81em 13.62em; }
    14.26% { translate: 66.92em 14.19em; }
    14.32% { translate: 68.01em 14.77em; }
    14.38% { translate: 69.08em 15.35em; }
    14.51% { translate: 71.11em 16.48em; }
    14.64% { translate: 72.97em 17.57em; }
    14.78% { translate: 74.61em 18.60em; }
    14.91% { translate: 76.01em 19.54em; }
    15.03% { translate: 77.14em 20.40em; }
    15.23% { translate: 78.34em 21.49em; }
    15.48% { translate: 79.11em 22.58em; }
    16.07% { translate: 78.79em 23.78em; }
    17.16% { translate: 77.48em 24.27em; }
    17.41% { translate: 76.24em 24.48em; }
    17.62% { translate: 74.80em 24.64em; }
    17.74% { translate: 73.55em 24.73em; }
    17.87% { translate: 72.04em 24.81em; }
    18% { translate: 70.25em 24.86em; }
    18.13% { translate: 68.19em 24.89em; }
    18.26% { translate: 65.85em 24.90em; }
    18.32% { translate: 64.57em 24.89em; }
    18.39% { translate: 63.24em 24.88em; }
    18.45% { translate: 61.84em 24.85em; }
    18.51% { translate: 60.38em 24.82em; }
    18.58% { translate: 58.86em 24.79em; }
    18.64% { translate: 57.30em 24.75em; }
    18.71% { translate: 55.68em 24.70em; }
    18.77% { translate: 54.03em 24.64em; }
    18.83% { translate: 52.34em 24.58em; }
    18.91% { translate: 50.62em 24.51em; }
    18.97% { translate: 48.88em 24.44em; }
    19.04% { translate: 47.12em 24.36em; }
    19.1% { translate: 45.35em 24.29em; }
    19.16% { translate: 43.57em 24.20em; }
    19.23% { translate: 41.80em 24.12em; }
    19.29% { translate: 40.04em 24.03em; }
    19.36% { translate: 38.30em 23.94em; }
    19.42% { translate: 36.57em 23.85em; }
    19.48% { translate: 34.88em 23.76em; }
    19.55% { translate: 33.22em 23.67em; }
    19.61% { translate: 31.61em 23.58em; }
    19.68% { translate: 30.04em 23.49em; }
    19.74% { translate: 28.52em 23.41em; }
    19.8% { translate: 27.06em 23.33em; }
    19.87% { translate: 25.66em 23.25em; }
    19.93% { translate: 24.33em 23.17em; }
    20% { translate: 23.06em 23.10em; }
    20.12% { translate: 20.73em 22.97em; }
    20.25% { translate: 18.70em 22.86em; }
    20.39% { translate: 16.97em 22.77em; }
    20.52% { translate: 15.52em 22.70em; }
    20.71% { translate: 13.86em 22.63em; }
    20.97% { translate: 12.48em 22.59em; }
    22.45% { translate: 11.69em 22.72em; }
    22.84% { translate: 13.14em 22.90em; }
    23.04% { translate: 14.86em 23.05em; }
    23.17% { translate: 16.50em 23.18em; }
    23.29% { translate: 18.57em 23.33em; }
    23.36% { translate: 19.78em 23.41em; }
    23.42% { translate: 21.09em 23.50em; }
    23.49% { translate: 22.52em 23.60em; }
    23.55% { translate: 24.06em 23.70em; }
    23.61% { translate: 25.71em 23.81em; }
    23.68% { translate: 27.45em 23.92em; }
    23.74% { translate: 29.28em 24.03em; }
    23.81% { translate: 31.20em 24.15em; }
    23.87% { translate: 33.19em 24.28em; }
    23.93% { translate: 35.25em 24.41em; }
    24% { translate: 37.37em 24.54em; }
    24.06% { translate: 39.52em 24.68em; }
    24.13% { translate: 41.70em 24.81em; }
    24.19% { translate: 43.91em 24.95em; }
    24.25% { translate: 46.11em 25.09em; }
    24.32% { translate: 48.31em 25.23em; }
    24.38% { translate: 50.49em 25.38em; }
    24.46% { translate: 52.63em 25.52em; }
    24.52% { translate: 54.73em 25.66em; }
    24.58% { translate: 56.77em 25.79em; }
    24.65% { translate: 58.74em 25.93em; }
    24.71% { translate: 60.63em 26.06em; }
    24.78% { translate: 62.44em 26.19em; }
    24.84% { translate: 64.16em 26.32em; }
    24.9% { translate: 65.78em 26.44em; }
    24.97% { translate: 67.29em 26.56em; }
    25.03% { translate: 68.70em 26.67em; }
    25.1% { translate: 70.00em 26.78em; }
    25.23% { translate: 72.26em 26.98em; }
    25.35% { translate: 74.10em 27.17em; }
    25.48% { translate: 75.52em 27.32em; }
    25.67% { translate: 77.01em 27.52em; }
    26.07% { translate: 78.28em 27.77em; }
    27.55% { translate: 77.92em 28.26em; }
    27.81% { translate: 76.67em 28.46em; }
    28% { translate: 75.16em 28.63em; }
    28.13% { translate: 73.84em 28.76em; }
    28.26% { translate: 72.28em 28.88em; }
    28.38% { translate: 70.47em 29.02em; }
    28.51% { translate: 68.42em 29.15em; }
    28.65% { translate: 66.15em 29.29em; }
    28.7% { translate: 64.94em 29.36em; }
    28.78% { translate: 63.69em 29.43em; }
    28.84% { translate: 62.40em 29.50em; }
    28.91% { translate: 61.08em 29.57em; }
    28.97% { translate: 59.73em 29.63em; }
    29.03% { translate: 58.35em 29.70em; }
    29.1% { translate: 56.96em 29.77em; }
    29.16% { translate: 55.55em 29.84em; }
    29.23% { translate: 54.14em 29.91em; }
    29.29% { translate: 52.72em 29.97em; }
    29.35% { translate: 51.32em 30.04em; }
    29.42% { translate: 49.92em 30.10em; }
    29.48% { translate: 48.55em 30.16em; }
    29.55% { translate: 47.19em 30.22em; }
    29.61% { translate: 45.87em 30.28em; }
    29.67% { translate: 44.58em 30.34em; }
    29.74% { translate: 43.33em 30.40em; }
    29.8% { translate: 42.12em 30.45em; }
    29.93% { translate: 39.84em 30.56em; }
    30.07% { translate: 37.78em 30.66em; }
    30.2% { translate: 35.95em 30.75em; }
    30.33% { translate: 34.36em 30.83em; }
    30.45% { translate: 33.02em 30.91em; }
    30.65% { translate: 31.44em 31.01em; }
    30.9% { translate: 30.07em 31.12em; }
    32.39% { translate: 29.09em 31.34em; }
    32.83% { translate: 30.31em 31.39em; }
    33.04% { translate: 31.68em 31.37em; }
    33.16% { translate: 32.98em 31.34em; }
    33.29% { translate: 34.63em 31.29em; }
    33.42% { translate: 36.63em 31.22em; }
    33.55% { translate: 38.97em 31.13em; }
    33.61% { translate: 40.26em 31.08em; }
    33.68% { translate: 41.63em 31.03em; }
    33.74% { translate: 43.07em 30.98em; }
    33.8% { translate: 44.58em 30.92em; }
    33.87% { translate: 46.13em 30.87em; }
    33.93% { translate: 47.74em 30.81em; }
    34% { translate: 49.38em 30.75em; }
    34.06% { translate: 51.05em 30.70em; }
    34.12% { translate: 52.74em 30.64em; }
    34.2% { translate: 54.44em 30.59em; }
    34.25% { translate: 56.13em 30.55em; }
    34.33% { translate: 57.81em 30.51em; }
    34.39% { translate: 59.47em 30.47em; }
    34.45% { translate: 61.09em 30.44em; }
    34.52% { translate: 62.67em 30.41em; }
    34.58% { translate: 64.20em 30.40em; }
    34.65% { translate: 65.67em 30.39em; }
    34.71% { translate: 67.07em 30.39em; }
    34.78% { translate: 68.40em 30.39em; }
    34.84% { translate: 69.65em 30.41em; }
    34.97% { translate: 71.89em 30.46em; }
    35.1% { translate: 73.77em 30.55em; }
    35.22% { translate: 75.30em 30.66em; }
    35.42% { translate: 76.94em 30.87em; }
    35.68% { translate: 78.13em 31.18em; }
    37.17% { translate: 78.00em 32.18em; }
    37.49% { translate: 76.87em 32.75em; }
    37.68% { translate: 75.65em 33.24em; }
    37.87% { translate: 73.91em 33.86em; }
    38% { translate: 72.43em 34.35em; }
    38.13% { translate: 70.67em 34.90em; }
    38.25% { translate: 68.64em 35.51em; }
    38.38% { translate: 66.34em 36.18em; }
    38.46% { translate: 65.09em 36.54em; }
    38.52% { translate: 63.79em 36.90em; }
    38.58% { translate: 62.43em 37.28em; }
    38.65% { translate: 61.01em 37.67em; }
    38.71% { translate: 59.55em 38.07em; }
    38.78% { translate: 58.04em 38.48em; }
    38.84% { translate: 56.49em 38.89em; }
    38.9% { translate: 54.91em 39.31em; }
    38.97% { translate: 53.31em 39.74em; }
    39.03% { translate: 51.68em 40.17em; }
    39.1% { translate: 50.04em 40.60em; }
    39.16% { translate: 48.39em 41.04em; }
    39.22% { translate: 46.74em 41.47em; }
    39.29% { translate: 45.09em 41.90em; }
    39.35% { translate: 43.46em 42.33em; }
    39.42% { translate: 41.84em 42.76em; }
    39.48% { translate: 40.25em 43.18em; }
    39.55% { translate: 38.69em 43.59em; }
    39.61% { translate: 37.16em 43.99em; }
    39.67% { translate: 35.68em 44.39em; }
    39.75% { translate: 34.24em 44.77em; }
    39.8% { translate: 32.86em 45.15em; }
    39.88% { translate: 31.53em 45.51em; }
    39.94% { translate: 30.26em 45.86em; }
    40% { translate: 29.06em 46.19em; }
    40.13% { translate: 26.85em 46.82em; }
    40.26% { translate: 24.91em 47.39em; }
    40.39% { translate: 23.25em 47.89em; }
    40.52% { translate: 21.86em 48.33em; }
    40.71% { translate: 20.27em 48.88em; }
    40.96% { translate: 18.94em 49.42em; }
    42.45% { translate: 18.01em 50.15em; }
    43.74% { translate: 19.30em 50.53em; }
    44.13% { translate: 20.66em 50.59em; }
    44.39% { translate: 21.97em 50.58em; }
    44.58% { translate: 23.18em 50.55em; }
    44.77% { translate: 24.60em 50.49em; }
    44.97% { translate: 26.23em 50.40em; }
    45.09% { translate: 27.43em 50.33em; }
    45.22% { translate: 28.72em 50.24em; }
    45.35% { translate: 30.09em 50.14em; }
    45.49% { translate: 31.55em 50.03em; }
    45.62% { translate: 33.09em 49.90em; }
    45.74% { translate: 34.70em 49.77em; }
    45.87% { translate: 36.37em 49.62em; }
    46% { translate: 38.10em 49.46em; }
    46.13% { translate: 39.88em 49.29em; }
    46.26% { translate: 41.69em 49.12em; }
    46.38% { translate: 43.54em 48.94em; }
    46.51% { translate: 45.40em 48.75em; }
    46.64% { translate: 47.28em 48.56em; }
    46.78% { translate: 49.16em 48.37em; }
    46.91% { translate: 51.02em 48.18em; }
    47.04% { translate: 52.87em 47.98em; }
    47.16% { translate: 54.69em 47.79em; }
    47.29% { translate: 56.47em 47.60em; }
    47.42% { translate: 58.21em 47.42em; }
    47.55% { translate: 59.89em 47.23em; }
    47.68% { translate: 61.51em 47.06em; }
    47.8% { translate: 63.07em 46.89em; }
    47.93% { translate: 64.55em 46.73em; }
    48.06% { translate: 65.96em 46.58em; }
    48.2% { translate: 67.29em 46.44em; }
    48.33% { translate: 68.53em 46.30em; }
    48.52% { translate: 70.24em 46.12em; }
    48.71% { translate: 71.76em 45.96em; }
    48.9% { translate: 73.09em 45.82em; }
    49.16% { translate: 74.59em 45.67em; }
    49.42% { translate: 75.79em 45.55em; }
    49.81% { translate: 77.09em 45.42em; }
    50.51% { translate: 78.31em 45.32em; }
    52% { translate: 79.22em 45.24em; }
    52.78% { translate: 80.53em 45.15em; }
    53.35% { translate: 81.75em 45.07em; }
    53.94% { translate: 82.98em 45.00em; }
    54.64% { translate: 84.27em 44.95em; }
    56.13% { translate: 85.28em 44.99em; }
    57.42% { translate: 84.03em 45.13em; }
    58.13% { translate: 82.76em 45.20em; }
    58.77% { translate: 81.49em 45.25em; }
    59.41% { translate: 80.28em 45.28em; }
    60.26% { translate: 79.08em 45.30em; }
    61.74% { translate: 78.27em 45.30em; }
    62.39% { translate: 76.96em 45.30em; }
    62.71% { translate: 75.69em 45.30em; }
    62.97% { translate: 74.28em 45.29em; }
    63.16% { translate: 72.98em 45.28em; }
    63.35% { translate: 71.45em 45.27em; }
    63.54% { translate: 69.69em 45.25em; }
    63.68% { translate: 68.39em 45.24em; }
    63.81% { translate: 67.00em 45.23em; }
    63.94% { translate: 65.52em 45.22em; }
    64.07% { translate: 63.95em 45.21em; }
    64.19% { translate: 62.31em 45.19em; }
    64.32% { translate: 60.60em 45.18em; }
    64.45% { translate: 58.85em 45.17em; }
    64.58% { translate: 57.05em 45.15em; }
    64.71% { translate: 55.22em 45.14em; }
    64.83% { translate: 53.39em 45.13em; }
    64.96% { translate: 51.55em 45.12em; }
    65.1% { translate: 49.73em 45.11em; }
    65.23% { translate: 47.94em 45.11em; }
    65.36% { translate: 46.20em 45.10em; }
    65.48% { translate: 44.52em 45.10em; }
    65.61% { translate: 42.90em 45.10em; }
    65.74% { translate: 41.37em 45.10em; }
    65.87% { translate: 39.93em 45.11em; }
    66% { translate: 38.60em 45.12em; }
    66.13% { translate: 37.36em 45.13em; }
    66.33% { translate: 35.72em 45.15em; }
    66.52% { translate: 34.33em 45.18em; }
    66.78% { translate: 32.87em 45.22em; }
    67.1% { translate: 31.62em 45.29em; }
    68.58% { translate: 30.50em 45.50em; }
    70.06% { translate: 31.41em 45.71em; }
    70.46% { translate: 32.62em 45.87em; }
    70.71% { translate: 33.86em 46.01em; }
    70.91% { translate: 35.06em 46.13em; }
    71.1% { translate: 36.50em 46.27em; }
    71.29% { translate: 38.20em 46.43em; }
    71.42% { translate: 39.46em 46.54em; }
    71.55% { translate: 40.83em 46.66em; }
    71.67% { translate: 42.30em 46.78em; }
    71.8% { translate: 43.87em 46.91em; }
    71.94% { translate: 45.53em 47.05em; }
    72.07% { translate: 47.26em 47.18em; }
    72.2% { translate: 49.06em 47.33em; }
    72.32% { translate: 50.92em 47.47em; }
    72.45% { translate: 52.82em 47.62em; }
    72.58% { translate: 54.75em 47.76em; }
    72.71% { translate: 56.70em 47.91em; }
    72.84% { translate: 58.65em 48.05em; }
    72.97% { translate: 60.58em 48.20em; }
    73.09% { translate: 62.50em 48.34em; }
    73.22% { translate: 64.37em 48.48em; }
    73.36% { translate: 66.20em 48.61em; }
    73.49% { translate: 67.97em 48.74em; }
    73.62% { translate: 69.66em 48.86em; }
    73.74% { translate: 71.28em 48.98em; }
    73.87% { translate: 72.80em 49.09em; }
    74% { translate: 74.24em 49.19em; }
    74.13% { translate: 75.58em 49.29em; }
    74.26% { translate: 76.82em 49.38em; }
    74.45% { translate: 78.48em 49.50em; }
    74.64% { translate: 79.92em 49.61em; }
    74.84% { translate: 81.14em 49.70em; }
    75.1% { translate: 82.45em 49.80em; }
    75.48% { translate: 83.81em 49.90em; }
    76.45% { translate: 85.00em 50.00em; }
    78.07% { opacity: 0; }
    100% { translate: 85.00em 50.00em; opacity: 0; }
  }
  .ib.is-shown .ib-save { animation: ib-save-click 15.5s linear 0s infinite; }
  @keyframes ib-save-click {
    0%,50.96% { scale: 1; box-shadow: 0 0 0 0 rgba(108,92,231,0.5); }
    52% { scale: .975; box-shadow: 0 0 0 1em rgba(108,92,231,0); }
    52.58%,100% { scale: 1; box-shadow: 0 0 0 0 rgba(108,92,231,0); }
  }
  .ib.is-shown .ib-slot1 { animation: ib-slot1 15.5s linear 0s infinite; }
  @keyframes ib-slot1 { 0%,10.65% { opacity: 1 } 12.07%,80.5% { opacity: 0 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-slot2 { animation: ib-slot2 15.5s linear 0s infinite; }
  @keyframes ib-slot2 { 0%,20.65% { opacity: 1 } 22.07%,80.5% { opacity: 0 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-slot3 { animation: ib-slot3 15.5s linear 0s infinite; }
  @keyframes ib-slot3 { 0%,30.65% { opacity: 1 } 32.06%,80.5% { opacity: 0 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-slot4 { animation: ib-slot4 15.5s linear 0s infinite; }
  @keyframes ib-slot4 { 0%,40.64% { opacity: 1 } 42.06%,80.5% { opacity: 0 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-chip1 { animation: ib-dim1 15.5s linear 0s infinite; }
  @keyframes ib-dim1 { 0%,6.46% { opacity: 1 } 9.04%,80.5% { opacity: .4 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-chip2 { animation: ib-dim2 15.5s linear 0s infinite; }
  @keyframes ib-dim2 { 0%,16.45% { opacity: 1 } 19.04%,80.5% { opacity: .4 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-chip3 { animation: ib-dim3 15.5s linear 0s infinite; }
  @keyframes ib-dim3 { 0%,26.45% { opacity: 1 } 29.03%,80.5% { opacity: .4 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-chip4 { animation: ib-dim4 15.5s linear 0s infinite; }
  @keyframes ib-dim4 { 0%,36.45% { opacity: 1 } 39.03%,80.5% { opacity: .4 } 82%,100% { opacity: 1 } }
  .ib.is-shown .ib-fill1 { animation: ib-fill1 15.5s linear 0s infinite; }
  @keyframes ib-fill1 {
    0%,11.94% { opacity: 0; scale: .985; translate: 0 0.18em;
      animation-timing-function: cubic-bezier(0.25,0.8,0.3,1) }
    14.26%,80.5% { opacity: 1; scale: 1; translate: 0 0 }
    82%,100% { opacity: 0; scale: .985; translate: 0 0.18em } }
  .ib.is-shown .ib-fill2 { animation: ib-fill2 15.5s linear 0s infinite; }
  @keyframes ib-fill2 {
    0%,21.94% { opacity: 0; scale: .985; translate: 0 0.18em;
      animation-timing-function: cubic-bezier(0.25,0.8,0.3,1) }
    24.25%,80.5% { opacity: 1; scale: 1; translate: 0 0 }
    82%,100% { opacity: 0; scale: .985; translate: 0 0.18em } }
  .ib.is-shown .ib-fill3 { animation: ib-fill3 15.5s linear 0s infinite; }
  @keyframes ib-fill3 {
    0%,31.94% { opacity: 0; scale: .985; translate: 0 0.18em;
      animation-timing-function: cubic-bezier(0.25,0.8,0.3,1) }
    34.25%,80.5% { opacity: 1; scale: 1; translate: 0 0 }
    82%,100% { opacity: 0; scale: .985; translate: 0 0.18em } }
  .ib.is-shown .ib-fill4 { animation: ib-fill4 15.5s linear 0s infinite; }
  @keyframes ib-fill4 {
    0%,41.94% { opacity: 0; scale: .985; translate: 0 0.18em;
      animation-timing-function: cubic-bezier(0.25,0.8,0.3,1) }
    44.26%,80.5% { opacity: 1; scale: 1; translate: 0 0 }
    82%,100% { opacity: 0; scale: .985; translate: 0 0.18em } }
  .ib.is-shown .ib-fill5 { animation: ib-fill5 15.5s linear 0s infinite; }
  @keyframes ib-fill5 {
    0%,32.91% { opacity: 0; scale: .985; translate: 0 0.18em;
      animation-timing-function: cubic-bezier(0.25,0.8,0.3,1) }
    35.22%,80.5% { opacity: 1; scale: 1; translate: 0 0 }
    82%,100% { opacity: 0; scale: .985; translate: 0 0.18em } }

  /* End state, no motion: the finished invoice, every section placed, no cursor.
     Each animated piece is parked at its END value by hand, because
     `animation: none` otherwise reverts it to the START value — the same trap
     `.crf`'s reduced-motion block documents. */
  @media (prefers-reduced-motion: reduce) {
    .ib-cursor, .ib-ghost, .ib-drop, .ib-slot,
    .ib-summary, .ib-sent { display: none !important; }
    .ib-build { opacity: 1 !important; animation: none !important; }
    .ib-fill { opacity: 1 !important; scale: 1 !important; animation: none !important; }
    .ib-chip.is-taken { opacity: .4 !important; animation: none !important; }
    .ib-save, .ib-send, .ib-check { animation: none !important; }
    /* explicit, so the static state cannot end up with the sheet parked
       centre-stage or the panel parked invisible */
    .ib-sheet, .ib-panel { animation: none !important; translate: none !important;
      opacity: 1 !important; }
  }

  /* ---- mobile: the stage is unreadable below 1040px, so state the claim
          plainly — the set of sections you can put on your own template ---- */
  .ib-m { display: none; }
  @media (max-width: 1040px) {
    .ib { padding: var(--s-4); margin-top: var(--s-10); }
    .ib-stage { display: none; }
    .ib-m { display: block; }
    .ib-m-lbl { font-family: var(--font-data); font-size: 12px; text-transform: uppercase;
      letter-spacing: 0.12em; color: var(--dark-text-tertiary, #8A8FA8); margin-bottom: 12px; }
    .ib-m-set { display: flex; flex-wrap: wrap; gap: 8px; }
    .ib-m-chip { display: inline-flex; align-items: center; gap: 7px;
      padding: 9px 12px; background: rgba(255,255,255,0.055);
      border: 1px solid rgba(255,255,255,0.10); border-radius: 10px;
      font-family: var(--font-data); font-size: 13px; color: var(--dark-text, #E8E8F0); }
    .ib-m-chip svg { width: 14px; height: 14px; fill: var(--dark-text-tertiary, #8A8FA8); stroke: none; }
    .ib-m-note { margin-top: 14px; font-family: var(--font-data); font-size: 13px;
      line-height: 1.55; color: var(--dark-text-secondary, #B0B5D0); }
  }
