/* ═══════════════════════════════════════════════════════════
   Rkieh Productions — the experience layer
   ───────────────────────────────────────────────────────────
   phase5.css established the vocabulary: the signal, the field, the
   engineering marks. This file establishes the WORLD those marks live
   in, and it changes one structural thing about the page.

   THE BANDING PROBLEM
   The page used to be a stack of panels: cream section, cream section,
   black section, cream section, black section. Every boundary was a cut,
   and a cut is what makes a page read as a template with content poured
   into it.

   THE FIX — ground and objects
   There is now exactly one ground: a warm, continuously lit environment
   that runs the whole document. It is painted once, in a fixed layer, so
   its light and its measurement grid never restart at a section edge.
   Nothing that scrolls paints its own full-width background any more.

   Darkness is no longer a section. It is an OBJECT — the Rkieh Productions console —
   a deep graphite surface that floats on that one ground. The console
   appears three times: the hero stage, the system field, and the close.
   Because it is an object rather than a band, entering it is a thing
   moving toward you, not the page changing colour. The only place the
   page truly goes dark is the very bottom, where the close and the
   footer are one continuous ending reached through a long ramp.

   Motion rules are inherited unchanged: transforms and opacity only,
   everything readable before any script runs, reduced motion lands on a
   finished frame rather than an empty one.
   ═══════════════════════════════════════════════════════════ */

/* ── 1. Environment tokens ──────────────────────────────── */
:root{
  /* the one ground, warm and slightly lit from the top */
  --env-base:#ffffff;
  /* THE FIRST SCREEN'S GROUND, AND IT IS NOT THE PAGE'S. The render is a
     landscape now, not an object floating in cream: its outer columns measure
     #f3e8df at the top and #ddcbbc at the foot — warm sand, 12 to 30 values
     off --env-base. Feathered into the page's cream that difference reads as
     a warm halo round a rectangle, which is the one thing the feather exists
     to prevent. So the section takes the picture's own ground and hands back
     to the page's below the copy. */
  --hero-sky:#f1e5db;
  --hero-sand:#e3d2c4;
  /* the fixed header's height, measured: constant at every viewport */
  --hdr-h:59px;
  --env-lift:#faf8f3;
  --env-sink:#eae5db;

  /* the console — a warm near-black, never blue-black */
  --con-1:#1a1817;
  --con-2:#141312;
  --con-3:#22201e;
  --con-line:rgba(244,241,235,.14);
  --con-line-2:rgba(244,241,235,.07);
  --con-ink:#f4f1eb;
  --con-ink-2:#b0aba2;
  --con-ink-3:#9b968d;

  /* atmosphere */
  --bloom-red:rgba(212,43,48,.20);
  --bloom-warm:rgba(242,182,34,.13);
  --bloom-cool:rgba(18,171,102,.10);
  --bloom-deep:rgba(26,25,23,.09);

  /* layered translucent surfaces */
  --pane:rgba(255,253,250,.74);
  --pane-solid:#fffdfa;
  --pane-line:rgba(26,25,23,.11);
  --pane-edge:inset 0 1px 0 rgba(255,255,255,.85);

  /* elevation — three steps, used consistently */
  --el-1:0 1px 2px rgba(26,25,23,.045), 0 4px 12px -5px rgba(26,25,23,.09);
  --el-2:0 2px 6px -2px rgba(26,25,23,.07), 0 18px 40px -20px rgba(26,25,23,.22);
  --el-3:0 10px 24px -10px rgba(26,25,23,.13), 0 48px 96px -44px rgba(26,25,23,.40);
  --el-sig:0 10px 30px -14px rgba(212,43,48,.55);

  /* the console's own elevation, on light ground */
  --el-con:0 2px 8px -2px rgba(26,25,23,.18),
           0 40px 80px -36px rgba(26,25,23,.45),
           0 0 0 1px rgba(26,25,23,.07);

  /* motion */
  --e-out:cubic-bezier(.22,1,.36,1);
  --e-io:cubic-bezier(.65,0,.35,1);
  --e-soft:cubic-bezier(.33,1,.68,1);

  /* the console's inset from the page edge */
  --con-gut:clamp(0px,calc((100vw - var(--wrap)) / 2 + 0.6rem),4rem);
  --con-r:clamp(1.1rem,.7rem + 1.6vw,2.1rem);
}

/* The header floats over the same ground the page is painted in, so the
   two must agree — otherwise the pill sits on a strip of a different
   cream than everything below it. */
body.p5body{background:var(--env-base)}

/* ── 2. The ground ──────────────────────────────────────
   One fixed layer, painted once. Because it does not scroll it cannot
   restart at a section edge, which is the whole point: the light and the
   measurement grid are continuous for the length of the document.

   THREE LAYERS, NOT SIX. The first version gave every bloom its own
   absolutely-positioned element behind a 72px blur. That is six
   viewport-sized surfaces to composite on every scrolled frame, and it took
   the page from 41fps to 13 on a software rasteriser. All three blooms are
   now radial-gradient stops on ONE element, the grain is a background layer
   on the sky itself, and the only things that move are two transforms —
   which the compositor does without repainting anything.

   The base colour lives on <body>, not here. A contrast audit walks up from
   a text node looking for the first opaque background and has to find the
   colour the visitor actually sees; the sky is painted above the canvas at
   z-index -1, so body's colour is both what the walk finds and what is
   really behind the page. */
.p5page{position:relative;background:transparent}
.p5page > *{position:relative;z-index:1}
.p5page > .p5sky{z-index:-1}

.p5sky{
  position:fixed;inset:0;pointer-events:none;overflow:hidden;
  contain:layout paint style;
  /* WHITE, AS ASKED — 2026-09-05. This fixed sheet used to wash the whole
     viewport with three layers: a grey noise texture at .16, a radial of
     --env-lift (#faf8f3) from the top, and a linear fall to --env-sink
     (#eae5db) below the half. `body` was already #ffffff; this was what made
     every screen read cream, and sampling the left gutter down the page gave
     #FAFAFA to #F3F3F3 rather than white.
     The grain went with the gradients — it is what kept the last few points
     off pure white. Put the noise layer back on its own if the page reads too
     flat against the clay illustrations; the gradients are the part that
     carried the colour.
     --env-lift and --env-sink are untouched: two panels further down use them
     as --surface-2, and whitening the tokens would have flattened those into
     the page. */
  background-image:none;
  background-color:#ffffff;
}

/* The measurement grid's styles went with its markup on 2026-08-26 — see the
   note in templates/public/page.html. */

}

/* The blooms — all three on one surface, no blur filter: a multi-stop radial
   gradient has the same falloff and is drawn once instead of per frame.

   `will-change` is NOT declared here. It is added by script while the pointer
   is actually moving and taken off again ~700ms after it stops, so the layer
   exists only for as long as something is using it. Left on permanently it
   is a 2.5-megapixel surface re-composited on every scrolled frame, which on
   a software rasteriser cost three quarters of the page's frame rate. */
.p5sky-blooms{
  position:absolute;inset:-12%;
  transform:translate3d(calc(var(--px,0) * 22px),calc(var(--py,0) * 16px),0);
  background-image:
    radial-gradient(38% 38% at 88% 6%,
      rgba(212,43,48,.24),rgba(212,43,48,.15) 34%,rgba(212,43,48,.05) 62%,transparent 82%),
    radial-gradient(34% 34% at 6% 92%,
      rgba(18,171,102,.13),rgba(18,171,102,.07) 36%,rgba(18,171,102,.02) 64%,transparent 84%),
    radial-gradient(30% 30% at 62% 56%,
      rgba(242,182,34,.15),rgba(242,182,34,.08) 36%,rgba(242,182,34,.02) 64%,transparent 84%);
}
.p5sky.live .p5sky-blooms{will-change:transform}

/* The gutter thread's styles went with its markup on 2026-08-26 — see the
   note in templates/public/page.html. */


/* ── 4. Sections stop painting themselves ───────────────
   Every scrolling section is transparent now. What used to be a section
   background is either the one ground behind it, or a console object
   sitting on that ground. */
.p5page .sec,
.p5page .p5fams,
.p5page .p5adv{background:transparent}
/* phase5.css gave the advisor its own radial ground; the sky carries that
   light now, and two of them stacked read as a stain. */
.p5page .p5adv{background:none}

/* Section rhythm. The marketing default put roughly 200px of nothing between
   every pair of blocks, and this page has eleven of them: a sixth of the
   document was empty ground. Generosity at that scale reads as a layout
   someone forgot to fill. A short block between two chapters gets a short
   gap; the chapters themselves keep their air. */
.p5page .sec{padding-block:clamp(2.4rem,1.8rem + 2.6vw,4rem)}
.p5page .sec.tight,
.p5page .sec.sec-tight{padding-block:clamp(1.5rem,1.2rem + 1.4vw,2.2rem)}
.p5page .sec-head{margin-block-end:clamp(1.5rem,1.1rem + 1.6vw,2.4rem)}
.p5page .p5fams{padding-block:clamp(2.6rem,2rem + 3vw,4.4rem)}
.p5page .p5adv{padding-block:clamp(3rem,2.2rem + 3.4vw,5.25rem)}

/* ── 5. THE CONSOLE ─────────────────────────────────────
   The recurring dark object. Everything dark on this site is one of these,
   which is what lets the hero, the system field and the close read as the
   same instrument seen three times rather than three unrelated dark bands. */
.con{
  position:relative;border-radius:var(--con-r);
  background-image:
    radial-gradient(120% 80% at 50% -10%,rgba(244,241,235,.055),transparent 60%),
    linear-gradient(180deg,var(--con-3),var(--con-1) 22%,var(--con-2));
  /* An explicit colour as well as the gradients, and deliberately the LIGHTEST
     of them. A gradient-only background computes as transparent, so a contrast
     audit walking up from a label inside the console would sail past it to the
     cream ground and report light-on-dark text as a failure. Naming the
     lightest stop means the figure the audit computes is never better than
     what the visitor actually sees. */
  background-color:var(--con-3);
  color:var(--con-ink);
  box-shadow:var(--el-con);
  overflow:hidden;
  --ink:var(--con-ink);--ink-2:var(--con-ink-2);--ink-3:var(--con-ink-3);
  --line:var(--con-line);--line-2:var(--con-line-2);
  --surface:var(--con-3);--surface-2:#2a2725;
  --brand:var(--sig-2);--on-brand:#2a0b0c;
}
/* The console's measurement grid and its bloom are background layers on the
   surfaces that need them — the hero field and each stack panel — rather than
   elements of their own. Four masked, panel-sized children composited while
   three of them overlap was the most expensive thing on this page. */

/* ── 6. Panes — the light counterpart to the console ───
   Layered translucent surfaces on the one ground. Used for anything that
   used to be a flat card. */
.pane{
  position:relative;border-radius:var(--r-lg);
  background:var(--pane);
  -webkit-backdrop-filter:blur(14px) saturate(1.12);
  backdrop-filter:blur(14px) saturate(1.12);
  border:1px solid var(--pane-line);
  box-shadow:var(--el-1),var(--pane-edge);
}
@supports not (backdrop-filter:blur(2px)){
  .pane{background:var(--pane-solid)}
}

/* ── 7. Reveal utilities beyond the shared sweep ────────
   The generic [data-anim] sweep stays exactly as it is. These are for the
   moments that deserve more than a fade: a headline arriving, a rule being
   drawn, a diagram being assembled. All of them are finished states in CSS
   and only get a start-state under .js-on, so nothing here can strand
   content. */

/* word-by-word mask reveal — the spans are created by script, so with no
   script the headline is simply a headline.

   The padding/negative-margin pair is what keeps `overflow:hidden` from
   cropping an ascender or the overhang of an italic serif: it gives the mask
   room on every side and then takes that room back out of the layout, so
   line breaking and metrics are exactly what they were. */
.rk-w{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding:.16em .14em .18em;margin:-.16em -.14em -.18em}
.rk-w > i{display:inline-block;font-style:inherit}

/* a rule that draws itself */
.js-on .rk-rule{transform:scaleX(0);transform-origin:left center}

/* ── 8. Micro-interaction: buttons carry the signal ─────
   One shared hover, so the primary action behaves the same everywhere. */
.btn-brand{box-shadow:0 1px 2px rgba(26,25,23,.08)}
.btn-brand:hover{box-shadow:var(--el-sig)}
.btn{position:relative;overflow:hidden}
.btn::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(28% 120% at var(--mx,50%) 50%,
             rgba(255,255,255,.22),transparent 70%);
  opacity:0;transition:opacity .3s var(--e-out);
}
.btn-brand::after,.btn-light::after{opacity:0}
.btn:hover::after{opacity:1}
.btn-ghost::after{background:radial-gradient(28% 120% at var(--mx,50%) 50%,
  rgba(212,43,48,.12),transparent 70%)}

/* ── 9. Reduced motion / script failure ─────────────────
   The drifting blooms stop and every scripted start-state is released. A
   still frame, not a blank one. */
@media (prefers-reduced-motion:reduce){
  .p5sky-blooms{transform:none}
  .js-on .rk-rule{transform:none}
}
html.reduce-motion .p5sky-blooms,
html.motion-failed .p5sky-blooms,
html.phase5-failed .p5sky-blooms{transform:none}
html.motion-failed .rk-rule,
html.phase5-failed .rk-rule,
html.reduce-motion .rk-rule{transform:none !important}

/* ═══════════════════════════════════════════════════════════
   10. THE HERO — daylight, and four systems standing in it
   ───────────────────────────────────────────────────────────
   The first screen used to be the console: a full-viewport graphite field
   with the copy set inside it. The console belongs to the chapters that
   demonstrate something — the system field, the close — and opening on it
   meant the front door was the darkest room in the building.

   The hero is a PLACE now. Sky, hills, warm ground, and the four working
   environments standing on that ground with one red signal running through
   them. The ground it ends on is the ground the rest of the page is painted
   in, so the first screen does not end, it continues.

   It is built as two things in flow, not as copy floating on a picture: the
   scene takes the room above, the words take the room below, and neither can
   land on the other whatever the copy or the viewport turns out to be.
   ═══════════════════════════════════════════════════════════ */
:root{
  /* daylight */
  --sky-1:#a9d9f2;   /* the top of the sky      */
  --sky-2:#cdeaf9;
  --sky-3:#eaf5fc;   /* the haze at the horizon */
  /* the warm ground the page is painted in */
  --land:#faf6ef;
  /* THE HERO'S GROUND IS THE FILM'S OWN. This film ends on warm sand rather
     than grass — sampled across the depths the seam can land at, it runs
     #c5b5a4 to #a89e94 — so the ground is the middle of that range and the
     copy stays DARK on it, which is both what the reference asks for and
     what the contrast demands: ink clears 6.7:1 here where white manages
     only 2.6:1. It then lightens toward the page's own cream under the
     words, so the hero does not end on a band edge at all. */
}

.p5hero{
  position:relative;
  /* the film may bleed past both edges; it must never widen the page */
  overflow:clip;
  min-block-size:100svh;
  /* ONE COMPOSITION. The film is the field the whole first screen is made of
     and the words sit INSIDE it, low, not in a panel underneath. So the
     section is a stage: the film is laid absolutely across it on a desktop
     and the copy is the only thing in flow, pushed to the bottom. */
  /* Stacked (narrow), the film leads and any slack falls at the BOTTOM, where
     it is already the page's cream and simply continues into it. Bottom-
     aligning there put the slack under the header instead — a cream void
     above the picture. On a desktop the copy is laid over the film, so the
     stage is bottom-aligned in the media query below. */
  display:flex;flex-direction:column;justify-content:flex-start;
  /* No top padding on a desktop. The picture starts at the very top of the
     screen and the header floats on its empty sky — a cream strip above it
     would announce that the daylight is a section on a page. The picture's
     top 13% carries nothing, and the header is 59px, so at desktop sizes it
     covers 6-9% of the picture and touches no content.

     A NARROW SCREEN CANNOT AFFORD THAT. Stacked, the picture is only as tall
     as the window is wide divided by its ratio — 211px on a 375pt phone — so
     the same 59px header covers 28% of it and cuts into the scene itself.
     There the picture is pushed clear of the header instead (below); a band
     that begins under a fixed header is what every page does, and it is far
     less of a lie than a clipped picture. */
  /* Less room under the words than a section would take: they belong to the
     picture, so they sit near its lower edge — which also opens the gap
     between them and the film's own labels above. */
  padding-block:0 clamp(1.4rem,.9rem + 1.8vw,2.4rem);
  /* THE SECTION IS THE PICTURE'S GROUND, THEN THE PAGE'S. The picture is
     contained rather than cropped, so what is not picture is this, and it has
     to be the render's own sand or the margin beside it is a different
     surface. Below the copy it ramps into the cream the rest of the document
     is painted in, so the screen still ends in the page rather than at an
     edge. It is also what the contrast audit sees, which is the honest
     answer: the words have to read on it even if the picture never paints. */
  background:linear-gradient(180deg,
    var(--hero-sky) 0%, var(--hero-sand) 62%,
    var(--hero-sand) 82%, var(--env-base) 100%);
  color:var(--ink);
  /* The supporting copy takes a darker grey inside the hero than it does on
     the page. The contrast audit composites ANCESTOR backgrounds, so it
     judges this text against the section's declared sand rather than against
     the cream the lightening actually puts behind it — and it is right to:
     if that overlay ever failed to paint, the words still have to read.
     #3a3833 clears the sand at 5.11:1 and the cream at 10.48:1. */
  --ink-2:#3a3833;
}

/* Stacked only: clear the fixed 59px header so it cannot clip the scene.
   Border-box keeps the section at 100svh; the content simply starts lower. */
@media (max-width:999px){
  .p5hero{padding-block-start:var(--hdr-h)}
}
/* STACKED, THE STAGE TAKES ITS OWN HEIGHT. 100svh is right when the film is
   laid across the whole stage and the words are inside it — the film fills
   the screen and the height is the composition. Stacked it is not: the film
   is 16:9 at the top, the words sit on the ground it dissolves into, and
   100svh then reserves whatever is left as empty cream below the actions —
   177px of it at 768x1024, 217px at 834x1112. That void is the "picture with
   a panel under it" reading coming back in through the bottom of the screen.

   So below 1000 the section is as tall as the film and the words, and the
   page's next screen begins where they end — which also lets a little of it
   show, and an edge that invites a scroll is worth more than a void that
   ends one. Nothing moves: the film, the headline and both actions keep the
   positions the suite measures; only the emptiness under them goes. */
@media (max-width:999px){.p5hero{min-block-size:auto}}

/* the old console hero's field, chrome and exit ramp are gone with the
   console; so is the four-line drawing grid it replaced */
.p5hero-grid{display:none}

/* ── the film, whole ───────────────────────────────────
   In flow at its own 16:9 on a narrow screen, and laid across the entire
   stage on a desktop (below). Either way it is CONTAINED, never cropped:
   the warehouse, the set, the application and the dome are the argument this
   screen is making, and a composition that cuts one of them off is making a
   different argument. */
.p5hero-media{
  position:relative;flex:0 0 auto;
  inline-size:100%;aspect-ratio:16 / 9;
  overflow:hidden;
  /* ONE GROUND, AND THE PICTURE DISSOLVES INTO IT.
     A landscape gradient stood here — sky blue, into hill green, into sand —
     because the hero used to be a film shot outdoors, and a margin beside it
     had to read as more landscape or it read as the end of a video.

     This scene is a studio render on flat cream. Its outer bands measure
     rgb(248 240 236) on the left and rgb(241 233 228) on the right, which is
     the page's own ground to within about six values of 255. There is
     nothing left to continue, so nothing is drawn: the margin simply IS the
     ground, the picture feathers into it at its own edges, and no boundary
     exists for the eye to find. Two stops rather than one because the
     render's own horizon darkens as it falls. */
  background:linear-gradient(180deg,var(--hero-sky),var(--hero-sand));
}

/* ── the copy, on the ground the scene ends in ─────────
   Headline left, supporting copy and both actions beside it: the picture is
   read first and the sentence lands under it, in one line of sight. */
.p5hero-in{position:relative;z-index:4;flex:0 0 auto;
  padding-block-start:clamp(.8rem,.5rem + 1.2vw,1.5rem)}
/* The two columns need real room. At 1024 they were 430px each: the lead ran
   to five lines and the two actions could not sit side by side, so they
   stacked and the columns fell out of balance. Below 1150 the copy is one
   column instead — the headline gets the full measure and sets in two lines,
   which is a better first screen than two cramped ones. */
@media (min-width:1150px){
  .p5hero-in{
    display:grid;align-items:end;
    grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
    column-gap:clamp(1.6rem,.6rem + 2.8vw,3.6rem);
  }
}
.p5hero-head,.p5hero-body{max-inline-size:min(100%,40rem)}
/* THE MEASURE IS WHAT BUYS THE FILM ITS HEIGHT. At 15ch this headline broke
   to four lines, and those four lines were 250px the band never got — the
   band is the flex item that takes what is left, so every line here is frame
   height thrown away. Given a wider measure it sets in three at the SAME
   size, and the film gains that line back. */
.p5hero h1{
  margin-block:clamp(.55rem,.45rem + .5vw,.9rem) 0;
  /* experience.css loads after phase5.css, so this is the declaration that
     wins — the restore to --t-h1 on 2026-09-05 had to happen in both. See
     the note at the same rule in phase5.css for what the old cap was for
     and what has to be re-measured if the headline grows again. */
  font-size:var(--t-h1);
  max-inline-size:19ch;color:var(--ink);
}
.p5hero .lead{max-inline-size:44ch;color:var(--ink-2)}
/* WIDER THAN 16:9, THE FOURTH LINE IS THE PROBLEM. Past that aspect the film
   fills the stage's height, which puts its own label row — ERP & WAREHOUSE
   OPERATIONS and the three beside it — exactly where the copy begins. At
   19ch inside a 40rem cap this headline sets in four lines on a 1900px
   window, and the fourth line is what pushes the block up until the kicker
   lands on top of "OPERATIONS".
   The window is offering a wider measure than the copy was taking, so the
   headline takes it and sets in three lines at the same size. The block is
   bottom-anchored, so one line less moves everything down by exactly that
   line — the kicker clears the labels, the type keeps its scale, and both
   actions stay where they were. */
@media (min-width:1000px) and (min-aspect-ratio:16/9){
  .p5hero-head{max-inline-size:min(100%,54rem)}
  .p5hero h1{max-inline-size:27ch}
}
.p5hero-cta{margin-block-start:clamp(1rem,.8rem + .9vw,1.5rem)}
/* On the film's green the secondary action is a white pill against a dark
   ground, so it no longer needs a drawn edge to be a button — it needs its
   own ink back, because the hero inverted --ink for the copy and the pill is
   white underneath. */
.p5hero .btn-light{--bg:#fffcfa;--fg:#1a1917;--bd:rgba(26,25,23,.10);
  box-shadow:var(--el-1)}
.p5hero .btn-light:hover{--bd:rgba(26,25,23,.22)}

/* The kicker was a light pill on cream: a surface tint and a hairline. On the
   green it becomes glass — the ground showing through, with a white edge —
   and the tag inside it inverts to match. */
/* A light pill again, now that the ground under it is sand rather than
   grass. Near-opaque rather than a tint: a translucent pill takes its
   contrast from whatever the film is doing behind it, and the film moves. */
.p5hero-kicker{
  background:rgba(255,253,250,.9);
  border-color:rgba(26,25,23,.10);
  color:var(--ink-2);box-shadow:var(--el-1);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
}

/* ── the header, floating on the sky ───────────────────
   Fixed rather than sticky on a Phase 5 page: sticky reserves its own height
   in the flow, which put a cream band above the first screen.

   The bar is opaque and flush with the top of the screen, so the scene simply
   runs under it — the same thing clay.com's landscape does. There is no scrim
   to tint any more; the only room the header still has to notice is the
   graphite of the close, where it goes to dark glass. */
.p5body .hdr{position:fixed;inset-inline:0;inset-block-start:0}
/* In graphite, over the close: a touch more transparent so the bar reads as
   tinted air rather than a second black rectangle, and a light hairline
   along its bottom edge so it has an edge at all against the dark. No blur
   — this bar only ever exists scrolled, and § 21 does not blur a scroll.
   .92 to .90 costs nothing that matters: the secondary ink still lands at
   6.4:1 composited on the ground underneath, well past the 4.5 the contrast
   audit holds every page to. */
html.hdr-dark .hdr-in{background:rgba(30,27,25,.9);
  box-shadow:inset 0 -1px 0 rgba(244,241,235,.09),
             0 10px 30px -18px rgba(0,0,0,.8)}
html.hdr-dark .nav-link{color:var(--con-ink-2)}
html.hdr-dark .nav-link:hover,html.hdr-dark .nav-item:hover > .nav-link,
html.hdr-dark .nav-link[aria-current="page"],html.hdr-dark .nav-link[aria-expanded="true"]{
  color:var(--con-ink);background:rgba(244,241,235,.09)}
html.hdr-dark .burger{background:transparent;border-color:rgba(244,241,235,.26)}
html.hdr-dark .burger span,
html.hdr-dark .burger span::before,
html.hdr-dark .burger span::after{background:var(--con-ink)}
.hdr-in,.nav-link,.burger{transition:background .35s var(--e-out),color .35s var(--e-out),
  border-color .35s var(--e-out),box-shadow .35s var(--e-out)}

/* Short viewports: spend the room on the words. The scene is already elastic
   — it is the flex item that gives — but below this height the headline has
   to come down too or the primary action goes under the fold.
   THE FLOOR IS 861, NOT 1000. Between 861 and 999 this rule used to stop and
   the phone rule below had not started, so a short window in that band got no
   step-down at all. 861 is that rule's own boundary — and the boundary three
   other rules in this file already use — so the two now meet instead of
   leaving a gap between them.
   The band is over the fold either way: it is a single column, the film takes
   its share first, and a window 861-999 wide and only 600-800 tall does not
   have room for a headline, a lead and two actions. Measured at 999x800, the
   actions ended 257px past the fold before any of this; leaving the gap open
   while --t-h1 came back on 2026-09-05 would have made that 353px, and
   closing it makes it 220px. Better, not fixed — the band needs a layout
   answer, not a type size, and it has been over the fold since long before
   the headline changed.
   Tall windows in the band are untouched and keep the full size: the height
   condition is what decides, and it always was. Measured at 960x1200 and
   900x1180, both clear the fold at 76px and 73px. */
@media (min-width:861px) and (max-height:840px){
  .p5hero{padding-block-end:clamp(1.8rem,1.4rem + 1.4vw,2.6rem)}
  .p5hero h1{font-size:clamp(2.1rem,1.1rem + 2.9vw,3.15rem);
    margin-block-start:clamp(.5rem,.4rem + .4vw,.8rem)}
  .p5hero .lead{font-size:1.02rem;line-height:1.5}
  .p5hero-media{min-block-size:clamp(200px,34svh,400px)}
}

/* ═══════════════════════════════════════════════════════════
   10b. THE HERO FILM — the rendered scene, playing
   ───────────────────────────────────────────────────────────
   The drawn scene's job is now done by a short animated render of the same
   four environments. It fills the band above the words and COVERS it, so the
   objects stay put whatever the band's height turns out to be: the film is
   16:9, the band is shorter, and cover-cropping trims sky and ground — never
   the row of objects, which is the point.

   Two states, and the still is the floor. `poster` is the film's own first
   frame — shown before playback, under reduced motion, and with no script at
   all — so this is never an empty rectangle. The poster and the video are
   fitted the same way, so the first frame of playback lands exactly where the
   still was and nothing jumps. */
/* THE BOX IS THE PICTURE, NOT THE STAGE, and everything below depends on it.
   `object-fit:contain` in a box of a different shape leaves slack in one
   axis, and a mask laid on that box then feathers somewhere the picture is
   not — which is a hard edge on one side and a ghost on the other. Declaring
   the picture's own ratio and sizing ONE axis makes the box exactly the
   rendered image, so the mask and the image share their edges by
   construction. 1672/941 is the file's true ratio; it is not quite 16/9, and
   at 2560 wide that difference is a pixel and a half of hairline. */
.p5hero-still{
  position:absolute;
  inset-block-start:0;inset-inline:0;margin-inline:auto;
  aspect-ratio:1672 / 941;
  --scale:100%;
  inline-size:var(--scale);block-size:auto;
  display:block;border:0;
  pointer-events:none;

  /* THE EDGES ARE FEATHERED, WHICH IS WHY THERE IS NO BOX.
     The picture is 16:9 and a window almost never is, so a margin beside it
     is unavoidable at nearly every size. Filling that margin was tried three
     ways — a mirror of the frame, a blurred copy of it, and a 41-stop
     gradient sampled from the edge column — and all three are answers to a
     landscape film, where the margin has to become more sky and more grass.
     On flat cream they each drew the one thing they existed to prevent: a
     visible rectangle, because a fill and a picture can only agree where
     their mappings agree, and past 16:9 they never do.

     Feathering removes the question. If the picture has no edge, the margin
     needs no filling, and every window is the same window.

     7% a side, 16% at the foot. Substantial content — the five pods, their
     props and their labels — measures between 4.7% and 95.4% of the width,
     so the side fades only ever reach hills and the outermost trees, which
     is exactly what a scene dissolving into a page should give up first. */
  --edge:7%;
  /* THE FOOT STARTS BELOW THE CONTENT, NOT ACROSS IT. Solid content ends at
     80.2% of the picture's height and its softest shadow at 81.6%; the fade
     begins at 84%, so it only ever dissolves empty ground. This is why the
     fade has to be measured against the PICTURE and not the stage — the old
     stage-relative blend could not know where the pods were, and washed the
     two lowest labels by a third. */
  --foot:16%;
  -webkit-mask-image:
    linear-gradient(90deg,transparent 0,#000 var(--edge),
                    #000 calc(100% - var(--edge)),transparent 100%),
    linear-gradient(180deg,#000 calc(100% - var(--foot)),transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(90deg,transparent 0,#000 var(--edge),
                    #000 calc(100% - var(--edge)),transparent 100%),
    linear-gradient(180deg,#000 calc(100% - var(--foot)),transparent 100%);
  mask-composite:intersect;
}

/* THE CREAM BLEND IS GONE, AND THAT IS THE POINT.
   A gradient of the page's cream lay over the bottom 56% of the stage so the
   film — green at its foot — could become the page with no visible join. It
   was doing two jobs: hiding a colour change, and giving the words a calmer
   field.

   Neither survives. The stage's ground IS the page's ground now, one flat
   --env-base, so there is no colour change to hide; and the words sit on the
   picture's own empty foot, which is that same cream. What the blend was
   still doing was washing the picture: measured on the page, MEDIA
   PRODUCTIONS and ON PREM AI sat 27-36% into it, which is why the two lower
   labels read pale against the three above them.

   The picture's own foot fade (--foot, on .p5hero-still) does the remaining
   work, and it is measured against the PICTURE rather than the stage, so it
   can be placed below the content instead of across it. */

/* Where the hero's ground hands back to the page's. The hero is a band of
   the film's green now, so it needs an ending: a short ramp at the very
   bottom, below the actions, into the cream the rest of the document is
   painted in. */
/* ── the film laid across the whole stage, on a desktop ──
   The stage is roughly 1.6:1 and the film is 1.78:1, so contained it fills
   the width and leaves a shallow band at the bottom. Absolute rather than in
   flow, so the copy overlaps it instead of standing under it — which is the
   difference between one composition and two sections. */
@media (min-width:1000px){
  .p5hero{justify-content:flex-end}
  .p5hero-media{position:absolute;inset:0;aspect-ratio:auto;z-index:0}
  /* THE PICTURE STOPS ABOVE THE WORDS, AND THAT IS A PROPERTY OF THIS
     RENDER. The film this replaced kept every podium between 33% and 62% of
     its height and handed the bottom third to the copy. This one does not:
     it carries five pods, and two of them — MEDIA PRODUCTIONS and ON PREM AI
     — put their label text at 74-78% of its height, which is exactly where
     the headline lands. Measured at six desktop sizes, the labels collided
     with the headline at five of them.

     AND THE COPY IS TWO THINGS, NOT ONE. The clearance below was first
     measured against the headline, which is wrong at most sizes: the
     right-hand column — lead, then actions — starts HIGHER than the headline
     does, and across a 51-viewport sweep it was the binding element in 36 of
     them. Measured against the headline alone, 84% looked clear everywhere;
     measured against whichever of the two sits higher, it overlapped at
     1280x640 and 1280x720 and ran to nothing at 1920x720. 74% is the largest
     value that clears BOTH at every size swept.

     ONE SCALE, TWO REGIMES. Below the picture's own ratio the width is what
     runs out; above it the height is. Naming the size once as --scale and
     letting each regime spend it on the axis that binds keeps the picture at
     the same fraction of the room it has either way, and means the steps
     below set a single value instead of six. */
  /* AND IT SITS DOWN OFF THE HEADER. Top-aligned, the picture starts at the
     very top of the stage and the slack all falls BELOW it — a gap between
     the lowest label and the copy that runs from 45px to over 600px
     depending on the window, while the scene itself is jammed against the
     bar. Dropping it spends that gap on the top instead, where it reads as
     air rather than as a hole.

     How much is not a free choice: the offset comes straight out of the
     clearance, and the clearance is 16px at 1100x640. So it is a share of
     the stage rather than a number of pixels, and it is larger only where
     the room provably exists — measured, every cell at 950px and taller has
     at least 62px of slack, and most have three times that. */
  /* AND IT NEVER STARTS ABOVE THE HEADER. A share of the stage was enough
     while the render carried 13% of empty sky at its top — the bar sat in
     that band and touched nothing. This one begins its content at 4.7%, so
     3% of a 900px stage put the dashboard 6px behind the bar and 12px behind
     it at 1366x768. `max()` makes the header's own height the floor: the
     picture starts below the bar or lower, never above it, whatever the
     window does. The percentage still wins where there is room for it. */
  .p5hero-still{--scale:65%;inset-block-start:max(var(--hdr-h),3%)}
  @media (min-height:950px){ .p5hero-still{inset-block-start:max(var(--hdr-h),6%)} }
  /* past the picture's own ratio the height is what binds, so the scale is
     spent there and the width follows from the aspect. `inset-inline:0` with
     `margin-inline:auto` is what centres it once the width stops being
     stated. */
  @media (min-aspect-ratio:1672/941){
    .p5hero-still{inline-size:auto;block-size:var(--scale)}
  }

  /* AND IT SHRINKS AGAIN WHEN THE ROOM RUNS OUT, WHICH IS A QUESTION OF THE
     COPY'S HEIGHT AND NOT THE WINDOW'S. 84% clears the labels at every
     ordinary desktop size — 1366x768, 1440x900, 1600x900, 1920x1080 and
     2560x1440 all clear by 34 to 118px — and none of them should be touched.

     What breaks it is the headline WRAPPING. Below about 1200px it takes a
     fourth line and the copy block stops being ~250px tall and becomes ~400;
     on a short screen that is most of the height, and what is left above it
     is less than the picture needs. So the steps are bounded on BOTH axes.
     Bounding on height alone was tried and rejected: it shrank 1366x768,
     which had clearance already and needed no help.

     The first rule is the exception — a very short window at any width,
     where even three lines of copy leave too little. The narrow rules after
     it win where both apply. Every bound was read off the laid-out page
     across a grid of widths and heights. Below 1000px the layout stacks and
     the words stand under the picture, where none of this arises. */
  /* Two steps, not one. Flooring the offset at the header cost 38px of the
     clearance below on a short window — the picture starts lower, so it ends
     lower. Paid back out of the scale, where there was room for it. */
  @media (max-height:900px){ .p5hero-still{--scale:62%} }
  @media (max-height:780px){ .p5hero-still{--scale:50%} }
  @media (max-height:680px){ .p5hero-still{--scale:42%} }
  @media (max-width:1200px){
    @media (max-height:860px){
      .p5hero-still{--scale:59%;inset-block-start:var(--hdr-h)}
    }
    /* PAST HERE THE PICTURE IS SMALL ENOUGH THAT THE HEADER EATS INTO IT.
       The header floating on the picture's empty sky is only free while the
       picture is big: it is a constant 59px, so it covers 5-9% of a full-size
       one — inside the 13% at the top that carries nothing — but 21-23% of a
       picture shrunk to clear the copy in a cramped window, which reaches
       into the scene. Below these bounds it is pushed clear of the header,
       and the scale is cut again to pay for the height that costs. */
    @media (max-height:780px){
      .p5hero-still{--scale:44%;inset-block-start:var(--hdr-h)}
    }
    @media (max-height:700px){
      .p5hero-still{--scale:30%;inset-block-start:var(--hdr-h)}
    }
  }
  .p5hero-in{padding-block-start:0}
  /* THE COPY TRACKS THE FILM, NOT THE TEXT MEASURE. `.wrap` caps at 1230 and
     centres, which on a 1920 screen pushed the headline a fifth of the way
     in — reading as a column laid over a picture rather than as part of it.
     A gutter taken from the viewport keeps it about a twelfth in at every
     width, which is where a caption sits on a photograph. */
  .p5hero-in{max-inline-size:none;padding-inline:clamp(1.15rem,8vw,11rem)}
  /* The copy sits low and left, the way a caption sits under a picture
     rather than beside it. Clay puts its headline at about two thirds down
     and a tenth in; this lands in the same neighbourhood by way of the
     page's own measure, which is where the rest of the site is set. */
  .p5hero-in{padding-block-end:clamp(.5rem,.2rem + 1vw,1.4rem)}
}

/* THE SIDE GAPS ARE FILLED BY THE FILM ITSELF NOW.
   What stood here mirrored the frame about its own edge to fill the gap a
   16:9 film leaves in a wider window. The colour matched to 7 of 255 — but a
   mirror is a mirror: the hills unfolded back on themselves and it read as a
   reflection down each side of the screen, which the client saw at once.

   There is no footage in that gap, so anything put there is invented. The
   answer is to stop inventing and use the film's own pixels — §33 covers the
   stage with the film at the aspects where the gap appears. Measured across
   three frames, the film's content (podiums, props, labels) sits between 33%
   and 62% of its height; filling a 2:1 window costs 12% of the height and an
   ultrawide 2.33:1 costs 24%, all of it sky and empty ground. No scene and
   no label is ever touched.

   Below 16:9 the gap is top-and-bottom instead, where `cover` would crop the
   sides and the outermost podiums live — so that case stays CONTAINED and
   keeps the blurred fill above, which measured 3 of 255 across that seam. */


/* The ground LIGHTENS under the words, from the film's sand into the cream
   the rest of the document is painted in. One gradient does two jobs: it
   gives the copy a paler, calmer field to sit on — ink reaches 9:1 by the
   actions — and it hands the hero back to the page with no band edge at all,
   which is what the old cream-to-green cut needed a separate ramp for.

   ABOVE the film, not behind it. Behind it, the overlay only emerged below
   the seam — already part-lightened — and that measured as a six-value step.
   Crossing the join, one gradient covers both sides and a step is
   arithmetically impossible; it also hazes the film's own foreground, which
   is what distance does to ground anyway. */
.p5hero::before{content:none}
.p5hero-media{z-index:1}

/* On a phone the film gives the screen back to the words: the band is the
   elastic part of this layout, so it shrinks first and the headline and both
   actions stay above the fold. The crop rides up a touch so the row of
   objects still reads at the smaller size. */
@media (max-width:860px){
  .p5hero-media{min-block-size:clamp(190px,30svh,300px)}
}
/* A small phone in a short viewport — a 4.7" screen, or any phone with the
   browser chrome showing. The scene is the elastic part of this layout and it
   gives first; after that the headline comes down a step. The order is
   deliberate: a smaller picture is a smaller picture, a headline pushed under
   the fold is a first screen that says nothing. */
@media (max-width:860px) and (max-height:720px){
  /* The film is sized by its own ratio now, so the old min-height lever does
     nothing — the room has to come out of the type instead. It is the film
     that must not shrink here: contained at this width it is already only
     two hundred pixels tall, and cropping it to save space would cut the
     very scenes this screen exists to show. */
  .p5hero-in{--tight:1}
  .p5hero{padding-block-end:clamp(1.4rem,1.1rem + 1.4vw,2rem)}
  .p5hero-in{padding-block-start:clamp(.7rem,.5rem + 1vw,1.1rem)}
  .p5hero h1{font-size:clamp(1.95rem,1.25rem + 2.4vw,2.55rem);
    margin-block-start:clamp(.5rem,.4rem + .5vw,.8rem)}
  .p5hero .lead{font-size:.95rem;line-height:1.38}
  .p5hero-cta{margin-block-start:clamp(.7rem,.55rem + .6vw,1rem);gap:.5rem}
  .p5hero-kicker{padding-block:.28rem;font-size:.86rem}
  .p5hero-in{row-gap:.6rem}
}

/* ── 11. Flow Engine, drawn on the console ─────────────── */
 /* No will-change here. On an SVG group it buys nothing the compositor can
    use, and it costs a layer per group. */
.fe-layer{}
.fe-arc{fill:none;stroke:rgba(var(--fe-ink),.07);stroke-width:1}
.fe-dot{fill:rgba(var(--fe-ink),.07)}
.fe-plate{stroke:rgba(var(--fe-ink),.14);stroke-width:1.1}
.fe-well{fill:#eae4d8;stroke:rgba(var(--fe-ink),.10);stroke-width:1}
.fe-hair{fill:none;stroke:rgba(var(--fe-ink),.14);stroke-width:1}
.fe-div{fill:none;stroke:rgba(var(--fe-ink),.14);stroke-width:1}
.fe-flow{fill:none;stroke:rgba(var(--fe-ink),.13);stroke-width:1;stroke-dasharray:2 6}
.fe-tick{fill:none;stroke:rgba(var(--fe-ink),.40);stroke-width:1}
.fe-frame-edge{fill:none;stroke:rgba(var(--fe-ink),.26);stroke-width:1.1}
.fe-mute{fill:rgba(var(--fe-ink),.62)}
.fe-mute-2{fill:rgba(var(--fe-ink),.28)}
.fe-bar{fill:rgba(var(--fe-ink),.82)}
.fe-label{font-family:var(--mono);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;fill:currentColor}
.fe-cap{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;
  text-transform:uppercase;fill:rgba(var(--fe-ink),.62)}
.fe-title{font-family:var(--sans);font-size:12.5px;font-weight:700;
  letter-spacing:-.014em;fill:rgba(var(--fe-ink),.92)}
.fe-sig{fill:var(--sig)}
.fe-acc{fill:currentColor}
.fe-acc-s{stroke:currentColor;fill:none;stroke-width:1.65;stroke-linecap:round}
.fe-conn{stroke-width:1.45}
.fe-graph{stroke-width:1.55}

.fe-spine{fill:none;stroke-width:2;stroke-linecap:round}
 /* The glow under the trail is a second, wider, fainter copy of the same
    path rather than a drop-shadow filter: a filtered stroke whose dash offset
    changes every frame is re-filtered every frame. */
.fe-trail{fill:none;stroke:var(--sig);stroke-width:2.2;stroke-linecap:round;opacity:.95}
.fe-trail-glow{fill:none;stroke:var(--sig);stroke-width:7;stroke-linecap:round;opacity:.18}
.fe-branch{fill:none;stroke:rgba(var(--fe-ink),.17);stroke-width:1;
  transition:stroke .4s var(--e-out)}
.fe-branch.lit{stroke:var(--sig)}
.fe-station{fill:#fffdfa;stroke:rgba(var(--fe-ink),.30);stroke-width:1.5;
  transition:fill .35s var(--e-out),stroke .35s var(--e-out)}
.fe-station.lit{fill:var(--sig);stroke:var(--sig)}
.fe-pulse{fill:var(--sig-2)}
.fe-halo{fill:var(--sig);opacity:.22}
.fe-outcome-halo{fill:var(--sig);opacity:.14}
.fe-outcome{stroke:rgba(255,255,255,.22);stroke-width:1}

/* Under no script the trail is the whole spine — the finished frame of the
   journey rather than an empty track. Script takes it back to zero on its
   first frame and drives it from the pulse. */
.js-on .fe-trail,.js-on .fe-trail-glow{stroke-dasharray:1000;stroke-dashoffset:1000}

/* ── 12. THE FOUR SYSTEMS, AS A STACK ───────────────────
   The chapter was one very tall dark console with four demos inside it.
   Reading it meant scrolling past three systems to reach the fourth, and the
   whole thing was a single black block cut into the page.

   It is four panels now, and they stack: each sticks under the header, the
   next slides up over it, and the one behind recedes and dims with its top
   edge still showing. Scroll position is the control; the lips along the top
   are the progress indicator. Every system gets the whole screen while it is
   the one being read.

   The section itself is back on the ground — heading in daylight, panels as
   objects standing on it. */
.p5field{
  background:none;background-color:transparent;
  margin-inline:0;border-radius:0;box-shadow:none;overflow:visible;
  padding-block:clamp(3rem,2.2rem + 3.4vw,5rem) clamp(2.4rem,1.8rem + 2.6vw,4rem);
  /* The section used to BE the console and set the console's ink tokens on
     itself. It is daylight now, so they have to be handed back — a light
     token on a light ground is invisible text, not a subtle one. The dark
     tokens move to the panels, which is where the dark surface went. */
  color:var(--oat-950);
  --ink:var(--oat-950);--ink-2:var(--oat-800);--ink-3:var(--oat-750);
  --line:var(--oat-400);--line-2:var(--oat-300);
  --surface:var(--oat-50);--surface-2:var(--oat-100);
  --brand:var(--pro);--brand-2:var(--pro-2);--on-brand:var(--oat-50);
}
.p5field::before,.p5field::after{display:none}
.p5field-grid,.p5field-seam{display:none}
.p5field-head .lead{color:var(--ink-2)}
.p5field .eyebrow{color:var(--brand-text,var(--sig))}
.p5field-note{margin-block-start:clamp(1.6rem,1.2rem + 1.6vw,2.6rem);
  padding-inline-start:1rem;border-inline-start:2px solid var(--line);
  color:var(--ink-2);font-size:var(--t-sm);line-height:1.65;max-inline-size:70ch}

/* ── the stack ── */
.p5stack{position:relative;min-inline-size:0;--lip:12px;--stack-top:5.3rem}
@media (max-width:860px){.p5stack{--lip:9px;--stack-top:4.9rem}}

.p5demo{
  position:sticky;
  inset-block-start:calc(var(--stack-top) + var(--i,0) * var(--lip));
  margin-block-end:clamp(1.4rem,1rem + 2vw,2.6rem);
  scroll-margin-top:7rem;min-inline-size:0;
  --fam:var(--sig);--fam-soft:rgba(212,43,48,.16);
}
.p5demo:last-child{margin-block-end:0}
/* see the note in experience.js: the overlap is only affordable promoted */
.p5stack.live .p5demo-inner{will-change:transform}

.p5demo-inner{
  /* No overflow clip. The radius clips the background for free, the dim
     overlay inherits it, and nothing inside reaches the edge — while a
     rounded clip on a panel-sized box is re-applied on every frame of the
     scrub that covers it. */
  position:relative;overflow:visible;
  color:var(--con-ink);
  --ink:var(--con-ink);--ink-2:var(--con-ink-2);--ink-3:var(--con-ink-3);
  --line:var(--con-line);--line-2:var(--con-line-2);
  --surface:var(--con-3);--surface-2:#2a2725;
  --brand:var(--sig-2);--on-brand:#2a0b0c;
  border-radius:var(--con-r);
  /* A stuck panel has to finish inside the window it sticks in, or the next
     one slides over copy nobody has read yet. At 900px that window is about
     770px once the header and the lips are paid for, so this is sized to
     land inside it. */
  min-block-size:min(72svh,700px);
  padding:clamp(1.05rem,.8rem + 1.1vw,1.7rem);
  display:grid;gap:clamp(.8rem,.65rem + .7vw,1.15rem);align-content:center;
  border:1px solid rgba(244,241,235,.08);
  box-shadow:0 2px 8px -2px rgba(26,25,23,.2),0 44px 90px -44px rgba(26,25,23,.55);
}
/* The family's own light, and its measurement grid, inside its panel.

   The grid is a background layer here rather than a masked child element.
   Four masked, panel-sized children being composited while three of them
   overlap cost more than everything else in this chapter — and a repeating
   linear-gradient on a background that is already being painted is free. */
.p5demo-inner{
  background-image:
    linear-gradient(90deg,var(--con-line-2) 1px,transparent 1px),
    radial-gradient(58% 42% at 84% 6%,color-mix(in srgb,var(--fam) 13%,transparent),transparent 68%),
    radial-gradient(46% 40% at 2% 96%,rgba(212,43,48,.10),transparent 70%),
    linear-gradient(180deg,var(--con-3),var(--con-1) 30%,var(--con-2));
  background-size:clamp(56px,6vw,104px) 100%,auto,auto,auto;
}
/* The shade a panel takes while the next one covers it. Two rules decided its
   shape. It is a flat overlay rather than a filter, because a filter
   re-rasterises the whole panel on every frame of the scrub and a panel is
   most of a screen. And it is a real element whose OPACITY is animated rather
   than a pseudo-element driven by a custom property: opacity is a compositor
   property, a custom property is not, and the difference measured thirteen
   frames a second against thirty-four. */
.p5demo-dim{
  position:absolute;inset:0;display:block;pointer-events:none;z-index:6;
  background:#0a0908;opacity:0;border-radius:inherit;
}
.p5stack.live .p5demo-dim{will-change:opacity}
.p5demo-top{position:relative;z-index:1;max-inline-size:66ch}

.p5demo[data-family="operations"]{--fam:var(--fam-operations);--fam-soft:rgba(18,171,102,.17)}
.p5demo[data-family="media"]{--fam:var(--fam-media);--fam-soft:rgba(242,182,34,.17)}
.p5demo[data-family="applications"]{--fam:var(--fam-applications);--fam-soft:rgba(10,131,245,.17)}
.p5demo[data-family="enterprise-ai"]{--fam:var(--fam-enterprise-ai);--fam-soft:rgba(131,88,244,.17)}

.p5demo h3{font-size:clamp(1.35rem,1.05rem + 1.5vw,2.35rem);letter-spacing:-.034em;
  line-height:1.05;color:var(--con-ink)}
.p5demo-fam{color:var(--fam)}
.p5demo-lead{color:var(--con-ink-2);margin-block-end:0;max-inline-size:62ch}
.p5demo-note{color:var(--con-ink-3);border-inline-start-color:rgba(244,241,235,.16);
  margin-block-start:0;position:relative;z-index:1}

/* the console inside the panel — the panel's screen */
.p5console{
  position:relative;z-index:1;
  background:linear-gradient(180deg,#191716,#121110);
  border:1px solid rgba(244,241,235,.09);
  box-shadow:0 1px 0 rgba(255,255,255,.035) inset,0 22px 48px -26px rgba(0,0,0,.8);
  transition:border-color .5s var(--e-out),box-shadow .5s var(--e-out);
}
.p5demo.on .p5console{border-color:color-mix(in srgb,var(--fam) 22%,rgba(244,241,235,.09))}
.p5console-bar{background:rgba(255,255,255,.02);color:var(--con-ink-3)}

/* ── the chapter index, now on the light ground ──
   Narrower, and without its rail. Two red progress lines seventy pixels
   apart — the page thread in the gutter and the chapter rail here — read as
   one line that had been drawn twice; the marks alone say which of four this
   is, and the width they give back is what lets a six-stage workflow lay its
   tabs out without scrolling. */
.p5index button{color:var(--ink-3);padding-inline:.3rem .2rem;gap:.5rem}
.p5index button:hover{color:var(--ink-2);background:rgba(26,25,23,.05)}
.p5index li.on button{color:var(--ink)}
.p5index li .mk{background:var(--pane-solid);border-color:rgba(26,25,23,.22)}
.p5index li.on .mk{background:var(--sig);border-color:var(--sig)}
.p5index .rail{display:none}
.p5index ol{padding-inline-start:1rem}
@media (min-width:1040px){
  .p5field-body{grid-template-columns:10.5rem minmax(0,1fr);
    gap:clamp(1.5rem,.5rem + 2vw,2.6rem)}
  .p5index{inset-block-start:calc(var(--stack-top,5.6rem) + 1.4rem)}
}

/* ── panels arrive as they are reached ──
   Guarded by .js-on, so no script, a failed script and reduced motion all
   land on a panel that is simply finished. The class is applied on arrival
   AND on a watchdog, so a panel cannot be stranded blank. */
.js-on .p5demo-top > *,
.js-on .p5demo .p5console,
.js-on .p5demo .p5demo-note{opacity:0;transform:translate3d(0,20px,0);
  transition:opacity .62s var(--e-out),transform .62s var(--e-out)}
.js-on .p5demo.shown .p5demo-top > *,
.js-on .p5demo.shown .p5console,
.js-on .p5demo.shown .p5demo-note{opacity:1;transform:none}
.js-on .p5demo-top > *:nth-child(2){transition-delay:.06s}
.js-on .p5demo .p5console{transition-delay:.12s}
.js-on .p5demo .p5demo-note{transition-delay:.2s}
html.reduce-motion .p5demo-top > *,html.motion-failed .p5demo-top > *,
html.experience-failed .p5demo-top > *,
html.reduce-motion .p5console,html.motion-failed .p5console,
html.experience-failed .p5console,
html.reduce-motion .p5demo-note,html.motion-failed .p5demo-note,
html.experience-failed .p5demo-note{opacity:1 !important;transform:none !important}

@media (max-width:1039px){
  /* no index column; the panels are the whole width */
  .p5field-body{grid-template-columns:minmax(0,1fr)}
}
/* the console's own paddings, tuned so a six-stage workflow fits the window */
.p5field .p5stage{padding:clamp(.7rem,.5rem + .9vw,1.2rem)}
.p5field .p5caption{min-block-size:4.6rem;padding-block:.85rem .95rem}
.p5field .p5steps{padding:.6rem}

/* SHORT VIEWPORTS.
   A stuck panel that is taller than the window it sticks in is not a design
   choice, it is content the reader cannot reach: sticky pins the top, so the
   overflow at the bottom never scrolls into view. On a shorter screen the
   panel spends less on type and padding rather than hiding its last lines. */
@media (min-width:861px) and (max-height:870px){
  .p5demo-inner{padding:1.05rem 1.15rem;gap:.75rem}
  .p5demo h3{font-size:clamp(1.2rem,1rem + 1.1vw,1.75rem)}
  .p5demo-lead{font-size:.94rem;line-height:1.5}
  .p5field .p5stage{padding:.65rem}
  .p5field .p5steps{padding:.45rem}
  .p5field .p5caption{min-block-size:3.8rem;padding-block:.7rem .8rem}
  .p5stack{--stack-top:5rem;--lip:10px}
}
/* and one tier tighter for a 768-tall laptop, which is still common */
@media (min-width:861px) and (max-height:800px){
  .p5demo-inner{padding:.95rem 1.1rem;gap:.68rem}
  .p5demo-lead{font-size:.92rem}
  .p5field .p5caption{min-block-size:3.5rem;padding-block:.6rem .7rem}
  .p5stack{--stack-top:4.75rem;--lip:9px}
}
/* Below this there is no honest way to stack: a panel cannot be made to fit
   the window without shrinking the workflow diagram to nothing. The panels
   flow instead — same content, same order, nothing unreachable. */
@media (min-width:861px) and (max-height:719px){
  .p5demo{position:relative;inset-block-start:auto}
  .p5demo-inner{min-block-size:0;align-content:start}
}

@media (max-width:860px){
  /* Below the two-column layout a panel is taller than the screen it would
     stick in, so the next one would slide over copy nobody had reached. The
     panels simply flow instead: same content, same order, no stacking. */
  .p5demo{position:relative;inset-block-start:auto;
    margin-block-end:clamp(1rem,.8rem + 1.4vw,1.8rem)}
  .p5demo-inner{min-block-size:0;border-radius:1.1rem;align-content:start}
}

/* ── 13. THE CLOSE — the one place the page really goes dark
   A single ending: the close and the footer are one deep zone entered
   through a long ramp, not two black bands with a cream strip between
   them. The strip was the last literal instance of the banding. */
.p5close{
  position:relative;
  /* Sideways only. `overflow: clip` on both axes — which is what the section
     carried — clipped the ramp that reaches up out of the section, so the
     ending arrived as a hard edge with a ten-pixel fade instead of the two
     hundred it was drawing. */
  overflow-x:clip;overflow-y:visible;
  background:linear-gradient(180deg,var(--con-2),var(--oat-950) 76%);
  background-color:var(--con-2);
  /* the dusk band above carries the lead-in now, so the section itself opens
     closer to its own content */
  padding-block:clamp(2.6rem,2rem + 2.6vw,4.4rem) clamp(3rem,2.2rem + 3.4vw,5rem);
  --ink:var(--con-ink);--ink-2:var(--con-ink-2);--ink-3:var(--con-ink-3);
  --line:var(--con-line);--line-2:var(--con-line-2);
}
/* ── THE DUSK — the transition band into the ending ──
   A block in the flow, not an overlay reaching up out of the section. That
   distinction is the whole fix: an overlay begins inside whatever block comes
   before it, and on this page that was sixty pixels inside the verification
   card, which sat under a gradient it had no part in and looked faded and
   dirty for it. A band owns its own space and cannot touch a neighbour.

   Four things happen across it, all from the vocabulary the rest of the page
   already uses: the ground darkens and the measurement grid fades out with
   it. A signal used to descend through the band and land on a node at the
   threshold; the client removed both on 2026-08-27. */
.p5dusk{
  position:relative;display:block;pointer-events:none;
  block-size:clamp(6.5rem,4rem + 7vw,10.5rem);
  margin-block-start:clamp(1.5rem,1rem + 2vw,3rem);
  background:linear-gradient(180deg,
    rgba(20,19,18,0) 0%,
    rgba(20,19,18,.06) 26%,
    rgba(20,19,18,.24) 52%,
    rgba(20,19,18,.58) 74%,
    rgba(20,19,18,.86) 90%,
    var(--con-2) 100%);
}
/* the ground's grid, carried into the band and extinguished with it */
.p5dusk-grid{
  position:absolute;inset:0;display:block;
  max-inline-size:var(--wrap);margin-inline:auto;
  padding-inline:clamp(1.15rem,.5rem + 2.4vw,2.5rem);
  background-image:linear-gradient(90deg,rgba(26,25,23,.055) 1px,transparent 1px);
  background-size:calc((100% - 2 * clamp(1.15rem,.5rem + 2.4vw,2.5rem)) / 6) 100%;
  background-position:clamp(1.15rem,.5rem + 2.4vw,2.5rem) 0;
  background-repeat:repeat-x;
  mask-image:linear-gradient(180deg,#000,transparent 62%);
}
/* THE DESCENDING SIGNAL IS GONE, and its two rules with it: a red hairline
   down the centre of the band and the red node it landed on. Removed on
   2026-08-27 — the last of the signal motif, after the rail in the systems
   diagram, the panel readout bar and the four slide status dots. The band
   keeps the two jobs that matter: the ground darkens across it and the
   measurement grid is extinguished, so the ending is entered rather than
   arrived at. */
.p5close .lead{color:var(--con-ink-2)}
.p5close-scene svg{opacity:1}
.p5page ~ * .ftr,
.p5body .ftr{margin-top:0;background:var(--oat-950)}

/* ── 14. The capability rail, alive ─────────────────────
   Four rows on a hairline was accurate and inert. Each row now carries the
   family's own working glyph, the row lifts onto a pane as it is pointed
   at, and the signal bar on the left grows as the reader reaches it. */
.p5fam-list{border-block-start:0}
.p5fam{
  border-block-end:1px solid rgba(26,25,23,.10);
  border-radius:var(--r-md);
  padding-inline:clamp(.6rem,.4rem + .8vw,1.1rem);
  margin-inline:calc(clamp(.6rem,.4rem + .8vw,1.1rem) * -1);
  transition:background .4s var(--e-out),box-shadow .4s var(--e-out),
             transform .4s var(--e-out);
}
.p5fam:first-child{border-block-start:1px solid rgba(26,25,23,.10)}
.p5fam::before{
  background:linear-gradient(90deg,
    color-mix(in srgb,var(--fam) 9%,transparent),
    color-mix(in srgb,var(--fam) 3%,transparent) 42%,transparent 76%);
  inset-inline:0;
}
.p5fam:hover,.p5fam:focus-within{
  background:var(--pane);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:var(--el-2),var(--pane-edge);
  transform:translateX(2px);
}
.p5fam::after{inset-inline-start:0;inline-size:3px;inset-block:18%}
.p5fam-t .sq{box-shadow:0 0 0 0 color-mix(in srgb,var(--fam) 30%,transparent)}
.p5fam-glyph{display:none}
@media (min-width:1040px){
  .p5fam{grid-template-columns:3rem minmax(0,15.5rem) minmax(0,1fr) 6.5rem auto;
    gap:.35rem 1.6rem}
  .p5fam-glyph{display:block;inline-size:6.5rem;block-size:3.1rem;
    justify-self:end;opacity:.9;
    transition:opacity .35s var(--e-out)}
  .p5fam:hover .p5fam-glyph{opacity:1}
}
.p5fam-glyph svg{inline-size:100%;block-size:100%;overflow:visible}
.gl-line{fill:none;stroke:rgba(26,25,23,.22);stroke-width:1.2;stroke-linecap:round}
.gl-fill{fill:var(--fam)}
.gl-soft{fill:color-mix(in srgb,var(--fam) 26%,transparent)}
.gl-stroke{fill:none;stroke:var(--fam);stroke-width:1.4;stroke-linecap:round}

/* ── 15. The light blocks, given depth ──────────────────
   The stretch between the rail and the field used to be flat cream with
   hairlines on it. Same content, layered: panes, drawn rules, a signal that
   travels the lifecycle strip. */
.p5page .stat{padding-block:.2rem}
.p5page .stat::before{transition:transform .6s var(--e-out);transform-origin:top}
.p5page .stats{border-block-start:0;position:relative;padding-block-start:1.15rem}
.p5page .stats::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;
  block-size:1px;background:rgba(26,25,23,.14)}
.p5page .stats::after{content:"";position:absolute;inset-block-start:0;inset-inline-start:0;
  block-size:1px;inline-size:var(--rule,0%);background:var(--sig);
  box-shadow:0 0 10px 0 rgba(212,43,48,.5);transition:inline-size 1.2s var(--e-out)}

/* the published-capabilities entries */
.p5page .card-plain{border-block-start:1px solid rgba(26,25,23,.12);
  border-radius:var(--r-md);padding:1.5rem 1rem 1.6rem;
  margin-inline:-1rem;
  transition:background .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5page .card-plain:hover{background:var(--pane);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:var(--el-1),var(--pane-edge)}
.p5page .card-plain .ico-badge{border-color:rgba(26,25,23,.14);
  background:color-mix(in srgb,var(--acc,var(--brand)) 8%,transparent);
  transition:transform .35s var(--e-out),background .35s}
.p5page .card-plain:hover .ico-badge{transform:translateY(-2px) rotate(-4deg);
  background:color-mix(in srgb,var(--acc,var(--brand)) 15%,transparent)}

/* ── THE VERIFICATION NOTE, MADE SECONDARY ──────────────
   "How to read this site" is required and its wording is fixed, but on the
   homepage it was carrying a pane, a shadow, a coloured edge and a bold
   label — the visual weight of a feature, for what is a footnote about how to
   read the claims above it.

   It keeps every word, stays in the document where a reader will meet it, and
   is not hidden behind any interaction. What it loses is the card: a hairline
   rule, a quiet monospace label and a narrower measure, which is how a
   footnote is set. Colour is unchanged — the text still passes contrast on
   the ground; the weight comes out of the layout, not the ink. */
/* `.snote.snote-verification` rather than `.snote-verification`: the pane
   treatment below is `.p5page .snote`, the same specificity, and later in the
   file — so the single class lost the tie and the card kept its shadow. */
.p5page .snote.snote-verification{
  background:none;-webkit-backdrop-filter:none;backdrop-filter:none;
  border:0;border-radius:0;box-shadow:none;
  border-block-start:1px solid rgba(26,25,23,.16);
  padding:1.15rem 0 0;max-inline-size:78ch;
}
.p5page .snote.snote-verification::before{display:none}
.p5page .snote-verification .snote-label{
  font-family:var(--mono);font-size:.75rem;letter-spacing:.13em;
  font-weight:500;color:var(--ink-3);margin-block-end:.5rem}
.p5page .snote-verification p{font-size:var(--t-sm);color:var(--ink-2);
  line-height:1.7;max-inline-size:none}
.p5page .snote-verification .snote-link{font-size:var(--t-xs);color:var(--ink-2);
  font-weight:600;margin-block-start:.7rem}
.p5page .snote-verification .snote-link:hover{color:var(--sig)}
.p5page .snote-verification .snote-link .ico{inline-size:.9rem;block-size:.9rem}
/* and it sits in the page's quietest column, not the full measure */
.p5page .sec:has(> .wrap > .snote-verification) .wrap{max-inline-size:var(--wrap)}

/* the scope notes become real callouts on the ground */
.p5page .snote{background:var(--pane);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border:1px solid var(--pane-line);border-inline-start:0;
  border-radius:var(--r-md);box-shadow:var(--el-1),var(--pane-edge);
  padding:1.3rem 1.5rem 1.35rem;position:relative;overflow:hidden}
.p5page .snote::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;
  inline-size:3px;background:var(--sig);
  transform:scaleY(var(--draw,1));transform-origin:top;
  transition:transform .75s var(--e-out)}
.p5page .snote-verification::before{background:var(--berry-500)}
.p5page .snote-design::before{background:var(--tang-500)}
.p5page .snote-result::before{background:var(--matcha-600)}
.js-on .p5page .snote{--draw:0}

/* The warehouse lifecycle: a signal travels the strip as it is read.

   Ten stages on an auto-fit grid resolved to eight columns and left six empty
   cells sitting in the second row — the lifecycle looked like a table someone
   had abandoned halfway. Ten is 5×2 and 3×4 and 2×5; say so. */
.p5page .pstrip{background:transparent;border-color:rgba(26,25,23,.12);
  box-shadow:var(--el-1);border-radius:var(--r-md);overflow:hidden;
  grid-template-columns:repeat(2,minmax(0,1fr))}
@media (min-width:560px){.p5page .pstrip{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (min-width:900px){.p5page .pstrip{grid-template-columns:repeat(5,minmax(0,1fr))}}
/* the single continuous rule belonged to a single row */
.p5page .pstrip::before{display:none}
.p5page .pstep{background:var(--pane);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  transition:background .35s var(--e-out)}
.p5page .pstep:hover{background:var(--pane-solid)}
.p5page .pnum{background:transparent;color:var(--ink-3);transition:color .4s}
.p5page .pstep.lit .pnum{color:var(--sig)}
.p5page .pstep::after{content:"";position:absolute;inset-block-start:0;inset-inline:0;
  block-size:2px;background:var(--sig);transform:scaleX(0);transform-origin:left;
  transition:transform .5s var(--e-out)}
.p5page .pstep.lit::after{transform:scaleX(1)}

/* Larion's two cells */
.p5page .ecard{position:relative;overflow:hidden;
  transition:transform .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5page .ecard:hover{transform:translateY(-3px);box-shadow:var(--el-2)}

/* ═══════════════════════════════════════════════════════════
   16. THE SOLUTION ADVISOR
   Same architecture — a local, deterministic router, posting to this site's
   own endpoint and nowhere else. What changes is that it now behaves like a
   piece of software: the panel shows what it matches against before it is
   asked anything, the wait is three named passes rather than a spinner, and
   the answer assembles itself instead of appearing all at once.
   ═══════════════════════════════════════════════════════════ */
.p5adv-panel{
  background:var(--pane-solid);
  border:1px solid var(--pane-line);
  box-shadow:var(--el-3),var(--pane-edge);
}
.p5adv-bar{background:linear-gradient(180deg,rgba(26,25,23,.045),rgba(26,25,23,.02));
  border-block-end-color:var(--pane-line)}
/* `.p5adv-bar` went when the advisor was rebuilt in Clay's shape; its
   breathing dot rule outlived it and is removed here with the other
   status lights. */
.p5adv-fams{display:inline-flex;gap:.3rem;margin-inline-start:.15rem}
.p5adv-fams i{inline-size:.4rem;block-size:.4rem;border-radius:1px;background:var(--fam);
  opacity:.55;transition:opacity .3s var(--e-out),scale .3s var(--e-out)}
.p5adv-panel.thinking .p5adv-fams i{animation:fam-scan 1.05s ease-in-out infinite}
.p5adv-fams i:nth-child(2){animation-delay:.12s}
.p5adv-fams i:nth-child(3){animation-delay:.24s}
.p5adv-fams i:nth-child(4){animation-delay:.36s}
@keyframes fam-scan{0%,100%{opacity:.45;scale:1}45%{opacity:1;scale:1.5}}

.p5adv textarea{background:rgba(26,25,23,.028);border-color:rgba(26,25,23,.16)}
.p5adv textarea:focus{background:var(--pane-solid);
  box-shadow:0 0 0 4px rgba(212,43,48,.12),var(--el-1)}

.p5chip{background:var(--pane-solid);border-color:rgba(26,25,23,.15);
  box-shadow:var(--el-1);overflow:hidden;position:relative}
.p5chip::after{content:"";position:absolute;inset:0;border-radius:inherit;
  background:linear-gradient(90deg,rgba(212,43,48,.10),rgba(212,43,48,0) 70%);
  opacity:0;transition:opacity .28s var(--e-out)}
.p5chip:hover::after{opacity:1}
.p5chip:hover{box-shadow:var(--el-2)}
/* the example the answer on screen came from stays marked, so a second look
   at the panel says which question is being answered */
.p5chip.on{border-color:var(--sig);color:var(--ink);box-shadow:var(--el-2)}
.p5chip.on::before{opacity:1;scale:1.25}
.p5chip.on::after{opacity:1}

/* ── the working readout ── */
.p5adv-think{padding:clamp(1.1rem,.9rem + 1.2vw,1.7rem) clamp(1.25rem,1rem + 1.4vw,2rem);
  border-block-start:1px solid var(--pane-line);
  background:linear-gradient(180deg,rgba(26,25,23,.03),transparent)}
.p5adv-think[hidden]{display:none}
.p5think-steps{display:grid;gap:.55rem;margin:0 0 .95rem;padding:0;list-style:none}
.p5think-steps li{display:flex;align-items:center;gap:.65rem;color:var(--ink-3);
  transition:color .3s var(--e-out)}
.p5think-steps li .mk{inline-size:.5rem;block-size:.5rem;border-radius:50%;flex:none;
  background:transparent;border:1.5px solid rgba(26,25,23,.24);
  transition:background .3s var(--e-out),border-color .3s,scale .3s var(--e-out)}
.p5think-steps li.on{color:var(--ink-2)}
.p5think-steps li.on .mk{background:var(--sig);border-color:var(--sig);scale:1.15;
  box-shadow:0 0 0 4px rgba(212,43,48,.14)}
.p5think-steps li.done .mk{background:rgba(212,43,48,.35);border-color:rgba(212,43,48,.35)}
.p5think-bar{display:block;block-size:2px;border-radius:2px;background:rgba(26,25,23,.10);
  overflow:hidden;max-inline-size:16rem}
.p5think-bar i{display:block;block-size:100%;inline-size:var(--w,0%);background:var(--sig);
  box-shadow:0 0 10px 0 rgba(212,43,48,.5);
  transition:inline-size .42s var(--e-io)}

/* ── the answer ── */
.p5adv-out{background:linear-gradient(180deg,rgba(26,25,23,.035),transparent 40%);
  border-block-start:1px solid var(--pane-line)}
/* Script moves focus onto the answer so a keyboard or screen-reader visitor
   lands on it. That focus is real and must be visible — but the shared ring
   sits 3px OUTSIDE its target, and outside a seven-hundred-pixel region it
   reads as a red rule floating under the form rather than as a focus
   indicator. Inset, at full strength, it reads as what it is. */
.p5adv-out:focus-visible,.p5adv-out:focus{outline:2px solid var(--sig);
  outline-offset:-2px;border-radius:0}
.p5adv-status .bar{max-inline-size:11rem}
.p5rec-fam{background:var(--pane-solid);border-color:var(--pane-line);
  box-shadow:var(--el-1);overflow:hidden;
  transition:transform .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5rec-fam::after{content:"";position:absolute;inset-block-start:0;inset-inline:0;
  block-size:100%;pointer-events:none;
  background:radial-gradient(80% 60% at 0% 0%,
             color-mix(in srgb,var(--fam,var(--sig)) 10%,transparent),transparent 62%)}
.p5rec-fam:hover{transform:translateY(-2px);box-shadow:var(--el-2)}
.p5rec-flow .st{background:var(--pane-solid);border-color:rgba(26,25,23,.15);
  box-shadow:var(--el-1)}
.p5rec-flow .stp{position:relative}
.p5rec-caution{background:var(--pane-solid);box-shadow:var(--el-1);border-style:solid;
  border-color:var(--pane-line)}

/* ── 17. Typography reveals ─────────────────────────────
   Word-by-word, at the moments that carry the page: the hero, the rail, the
   field, the advisor and the close.

   Only an element that script has already split gets a start-state, and the
   script that splits it also guarantees it finishes — on arrival, and on a
   watchdog if the observer never fires. A heading cannot be stranded. */
.js-on .rk-split .rk-w > i{transform:translate3d(0,108%,0);
  transition:transform .82s var(--e-out)}
.js-on .rk-split.shown .rk-w > i{transform:none}
html.reduce-motion .rk-split .rk-w > i,
html.motion-failed .rk-split .rk-w > i,
html.experience-failed .rk-split .rk-w > i{transform:none !important}

/* ── 18. The header, on the one ground ──────────────────
   The bar's own surface — glass at rest, denser once the page is moving — is
   set in § 21 on `.hdr-in` itself, so one rule owns it on every route. The two
   `.p5body` overrides that used to sit here only restated an opaque
   background, and being the more specific pair they would have outranked it. */
.p5body .mega{background:rgba(255,253,250,.94);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  backdrop-filter:blur(20px) saturate(1.2);
  border-color:var(--pane-line);box-shadow:var(--el-3)}
.p5body .mnav{background:var(--env-base)}

/* ── 19. Mobile intent ─────────────────────────────────
   Meaningful motion stays; the expensive parts go. Two blurred blooms and a
   grain layer are the costly things on a phone, and the thread has no
   gutter to live in. */
@media (max-width:860px){
  .p5sky-blooms{inset:-6%}
  .p5fam:hover{transform:none}
}
@media (max-width:700px){
  .p5page .card-plain{margin-inline:0;padding-inline:0}
}
/* A pointer-driven parallax is a desktop idea. On a touch device the same
   listeners cost battery and do nothing a finger can trigger. */
@media (hover:none){
  .p5sky-blooms{transform:none}
}

/* The closing scene is the largest single raster on the page. Trimming it to
   the size it actually needs is worth more than any effect inside it. */
.p5close-scene svg{inline-size:min(1040px,118%)}
@media (max-width:860px){.p5close-scene svg{inline-size:150%}}

/* ═══════════════════════════════════════════════════════════
   20. ADOPTING THIS ON ANOTHER PAGE
   ───────────────────────────────────────────────────────────
   The homepage is the benchmark, not the only customer. Everything above is
   built so an internal page can take as much or as little of it as it needs,
   and nothing in this file assumes the Phase 5 blocks are present.

   THE GROUND — the continuous environment
     1. add `p5body` to <body>            (page.html does this from a block)
     2. wrap the page content in `.p5page`
     3. drop this inside that wrapper, first:

          <div class="p5sky" aria-hidden="true">
            <div class="p5sky-blooms"></div>
          </div>

     That is the whole ground. The sections inside must not paint their own
     full-width backgrounds; if one does, it cuts the environment in half and
     the page is a stack of panels again.

   THE CONSOLE — the dark object
     `.con` is the only dark surface in the system. Its measurement grid and
     its bloom are background LAYERS on the surface itself, never child
     elements: a masked, panel-sized child composited behind overlapping
     panels cost more than everything else on this page put together. And do
     not clip it — the radius clips a background for free, while a rounded
     overflow clip on a tall element is re-applied every frame it is on
     screen.

   THE PANE — the light surface
     `.pane` replaces a flat card. It is a translucent layer with a hairline,
     a top edge highlight and elevation `--el-1`, and it degrades to an opaque
     surface where `backdrop-filter` is unsupported.

   TOKENS
     colour      --env-base/-lift/-sink · --con-1..3 · --con-ink..-3 ·
                 --sig (the signal) · --fam-* (the four families)
     surface     --pane · --pane-line · --pane-edge
     elevation   --el-1 --el-2 --el-3 --el-sig --el-con
     motion      --e-out --e-io --e-soft
     geometry    --con-gut (the console's inset) · --con-r (its radius)

   MOTION UTILITIES
     `.rk-split` + `.rk-w` are the headline word reveal. Never write them by
     hand: experience.js creates the spans, and the same function guarantees
     they finish — on arrival, and on a watchdog if the observer never fires.
     A heading marked up by hand has no such guarantee and can be stranded.

   THE THREE RULES, which apply to anything added here
     · the page is finished before any script runs
     · reduced motion gets the finished frame, never the empty one
     · nothing animates a layout property, and nothing large animates on a
       loop — see §2 for what that cost the first time
   ═══════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════
   21. CONTACT
   ───────────────────────────────────────────────────────────
   Not a second design. The page keeps its blocks, its copy and its
   structure, and joins the homepage's ground so it stops looking like a
   different site with the same header. What changes is composition: the
   hero and the form stop being separated by four hundred pixels of nothing,
   the form becomes a pane rather than a flat card, and one quiet signal
   connects the two — the same device the homepage uses to say that these
   things are one system.
   ═══════════════════════════════════════════════════════════ */
/* `.p5body .phero`, not `.p5contact .phero`: page.html renders the standard
   page hero BEFORE the .p5page wrapper, so a selector scoped inside that
   wrapper never reaches it. The homepage has no .phero at all, so keying off
   the body class is both correct and contact-only in practice. */
/* Sideways only: the reasoning field bleeds past the right edge on purpose,
   and must not widen the page — but the contact hero's signal line hangs
   below the section and has to stay visible. */
.p5body .phero{padding-block:clamp(6.5rem,5rem + 4vw,8.5rem) 0;position:relative;
  overflow-x:clip;overflow-y:visible}
.p5body .phero .h1{max-inline-size:20ch}
.p5body .phero .lead{margin-block-start:1rem;max-inline-size:56ch}
/* the hero's own line down into the first block, so the page opens as one
   movement rather than two stacked sections. Contact only — on an Enterprise
   AI page the accent is purple and the reasoning field already carries the
   connection. */
.p5body-contact .phero::after{
  content:"";position:absolute;inset-block-end:calc(-1 * clamp(1.4rem,1rem + 1.6vw,2.4rem));
  inset-inline-start:clamp(1.15rem,.5rem + 2.4vw,2.5rem);
  inline-size:1.5px;block-size:clamp(2.4rem,1.6rem + 2.4vw,4rem);border-radius:2px;
  background:linear-gradient(180deg,var(--sig),rgba(212,43,48,0));
  box-shadow:0 0 10px 0 rgba(212,43,48,.35);
}
.p5contact .sec:first-of-type{padding-block-start:clamp(2.6rem,2rem + 2.6vw,4.2rem)}

/* the enquiry block: copy and form on the same baseline */
.p5contact .split{align-items:start}
@media (min-width:900px){
  .p5contact .split{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
    gap:clamp(2rem,1.2rem + 3vw,4rem)}
}
.p5contact .form-wrap{
  background:var(--pane-solid);border:1px solid var(--pane-line);
  border-radius:var(--r-xl);box-shadow:var(--el-3),var(--pane-edge);
  padding:clamp(1.4rem,1.1rem + 1.6vw,2.4rem);
}
.p5contact .field input,.p5contact .field textarea{
  background:rgba(26,25,23,.028);border-color:rgba(26,25,23,.16);
  transition:border-color .25s var(--e-out),box-shadow .25s var(--e-out),
             background .25s var(--e-out)}
.p5contact .field input:focus,.p5contact .field textarea:focus{
  background:var(--pane-solid);border-color:var(--sig);
  box-shadow:0 0 0 4px rgba(212,43,48,.12)}
.p5contact .form-note{margin-block-start:.2rem;color:var(--ink-3)}

/* the contact lines beside the form, as instrument readouts */
.p5contact .checks{gap:.85rem;margin-block-start:clamp(1.5rem,1.2rem + 1.4vw,2.2rem);
  padding-block-start:clamp(1.2rem,1rem + 1vw,1.8rem);
  border-block-start:1px solid rgba(26,25,23,.14)}
.p5contact .checks li{align-items:center;font-size:var(--t-body)}
.p5contact .checks .ico{color:var(--sig)}
.p5contact .checks a{border-block-end:1.5px solid transparent;transition:border-color .2s}
.p5contact .checks a:hover{border-block-end-color:currentColor}

/* the offices, as panes on the ground */
.p5contact .ocard{
  background:var(--pane);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border-color:var(--pane-line);box-shadow:var(--el-1),var(--pane-edge);
  transition:transform .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5contact .ocard:hover{transform:translateY(-3px);box-shadow:var(--el-2)}
.p5contact .ocard .eyebrow{margin-block-end:.5rem}
@supports not (backdrop-filter:blur(2px)){
  .p5contact .ocard{background:var(--pane-solid)}
}

/* ═══════════════════════════════════════════════════════════
   22. ENTERPRISE AI PAGES
   ───────────────────────────────────────────────────────────
   The Larion content is accurate and its safeguards are load-bearing; none
   of that changes here. What changes is that the pages stop being the
   plainest thing on the site: the shared ground, this family's purple as the
   accent, panes instead of flat cards, and one quiet reasoning field behind
   the hero. No claim is added, strengthened or implied.
   ═══════════════════════════════════════════════════════════ */
.p5larion{--fam:var(--fam-enterprise-ai)}
.p5body .p5ai-field{
  position:absolute;inset-block-start:50%;inset-inline-end:clamp(-4rem,-2vw,0rem);
  translate:0 -50%;inline-size:min(38vw,460px);pointer-events:none;
  opacity:.5;display:none;
}
@media (min-width:1000px){.p5body .p5ai-field{display:block}}
.lf{inline-size:100%;block-size:auto;overflow:visible}
.lf-bound{fill:none;stroke:color-mix(in srgb,var(--ube-500) 26%,transparent);
  stroke-width:1.2;stroke-dasharray:5 6}
.lf-cap{font-family:var(--mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;fill:color-mix(in srgb,var(--ube-700) 55%,transparent)}
.lf-doc,.lf-out{fill:color-mix(in srgb,var(--ube-500) 8%,transparent);
  stroke:color-mix(in srgb,var(--ube-500) 26%,transparent);stroke-width:1}
.lf-line{fill:color-mix(in srgb,var(--ube-500) 34%,transparent)}
.lf-link{fill:none;stroke:color-mix(in srgb,var(--ube-500) 30%,transparent);stroke-width:1}
.lf-edge{fill:none;stroke:color-mix(in srgb,var(--ube-500) 26%,transparent);stroke-width:1.2}
.lf-node{fill:var(--ube-500);opacity:.55}
/* three small nodes breathe. Nothing else moves — the lesson from the closing
   scene is that a large SVG re-rasterises for every element that does. */
.lf-pulse{fill:none;stroke:var(--ube-500);stroke-width:1.2;opacity:0;
  animation:lf-breathe 3.6s ease-in-out infinite}
.lf-pulse:nth-of-type(2){animation-delay:1.2s}
.lf-pulse:nth-of-type(3){animation-delay:2.4s}
@keyframes lf-breathe{
  0%,100%{opacity:0;transform:scale(.55)}
  40%{opacity:.5}
  70%{opacity:0;transform:scale(1)}
}
.lf-pulse{transform-box:fill-box;transform-origin:center}
@media (prefers-reduced-motion:reduce){.lf-pulse{animation:none;opacity:.28}}
html.reduce-motion .lf-pulse,html.motion-failed .lf-pulse{animation:none;opacity:.28}

/* The family's accent used to be carried by the eyebrow's own text colour.
   Eyebrows became filled pills site-wide, and this rule kept overriding the
   pill's white — violet on a red pill, violet on a green one. The accent is
   the pill's background now; the text is white, as everywhere else. */
.p5larion .eyebrow,.p5body-larion .phero .eyebrow{color:#fff}
.p5body-larion .phero .h1{max-inline-size:19ch}
.p5body-larion .phero .lead{max-inline-size:52ch}
.p5larion .snote::before{background:var(--ube-500)}
.p5larion .snote-verification::before{background:var(--ube-500)}
/* the positioning grid: panes with the family's badge, not floating icons */
.p5larion .card-plain{
  border-block-start:1px solid rgba(26,25,23,.12);border-radius:var(--r-md);
  padding:1.4rem 1.1rem 1.5rem;margin-inline:-1.1rem;
  transition:background .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5larion .card-plain:hover{background:var(--pane);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:var(--el-1),var(--pane-edge)}
.p5larion .card-plain .ico-badge{
  background:color-mix(in srgb,var(--acc,var(--ube-500)) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--acc,var(--ube-500)) 22%,transparent);
  transition:transform .35s var(--e-out)}
.p5larion .card-plain:hover .ico-badge{transform:translateY(-2px) rotate(-4deg)}
/* the two product areas */
.p5larion .ecard{transition:transform .35s var(--e-out),box-shadow .35s var(--e-out)}
.p5larion .ecard:hover{transform:translateY(-3px);box-shadow:var(--el-2)}

/* ── 16b. The advisor's answer, ranked ──────────────────
   The first family is the answer and the rest are context; they were drawn
   identically, so which was which had to be read off the kicker. The primary
   gets the family's own light and a heavier edge, the others step back. */
.p5rec-fam.is-primary{
  border-inline-start-width:4px;
  box-shadow:var(--el-2);
  background-image:linear-gradient(180deg,
    color-mix(in srgb,var(--fam,var(--sig)) 7%,transparent),transparent 46%);
}
.p5rec-fam.is-primary .t{font-size:clamp(1.2rem,1.06rem + .7vw,1.55rem)}
.p5rec-fam.is-primary .k{letter-spacing:.14em}
.p5rec-fam:not(.is-primary){background:transparent;box-shadow:none;
  border-color:rgba(26,25,23,.12)}
.p5rec-fam:not(.is-primary) .t{font-size:clamp(1.05rem,1rem + .35vw,1.2rem)}
@media (min-width:720px){
  /* the answer leads the row rather than sharing it equally */
  .p5rec-fams:has(.is-primary){grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}
}

/* ── 22b. THE CONSOLE SHELL ─────────────────────────────
   Frame, readout bar and body for a console that holds a scene. These were
   retired when the hero stopped using a shell of its own and became the
   console; the capability rail uses one again, so they are back — and this
   time they live with the rail rather than with the hero, which is the only
   place they are used. */
.p5stagecon{position:relative}
/* THE READOUT BAR IS GONE, and its rules with it. It was a breathing red
   dot, "Rkieh Productions · connected systems" and a four-bar signal meter across the top
   of the panel. The client removed it on 2026-08-27 as instrument chrome that
   reads as generated. `.p5stagecon` keeps its frame and `.p5stagecon-body`
   below is unchanged, so the panel is the same panel with nothing on top. */
.p5stagecon-body{position:relative;z-index:1}
/* Sizing only. NOT `display`: the scene ships a desktop and a phone
   composition and CSS picks one with display:none — setting display here
   overrides that and renders both, one under the other. That is the second
   time; the property does not belong in this rule. */
.p5stagecon-body svg{inline-size:100%;block-size:auto}

/* ── 23. THE RAIL'S CONNECTED-SYSTEMS DIAGRAM ───────────
   The scene is a portrait drawing — 620×730 — and it used to live in a
   narrow hero column that constrained it. Dropped into a full-width section
   it stretched to the measure and every band came out three hundred pixels
   tall. It gets a console sized to the drawing instead, centred: a portrait
   instrument standing on the page, at the scale it was drawn for. */
.p5fams-scene{margin-block-end:clamp(2rem,1.6rem + 2.4vw,3.4rem);position:relative}
.p5fams-scene .p5stagecon{
  max-inline-size:min(100%,33rem);margin-inline:auto;
  border-radius:clamp(.9rem,.6rem + 1.2vw,1.5rem);
}
.p5fams-scene .p5stagecon-body{padding:clamp(.5rem,.3rem + .7vw,.9rem)}
/* the red bloom the console casts on the ground it stands on */
.p5fams-scene::after{
  content:"";position:absolute;inset-block-end:-2.4rem;inset-inline:22%;
  block-size:5rem;pointer-events:none;z-index:-1;
  background:radial-gradient(60% 130% at 50% 0%,
    rgba(212,43,48,.22),rgba(212,43,48,.09) 40%,transparent 78%);
}
@media (min-width:1240px){
  /* wide enough to stand the instrument beside its own key */
  .p5fams-scene{margin-block-end:clamp(2.4rem,2rem + 2vw,3.6rem)}
  .p5fams-scene .p5stagecon{max-inline-size:36rem}
}

/* ── 24. THE FOUR AS A KEY ──────────────────────────────
   Where the diagram is making the point, the list beside it is labelling the
   picture — so it is a key, not four paragraphs repeating what the picture
   just said. Names, family marks, numbers, and a link each to the page that
   carries the detail. */
.p5fam-key{
  display:grid;gap:0;list-style:none;margin:0;padding:0;
  border-block-start:1px solid rgba(26,25,23,.12);
}
@media (min-width:760px){
  .p5fam-key{grid-template-columns:repeat(4,minmax(0,1fr));
    border-block-end:1px solid rgba(26,25,23,.12)}
}
.p5fam-k{
  position:relative;display:grid;gap:.5rem;align-content:start;
  padding:clamp(1.1rem,.9rem + 1vw,1.6rem) clamp(.9rem,.7rem + .8vw,1.4rem);
  border-block-end:1px solid rgba(26,25,23,.12);
  transition:background .35s var(--e-out);
}
@media (min-width:760px){
  .p5fam-k{border-block-end:0;border-inline-start:1px solid rgba(26,25,23,.12)}
  .p5fam-k:first-child{border-inline-start:0;padding-inline-start:0}
  .p5fam-k:last-child{padding-inline-end:0}
}
.p5fam-k:hover,.p5fam-k:focus-within{background:color-mix(in srgb,var(--fam) 5%,transparent)}
/* the family's signal touching its own entry */
.p5fam-k::after{
  content:"";position:absolute;inset-block-start:-1px;inset-inline:0;
  block-size:2px;background:var(--fam);border-radius:2px;
  transform:scaleX(0);transform-origin:left center;opacity:.9;
  transition:transform .55s var(--e-out);
}
.p5fam-k.lit::after{transform:scaleX(1)}
.p5fam-kt{
  font-size:clamp(1rem,.94rem + .38vw,1.18rem);letter-spacing:-.024em;
  font-weight:600;line-height:1.22;display:flex;align-items:baseline;gap:.55rem;
}
.p5fam-kt .sq{inline-size:.5rem;block-size:.5rem;border-radius:2px;flex:none;
  background:var(--fam,var(--sig));translate:0 -.1em;
  transition:scale .3s var(--e-out),box-shadow .3s}
.p5fam-k:hover .sq{scale:1.35;
  box-shadow:0 0 0 4px color-mix(in srgb,var(--fam) 18%,transparent)}
.p5fam-k .p5fam-n{color:var(--ink-3)}
.p5fam-k .p5fam-link{color:inherit}
.p5fam-k .p5fam-link::after{content:"";position:absolute;inset:0;z-index:1;
  border-radius:var(--r-sm)}
.p5fam-k .p5fam-link:focus-visible{outline:2.5px solid var(--fam,var(--focus));
  outline-offset:4px;border-radius:var(--r-xs)}

/* the homepage's own diagram sits a little larger than the index page's */
.p5page .p5fams-scene .p5stagecon{max-inline-size:min(100%,34rem)}


/* ═══════════════════════════════════════════════════════════
   21 · THE BAR, FINISHED
   A visual pass over the header and nothing else. The five names, their
   order, their wording, their destinations, the disclosure semantics and
   the drawer's structure are all exactly as they were; what changes is the
   surface it sits on, the room the labels have, the weight they carry and
   the way the whole thing answers a pointer.
   ═══════════════════════════════════════════════════════════ */

/* ── the surface: glass ─────────────────────────────────
   § 18 kept this bar opaque and gave a reason: a backdrop-filter over a
   scrolling page re-blurs its strip every frame. That was measured against
   a bar with nothing behind it worth seeing. What is behind it now is a
   film of a bright landscape running the width of the first screen, and an
   opaque cream slab laid across the top of that reads as a panel on the
   picture rather than part of it.

   So the bar takes the sky: the same `--pane` the page's other translucent
   surfaces use, blurred, with saturation pushed a little so the blue that
   comes through stays blue instead of going grey. The cost is guarded
   rather than ignored — no transition anywhere names backdrop-filter, so
   the blur is only ever recomposited for a scroll and never for an
   animation; touch pointers and small screens keep an opaque bar, which is
   where the strip is cheapest to notice and dearest to paint; and a reader
   who has asked for less transparency is given none. */
.hdr-in{
  /* SOLID, AND IT HAS AN EDGE. The bar was glass — a translucent warm fill
     over a 16px backdrop blur — which reads beautifully over a photograph
     and disappears entirely over this one: the hero's top band is near-white
     cream, the bar is near-white cream, and with no edge between them the
     header simply was not there.

     So: no backdrop-filter anywhere, one opaque fill, and a ring. The ring
     is a box-shadow rather than a border on purpose — a border would add two
     pixels to a bar whose height is set in rem and shift every row in it,
     where an inset ring costs no layout at all and follows --r-hdr's corners
     for free. The drop shadow under it is what separates the bar from the
     picture; the ring is what draws it when the two are the same colour. */
  background:#fbf9f5;
  box-shadow:0 0 0 1px rgba(26,25,23,.08),
             0 6px 18px -10px rgba(26,25,23,.20);
}
/* Moving, it deepens rather than changes: same ring, more shadow, because
   now there is text passing underneath it rather than a picture sitting
   still behind it. */
html:not(.hdr-dark) .hdr.stuck .hdr-in{
  background:#fdfcf9;
  box-shadow:0 0 0 1px rgba(26,25,23,.10),
             0 14px 30px -16px rgba(26,25,23,.34);
}

/* ── the balance of the bar ─────────────────────────────
   The five names sat hard left and the action hard right, which is fine in
   a bar that is full: at 1280 the space between them is 105px and reads as
   a gap. It does not stay that way. The names do not grow with the window
   and neither does the action, so everything the window gains lands in the
   middle — 735px at 1920, 1071px at 2560, which is 42% of the bar and reads
   as a bar that failed to load.

   The names take the middle instead. `margin-inline:auto` on the nav gives
   its two free margins an equal share of whatever is left, so the group
   centres between the mark and the action, and the action no longer needs
   an auto margin of its own to be pushed right — it already is. Where the
   bar is tight the autos collapse to nothing and the layout is exactly what
   it was, which is the behaviour the 1000-1240 rules were written for.
   AND IT IS BOUNDED AT 1000px, WHICH IS NOT A DETAIL. Below that the nav is
   `display:none` and the bar holds a mark and a burger — where `margin-left:
   auto` on .hdr-cta is the only thing holding the burger against the right
   edge. Released unconditionally it walks back to sit against the logo, with
   the whole width empty beside it. Caught on a phone screenshot, not by
   reading the rule. */
@media (min-width:1000px){
  .hdr .nav{margin-inline:auto}
  .hdr .hdr-cta{margin-left:0}
}
html.hdr-dark .hdr.stuck .hdr-in{
  box-shadow:inset 0 -1px 0 rgba(244,241,235,.1),
             0 16px 38px -22px rgba(0,0,0,.85);
}
/* Nothing to fall back FROM any more — the bar is opaque on every device, so
   the @supports and reduced-transparency branches that existed to undo a
   backdrop-filter are gone with it. What is left below is the coarse-pointer
   branch, which now only has to match the fill. */
/* The guard is the pointer, not the width. A 768px-wide desktop window is a
   desktop compositor and can blur a 43,000px strip without noticing; a phone
   at the same width cannot, and is also the one place the sky behind the bar
   is a thin band nobody is looking at. So a coarse pointer gets the opaque
   bar and a window that can hover keeps the glass at every width. */
@media (hover:none){
  .hdr-in{background:#fbf9f5}
  html:not(.hdr-dark) .hdr.stuck .hdr-in{background:#fdfcf9}
  html.hdr-dark .hdr-in{-webkit-backdrop-filter:none;backdrop-filter:none;
    background:rgba(30,27,25,.97)}
}
@media (prefers-reduced-transparency:reduce){
  .hdr-in{background:#fbf9f5}
  html:not(.hdr-dark) .hdr.stuck .hdr-in{background:#fdfcf9}
  html.hdr-dark .hdr-in{-webkit-backdrop-filter:none;backdrop-filter:none;
    background:#1e1b19}
}

/* ── the five names ─────────────────────────────────────
   `button.nav-link` in site.css resets padding to `inherit`, and the parent
   it inherits from is a `.nav-item` with none — so every trigger in this bar
   has been laying out with zero padding and the .6rem/.75rem written for it
   has never applied to anything, at any width. The labels came out 1.6px
   apart: each caret sat almost exactly midway between the name it belongs
   to and the next one, and the hover chip painted a rectangle tight to the
   letters. Padding goes back explicitly, at a specificity that beats the
   reset — and it is spent per breakpoint, because the room for five
   capability names, a mark and an action is not the same at 1440 as it is
   at 1024. */
.hdr .nav-link{
  padding-block:.44rem;padding-inline:.68rem;
  gap:.28rem;border-radius:.66rem;
  color:var(--ink-2);font-weight:500;letter-spacing:-.014em;
  transition:background .22s var(--e-out),color .22s var(--e-out);
}
/* Full ink is a state, not a resting colour. Five names in near-black were
   claiming the same attention as the one thing in the bar that is an
   action. */
.hdr .nav-link:hover,.hdr .nav-item:hover>.nav-link,
.hdr .nav-link[aria-current="page"]{color:var(--ink);background:rgba(26,25,23,.055)}
/* Open is a step past hover and has to look like one: there is a panel on
   the screen. */
.hdr .nav-link[aria-expanded="true"]{color:var(--ink);background:rgba(26,25,23,.08)}
/* Below 1241 the padding stops being a value and becomes a function of the
   room the window has. Five capability names, a mark and an action in a
   thousand pixels leaves about 25px of slack once the labels are set — so
   the padding cannot be a step, or the step has to be sized for 1000px and
   then 1200px inherits a bar as tight as a netbook's.

   It ramps instead: 1.4px a side at 1000, nine hundredths of a pixel for
   every pixel of window after that, capped where the full-size band starts
   so the two meet without a jump. Measured at every width in the table
   below, the labels never come closer than 10px to the action — the margin
   the author of the 1000px rule asked for, and the reason there are two
   ramps rather than one: at 1100 the label font steps up from .92 to .95rem
   and the budget resets.

     window   free space left over
     1000     11.0px      1140     13.9px
     1024     12.3px      1241     54.4px
     1040     13.0px      1440    243.8px

   The things either side of the names give room back too, in the compact
   band only: the action from its own padding, the bar from its left inset,
   the row from its margin, the bar's flex gap from all three. */
@media (min-width:1100px) and (max-width:1240px){
  .hdr .nav-link{padding-inline:min(.68rem,calc(7px + (100vw - 1100px) * .09))}
}
@media (min-width:1000px) and (max-width:1099px){
  .hdr .nav-link{padding-inline:min(7px,calc(1.4px + (100vw - 1000px) * .09))}
  .hdr .btn-sm{padding-inline:.72rem}
  .hdr .hdr-in{padding-left:.9rem;gap:.35rem}
  .hdr .nav{margin-left:.15rem}
}

/* ── the caret ──────────────────────────────────────────
   Smaller, lighter, and tied to the label it belongs to: the gap in front
   of it is now a third of the padding that follows it, so it reads as part
   of its own trigger instead of floating between two names. It brightens as
   well as turning over, so hovering a trigger looks like one object
   responding rather than a word and an arrow doing separate things. */
.hdr .nav-link .caret{
  inline-size:.58rem;block-size:.58rem;stroke-width:2.1;opacity:.38;
  transition:transform .34s var(--e-out),opacity .22s var(--e-out);
}
.hdr .nav-item:hover .caret,.hdr .nav-link[aria-expanded="true"] .caret{opacity:.9}

/* ── the mark ───────────────────────────────────────────
   32px of logo in a 59px bar sat small — a little over half the height it
   had to fill, which reads as timid next to a filled button. It goes up
   where there is room; below 1100 the bar needs those pixels for the names,
   and on a phone the mark is the only thing on the left, so it can afford a
   little more than it had. */
/* `max-height:1.95rem` in site.css caps this, so both have to move or
   neither does. And the four pixels of width the taller mark costs are only
   affordable in the same band that can afford full label padding — below
   1241 the bar is in its compact mode and every pixel is spoken for. */
@media (min-width:1241px),(min-width:641px) and (max-width:999px){
  .hdr .logo img{block-size:2.15rem;max-block-size:2.15rem}
}
@media (max-width:640px){.hdr .logo img{block-size:1.85rem;max-block-size:1.85rem}}
.hdr .logo{transition:opacity .25s var(--e-out)}
.hdr .logo:hover{opacity:.76}

/* ── the action, and the control beside it ──────────────
   The two things in the right cluster were 43.2px and 41.6px tall, so at
   every tablet width they were 0.8px out of line with each other top and
   bottom. Same height now, same radius, same family of object.

   The button keeps the brand red it carries everywhere else on the site.
   What is added is the light on it — a white hairline inside the top edge
   and a gradient too shallow to read as a gradient — and a shadow mixed
   from the red's own darkness instead of neutral grey, which is the
   difference between a coloured button that looks printed on a warm ground
   and one that looks pasted onto it. */
/* FLAT, AND THE SAME CORNER AS THE BAR. What stood here was a gradient
   sheen, an inset highlight and two coloured drop shadows, over the 1.5px
   border every .btn carries from site.css — five treatments to make one
   red rectangle look lit. Against a bar that is now itself flat and
   opaque, the lighting had nothing to be consistent with, and the border
   read as an outline around the fill rather than an edge of it.

   So: one colour, no border, no shadow, no gradient, and no lift on hover
   — the ONLY thing that changes is the red, which is the whole affordance
   a button of this size needs. The radius is --r-hdr, the bar's own, so
   the button's corner and the bar's corner are cut to one measure. */
.hdr .btn{
  border-radius:var(--r-btn);
  border:0;
  background-image:none;
  box-shadow:none;
}
.hdr .btn:hover,.hdr .btn:active{box-shadow:none;transform:none}
.hdr .btn-brand:hover{--bg:color-mix(in srgb,var(--brand) 92%,#000)}
/* An opaque cream square inside a bar you can see through is a patch. The
   burger is a hairline and its own three rules, and it fills only when a
   pointer is on it. */
.hdr .burger{
  inline-size:2.7rem;block-size:2.7rem;border-radius:.72rem;
  background:transparent;border:1px solid rgba(26,25,23,.16);
  transition:background .2s var(--e-out),border-color .2s var(--e-out)}
.hdr .burger:hover{background:rgba(26,25,23,.05);border-color:rgba(26,25,23,.32)}
.hdr .burger span,.hdr .burger span::before,.hdr .burger span::after{block-size:1.7px}
/* In a bar this shallow, a 3px focus offset lands on the neighbour. */
.hdr .nav-link:focus-visible,.hdr .btn:focus-visible,
.hdr .burger:focus-visible,.hdr .logo:focus-visible{outline-offset:2px}

/* ── the panel ──────────────────────────────────────────
   The same glass as the bar, one step denser because it is carrying
   twenty-odd destinations, and eight pixels below it rather than ten so the
   two read as one object opening. The hover fill goes translucent for the
   same reason the bar did: an opaque chip on a surface you can see through
   is a flat patch on it. The columns, the counts and the copy are
   untouched. */
.mega{top:calc(100% + .5rem)}
.p5body .mega{background:rgba(255,253,250,.9);border-color:rgba(26,25,23,.09);
  box-shadow:0 1px 2px rgba(26,25,23,.04),
             0 20px 44px -20px rgba(26,25,23,.24),
             0 64px 96px -64px rgba(26,25,23,.4)}
.hdr .mega-col a:hover,.hdr .mega-col a:focus-visible{background:rgba(26,25,23,.055)}

/* ── the drawer ─────────────────────────────────────────
   `.mnav .mnav .mnav details` cannot match anything: there is one .mnav on
   the page and it is not inside itself. So the divider that rule was
   written for has never been drawn, and the five rows have been floating in
   an empty panel with nothing to say where one ends and the next begins.
   One row, one line — and the row gives back a little height, so the five
   of them and the action sit higher up the screen. */
.mnav>details{border-block-end:1px solid var(--line-2)}
.mnav>details:first-of-type{border-block-start:1px solid var(--line-2)}
.mnav summary{padding-block:.95rem}
.mnav>details>summary>.caret{inline-size:1.1rem;block-size:1.1rem;
  color:var(--ink-3);stroke-width:2.1}
.mnav-cta{margin-top:1.5rem}
.mnav-cta .btn{border-radius:.85rem}
.mnav-cta .btn-brand{
  background-image:linear-gradient(180deg,rgba(255,255,255,.13),rgba(255,255,255,0) 58%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),
             0 2px 4px rgba(122,16,20,.16),
             0 14px 28px -14px rgba(122,16,20,.45)}


/* ═══════════════════════════════════════════════════════════
   22 · THE TOOL WALL
   Rows of tiles drifting past each other under the hero, in the place the
   stats band used to hold. The movement is clay.com's — three rows, the
   middle one running the other way, tiles of mixed width, the whole thing
   fading out at both edges rather than stopping at a line — and the parts
   that produce it are the ones already in this codebase: `.marq` for the
   mask and the loop, `.marq-track` for the animation, site.js for the speed
   and the off-screen pause.
   ═══════════════════════════════════════════════════════════ */

.twall-sec{padding-block-start:clamp(2.2rem,1.6rem + 2vw,3.4rem)}
/* The statement, centred over the rows inside the panel — Clay's placement.
   Set as a sentence rather than as a headline: it is doing the work the
   eyebrow, the heading and the disclaimer were doing outside the panel, and a
   sentence is what says "these are tools, not partners" without needing a
   second line of small print to do it. */
.twall-head{
  max-inline-size:52ch;margin:0 auto;
  padding-inline:clamp(1.15rem,4vw,3rem);
  text-align:center;text-wrap:balance;
  font-size:clamp(1.12rem,1rem + .62vw,1.55rem);
  font-weight:500;letter-spacing:-.028em;line-height:1.34;color:var(--ink-2);
}
.twall-head b{font-weight:700;color:var(--ink)}

/* The panel the rows sit in: the page's own cream, one step lifted, so the
   white tiles have something to be white against. */
.twall{
  margin-block-start:clamp(1.4rem,1rem + 1.2vw,2.2rem);
  /* The page's own measure, not wider. Reaching past it put the panel under
     the scroll thread, which lives 35px outside the wrap and drew a dotted
     red line down the first column of tiles. Level with the heading also
     reads as deliberate rather than as a card that missed its column. */
  margin-inline:auto;max-inline-size:var(--wrap);
  /* room at the top for the statement now that it lives in here */
  padding-block:clamp(1.6rem,1.2rem + 1.6vw,2.6rem)
               clamp(1.3rem,1rem + 1.2vw,2rem);
  padding-inline:0;
  row-gap:clamp(1.1rem,.9rem + .9vw,1.7rem);
  background:var(--env-lift);
  border:1px solid var(--pane-line);
  border-radius:clamp(1.2rem,.8rem + 1.6vw,2.2rem);
  display:grid;gap:clamp(.6rem,.45rem + .5vw,.9rem);
  overflow:hidden;
}
/* Every second row goes the other way. Two rows travelling together read as
   one wide thing sliding; travelling against each other they read as a field
   with depth in it, which is the whole effect. */
.twall-row .marq-track{gap:clamp(.6rem,.45rem + .5vw,.9rem);align-items:stretch}
.twall-row:nth-child(even) .marq-track{animation-direction:reverse}

/* The tile. One shape, three contents. */
/* One size up, to Clay's proportions: their tiles are big enough that a logo
   sits in air rather than in a slot, and at our old 3.9rem the marks were
   filling their tiles. */
.twall-t{
  flex:none;display:flex;align-items:center;gap:.8rem;
  min-block-size:4.75rem;padding:1.05rem 1.7rem;
  background:var(--pane-solid);
  border:1px solid var(--pane-line);border-radius:.9rem;
  box-shadow:0 1px 2px rgba(26,25,23,.03);
  transition:border-color .25s var(--e-out),box-shadow .25s var(--e-out),
             transform .25s var(--e-out);
}
.twall-t:hover{border-color:rgba(26,25,23,.2);transform:translateY(-2px);
  box-shadow:0 2px 4px rgba(26,25,23,.05),0 12px 24px -14px rgba(26,25,23,.28)}

/* A name set as a wordmark: the tile is the frame, so the name does not need
   a box of its own. Ink rather than grey — these are legible statements of
   what the work is made with, not decoration. */
.twall-t .name{font-size:1.14rem;font-weight:600;letter-spacing:-.024em;
  color:var(--ink-2);white-space:nowrap;transition:color .25s var(--e-out)}
.twall-t:hover .name{color:var(--ink)}
/* Logo-ready: drop an image on a tile and it takes the place of the wordmark
   at a height that matches the type it replaces. Nothing is hotlinked — the
   file comes from the media library like every other asset on the site. */
.twall-t img{max-block-size:1.55rem;inline-size:auto;object-fit:contain}

/* The stat tile carries the numbers the "At a glance" band used to hold, so
   nothing approved left the page when the band did. */
.twall-t.is-stat{gap:.6rem;padding-inline:1.5rem}
.twall-t.is-stat .v{font-size:1.95rem;font-weight:600;letter-spacing:-.04em;
  line-height:1;color:var(--brand)}
.twall-t.is-stat .l{font-size:var(--t-xs);font-weight:600;color:var(--ink-3);
  letter-spacing:.01em;max-inline-size:13ch;line-height:1.25}

/* The wide tile, for a sentence the site already publishes elsewhere. */
.twall-t.is-note{max-inline-size:min(34rem,80vw)}
.twall-t.is-note .q{font-size:var(--t-body);line-height:1.5;color:var(--ink-2);
  white-space:normal}

@media (max-width:760px){
  .twall{margin-inline:0;border-radius:clamp(1rem,.7rem + 1.4vw,1.6rem)}
  .twall-t{min-block-size:4.1rem;padding:.85rem 1.3rem}
  .twall-t .name{font-size:1.04rem}
  .twall-t.is-stat .v{font-size:1.65rem}
}
/* Standing still, a marquee has to look composed rather than interrupted:
   the row keeps its tiles and simply stops, and the mask stops implying
   there is more coming. */
@media (prefers-reduced-motion:reduce){
  .twall-row{-webkit-mask-image:none;mask-image:none}
  .twall-row .marq-track{animation:none;flex-wrap:wrap;width:100%;
    justify-content:center}
  .twall-row .marq-track > [aria-hidden="true"]{display:none}
}

/* The mark, beside the name rather than instead of it. 1.15rem is the optical
   match for the 1.02rem wordmark next to it: these glyphs are drawn to fill
   their box where a letterform leaves side-bearings, so matched by number they
   read a size too large. */
/* Constrained by HEIGHT, not by both axes. Fourteen of these marks are square
   symbols, but the AWS file is 1.67:1 and the Azure one 3.47:1 — sized to a
   square box they would have come out squashed, which is the one thing you may
   not do to somebody's logo. Height sets the optical weight, width follows. */
.twall-t .mk{block-size:1.42rem;inline-size:auto;max-inline-size:8.5rem;flex:none;
  opacity:.92;transition:opacity .25s var(--e-out)}
.twall-t:hover .mk{opacity:1}
/* A lockup carries its own name, so it is doing the work of both the mark and
   the words and gets the height of both. */
.twall-t .mk.is-lock{block-size:1.8rem}
@media (max-width:760px){
  .twall-t .mk{block-size:1.28rem;max-inline-size:7rem}
  .twall-t .mk.is-lock{block-size:1.6rem}
}


/* ═══════════════════════════════════════════════════════════
   23 · THE FOUR PILLARS, SIDE BY SIDE  (the KEY layout only)
   The section was a 544px portrait console centred in a 1900px page with the
   four names in a thin row underneath — a third of the width carrying
   everything and two thirds carrying nothing. The instrument cannot simply be
   scaled up to fix that: it is a hand-drawn SVG on a 620x730 viewBox, so
   width buys height at 1.18x and a 1230px console would stand 1450px tall.
   What fills the page is the composition, not the drawing: the names stand
   BESIDE the instrument as a full-height contents list, which is what the
   comment at § 17 said this width was for.

   EVERY RULE HERE IS SCOPED TO .p5fams-key. The block ships two layouts and
   only one of them fits a narrow column: the key is four names, the rows
   carry a title, a description, a glyph and a link each. Unscoped, the board
   put the rows in its left column, where the grid handed the description 0px
   and the row drew its number, its title and its glyph on top of one another.
   /capabilities/ uses the rows and keeps the full measure.
   ═══════════════════════════════════════════════════════════ */
@media (min-width:1150px){
  /* A board rather than a text column: this section takes a wider measure
     than the page's reading width, because it is a picture with a legend and
     neither half is prose. */
  .p5fams-key > .wrap{
    max-inline-size:min(100% - 3rem,1480px);
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,38rem);
    column-gap:clamp(2.4rem,1.4rem + 3vw,5rem);
    align-items:start;
  }
  .p5fams-key .p5fams-head{grid-column:1 / -1;margin-block-end:clamp(2rem,1.4rem + 2vw,3.2rem)}
  /* names left, instrument right — the same order the head sets with its
     heading and lead, and the drawing is right-aligned in its own viewBox
     (xMaxYMid), so it belongs on that side. */
  .p5fam-key{grid-column:1;grid-row:2;align-self:stretch}
  .p5fams-key .p5fams-scene{grid-column:2;grid-row:2;margin-block-end:0}
  .p5page .p5fams-key .p5fams-scene .p5stagecon{max-inline-size:100%}

  /* The key stops being a strip of four columns and becomes four rows with
     room in them: one line of the contents list per system, deep enough that
     the column stands as tall as the instrument beside it instead of ending a
     third of the way down. */
  .p5fam-key{
    grid-template-columns:minmax(0,1fr);
    border-block-start:1px solid rgba(26,25,23,.12);
    border-block-end:1px solid rgba(26,25,23,.12);
  }
  .p5fam-k{
    grid-template-columns:auto minmax(0,1fr);
    align-items:center;column-gap:clamp(1rem,.7rem + 1vw,1.6rem);
    padding:clamp(1.5rem,1.1rem + 1.4vw,2.35rem) 0;
    border-inline-start:0;
    border-block-end:1px solid rgba(26,25,23,.12);
  }
  .p5fam-k:last-child{border-block-end:0}
  .p5fam-k:hover,.p5fam-k:focus-within{
    background:color-mix(in srgb,var(--fam) 6%,transparent)}
  /* the hover wash needs to reach past the text, or it reads as a highlight
     on the words rather than on the row */
  .p5fam-k::before{
    content:"";position:absolute;inset-block:0;inset-inline:-1.1rem;z-index:-1;
    border-radius:.5rem;background:inherit}
  /* A number that is a station on the list, not a footnote to it. */
  .p5fam-n{font-size:.95rem;letter-spacing:.1em;color:var(--ink-3);
    align-self:center}
  .p5fam-kt{font-size:clamp(1.35rem,1rem + 1vw,1.95rem);letter-spacing:-.032em;
    line-height:1.1}
  .p5fam-kt .sq{inline-size:.62rem;block-size:.62rem;translate:0 -.06em}
  /* the family's own rule, at the top of its row, gets the full width */
  .p5fam-k::after{inset-inline:0}
}
/* Between the old 1240 breakpoint and this one the console had a wider cap
   than the column it now sits in; the board's own grid decides it instead. */
@media (min-width:1150px) and (max-width:1400px){
  .p5fams-key > .wrap{grid-template-columns:minmax(0,1fr) minmax(0,33rem)}
}


/* ═══════════════════════════════════════════════════════════
   24 · THE INSTRUMENT, IN THE PAGE'S OWN COLOURS
   It was a graphite console: right for a "console" as an idea, wrong sitting
   on cream between a bright film and a cream tool wall, where it read as a
   black rectangle dropped onto the page. Same drawing, same signal, same
   family accents — paper instead of graphite, ink instead of light.

   `.fe` only ever renders inside this scene, so the drawing's line work is
   re-inked outright rather than themed: one token, `--fe-ink`, carries the
   ink and every hairline is an alpha of it. The other consoles on the site
   (the demos, the close) still use --con-* and are untouched.
   ═══════════════════════════════════════════════════════════ */
.fe{--fe-ink:26,25,23}

.p5fams-scene .con{
  /* lit from the top like the rest of the page's panes, not from inside */
  background-image:
    radial-gradient(120% 80% at 50% -10%,rgba(255,255,255,.9),transparent 62%),
    linear-gradient(180deg,var(--pane-solid),var(--env-lift) 60%,var(--env-base));
  background-color:var(--pane-solid);
  color:var(--ink);
  border:1px solid var(--pane-line);
  box-shadow:var(--el-2);
  /* the local remap the dark .con made, put back the right way up: labels,
     captions and titles inside the drawing all read these. */
  --ink:var(--oat-950);--ink-2:var(--oat-800);--ink-3:var(--oat-750);
  --line:rgba(26,25,23,.12);--line-2:rgba(26,25,23,.07);
  --surface:var(--pane-solid);--surface-2:var(--env-lift);
  --brand:var(--pro);--on-brand:var(--oat-50);
  --con-ink:var(--oat-950);--con-ink-2:var(--oat-800);--con-ink-3:var(--oat-750);
  --con-line:rgba(26,25,23,.12);--con-line-2:rgba(26,25,23,.07);
}
/* The bloom the console used to cast was a red glow under a black slab. On
   paper it only has to seat the panel, so it goes to a soft neutral shadow
   and the red stays where the signal is. */
.p5fams-scene::after{
  background:radial-gradient(60% 130% at 50% 0%,
    rgba(26,25,23,.10),rgba(26,25,23,.04) 45%,transparent 78%);
}

/* ── the accents, at paper strength ─────────────────────
   Measured on the light skin, every accent in the drawing was landing at
   0.76 to 0.83 lightness — pastel. Two multiplications did it: each accent
   shape carries its own opacity in the markup (.55 to .95, drawn so the
   artwork had depth against graphite) and the cluster it sits in rests at
   .78 between signal passes. Against graphite those two dim a colour toward
   black and it stays a colour. Against paper they dim it toward white, and
   #12ab66 at an effective .37 is (167,223,196) — mint, not green.

   So the floor comes up and the hues go down. Resting clusters sit at .88
   rather than .78: still a visible step when the signal lights one (the
   suite's own threshold is 0.95, which the lit state still clears), but no
   longer a wash. And the four family colours take deeper values inside this
   scene only — the same hue, more of it, because a colour chosen to glow on
   near-black is always the wrong strength on white. Amber moves furthest:
   #f2b622 on paper is barely an edge. */
.js-on .fe-cluster{opacity:.88}
.p5fams-scene{
  --fam-operations:#0a8f56;
  --fam-media:#c98708;
  --fam-applications:#0a6ad4;
  --fam-enterprise-ai:#6b3ae6;
}

/* ── chroma: each system's plate belongs to its family ───
   The accents were solid and the page still read as "poor colour", and the
   reason is area, not strength. Four thin bars of green in a white rectangle
   is a rounding error next to the rectangle. So the colour moves into the
   plate itself: a wash of the family's own hue as the paper, its edge at a
   third strength, and the recess inside it tinted rather than grey. Every
   value is a color-mix of the SAME token the row's rule, square and label
   already use, so a family is one colour in four places instead of four
   colours that nearly agree. */
.p5fams-scene .fe-op .fe-plate{fill:color-mix(in srgb,var(--fam-operations) 8%,#fffdfa);
  stroke:color-mix(in srgb,var(--fam-operations) 36%,transparent)}
.p5fams-scene .fe-me .fe-plate{fill:color-mix(in srgb,var(--fam-media) 9%,#fffdfa);
  stroke:color-mix(in srgb,var(--fam-media) 38%,transparent)}
.p5fams-scene .fe-ap .fe-plate{fill:color-mix(in srgb,var(--fam-applications) 7%,#fffdfa);
  stroke:color-mix(in srgb,var(--fam-applications) 34%,transparent)}
.p5fams-scene .fe-ai .fe-plate{fill:color-mix(in srgb,var(--fam-enterprise-ai) 7%,#fffdfa);
  stroke:color-mix(in srgb,var(--fam-enterprise-ai) 34%,transparent)}
.p5fams-scene .fe-op .fe-well{fill:color-mix(in srgb,var(--fam-operations) 13%,#f3efe6)}
.p5fams-scene .fe-me .fe-well{fill:color-mix(in srgb,var(--fam-media) 14%,#f3efe6)}
.p5fams-scene .fe-ap .fe-well{fill:color-mix(in srgb,var(--fam-applications) 12%,#f3efe6)}
.p5fams-scene .fe-ai .fe-well{fill:color-mix(in srgb,var(--fam-enterprise-ai) 12%,#f3efe6)}
/* the divider inside a plate is that family's line, not a neutral one */
.p5fams-scene .fe-cluster .fe-div,
.p5fams-scene .fe-cluster .fe-hair{stroke:color-mix(in srgb,currentColor 30%,transparent)}

/* ── the four, readable together ────────────────────────
   Stretching the list to the instrument's height was the wrong call: it made
   each row 180px deep, so at a normal window you could see three systems and
   had to scroll for the fourth — and a list of four whose fourth item is off
   screen is not a list of four. The rows go compact and the list centres
   against the instrument instead of stretching to it. All four sit inside one
   screen at 1900x950 and at 1440x900. */
@media (min-width:1150px){
  .p5fam-key{align-self:center}
  .p5fam-k{padding:clamp(.8rem,.6rem + .7vw,1.2rem) 0}
  .p5fam-kt{font-size:clamp(1.12rem,.92rem + .6vw,1.5rem)}
  .p5fam-n{font-size:.86rem}
}

/* ── the column, filled top to bottom ───────────────────
   Centring the list against a 749px instrument put 320px of nothing between
   the heading and the first system — the same emptiness this section started
   with, moved up the page. The fix is not alignment, it is that the left
   column was only carrying half of what it should: the lead was sitting in
   the head's right cell, above the instrument, where it had nothing to do
   with the picture beside it.
   So the head goes single-column and stays left, the lead follows the
   heading as prose does, the four systems follow the lead, and the
   instrument takes the whole right-hand side across both rows. One text
   column, one picture, no gaps to explain. */
@media (min-width:1150px){
  .p5fams-key > .wrap{grid-template-rows:auto 1fr}
  .p5fams-key .p5fams-head{
    grid-column:1;grid-row:1;grid-template-columns:minmax(0,1fr);
    align-items:start;gap:1.1rem;margin-block-end:clamp(1.6rem,1.2rem + 1.4vw,2.6rem);
  }
  .p5fams-key .p5fams-head .lead{max-inline-size:42ch}
  .p5fams-key .p5fams-scene{grid-column:2;grid-row:1 / span 2;align-self:start}
  .p5fam-key{grid-column:1;grid-row:2;align-self:start}
}

/* ── 25 · BOTH BOARDS TAKE THE WINDOW ───────────────────
   The tool wall and the pillars board were both capped at the page's reading
   measure, 1230px, which in a 1890px window leaves 330px of nothing down each
   side — and a section that stops a third of the way short of the glass reads
   as unfinished rather than as measured. The reason the tool wall was pulled
   back to that measure no longer exists: it was clearing the gutter thread,
   and the thread was removed two commits ago.
   Prose keeps the reading measure. These two are a picture with a legend and a
   wall of tiles — neither is prose, and both take the window. */
@media (min-width:1150px){
  /* ONE EDGE FOR BOTH. The tool wall is a panel and the pillars board is a
     .wrap, and .wrap carries 40px of its own padding — so the panel's edge
     landed 40px outside the heading below it and the two boards were
     staggered. The board drops the wrap padding and both take the same
     measure, so the panel edge, the eyebrow and the first system all start on
     the same line. `100% - 5rem` keeps 40px of air at the window edge at
     widths where 1600 is not the binding cap. */
  .twall{max-inline-size:min(100% - 5rem,1600px)}
  .p5fams-key > .wrap{
    max-inline-size:min(100% - 5rem,1600px);padding-inline:0;
    /* THE COLUMNS END TOGETHER. The instrument's height is its width times
       1.18 — it is one drawing on a fixed viewBox — so the only way to balance
       the two sides is to let the picture be a little narrower and give the
       width back to the words. At 34rem the instrument stands about 680px and
       the left column (heading, lead, four systems) reaches about the same,
       which is what removes the hole under the list without pushing the
       fourth system off the screen. */
    grid-template-columns:minmax(0,1fr) minmax(0,34rem);
    column-gap:clamp(3rem,1.6rem + 3.4vw,5.5rem);
  }
  /* the room the balance frees goes back into the list: rows deep enough to
     read as entries rather than as a table, type back up a step */
  /* measured: at 1.7rem the column ended 101px short of the instrument, so
     the rows take that back — 25px a row, four rows, and the two sides land
     level. */
  .p5fam-k{padding:clamp(1.15rem,.8rem + 1.25vw,2.1rem) 0}
  .p5fam-kt{font-size:clamp(1.25rem,1rem + .78vw,1.78rem)}
  .p5fam-n{font-size:.92rem}
}
@media (min-width:1150px) and (max-width:1400px){
  .p5fams-key > .wrap{grid-template-columns:minmax(0,1fr) minmax(0,31rem)}
}

/* ── 26 · THE BOX TAKES THE ROOM IT HAS ─────────────────
   The instrument was asked to be wider without the words beside it moving.
   Scaling the drawing could never do that — it is one SVG on a fixed viewBox,
   so width came back as 1.18x of height and the box grew down the page instead
   of across it. So the DRAWING became landscape rather than the box becoming
   bigger: each plate's three cells step 190 and 380 units apart, the plate and
   its two rules stretch to cover them, and the canvas goes from 620 to 1000
   units wide at exactly the same 730 tall. The plates are 880 units instead of
   500 — on a 1900px window, 874px instead of 467.
   Nothing about the signal changes, which is why this is the safe version: the
   spine still runs at x=44 and the plates still begin at x=92, so all four
   branches and stations connect exactly as they did.
   The one visible consequence, and it was accepted: the box starts further
   left, so the left column is narrower and the family rules under each name
   are shorter. The heading, the lead and the four names keep their size and
   their position. */
@media (min-width:1150px){
  .p5fams-key > .wrap{grid-template-columns:minmax(0,1fr) minmax(0,64rem)}
  .p5page .p5fams-key .p5fams-scene .p5stagecon{max-inline-size:100%}
}
@media (min-width:1150px) and (max-width:1500px){
  .p5fams-key > .wrap{grid-template-columns:minmax(0,1fr) minmax(0,52rem)}
}

/* ── 27 · THE SCOPE NOTES, ON THE PAGE'S OWN LINE ───────
   These callouts sit in `.wrap mid` — a 960px measure, centred — while every
   other section on the page uses the full wrap, left-aligned. At 1900 that put
   their left edge at 510 where the page's text edge is 375 and the two wide
   boards start at 150: three different left edges down one page, and the notes
   were the only thing centred, which is what made them read as borrowed from
   another site.
   They keep a measure — they are prose, and prose does not want 1150px of line
   — but they take it from the left like everything else. The author had already
   done exactly this for the verification note (§ 17); this makes it the rule
   rather than the exception.
   The text comes up to the page's body size with it: 15px was the small print
   scale, and these notes carry the argument rather than annotate it. */
.p5page .sec:has(> .wrap > .snote) > .wrap{max-inline-size:var(--wrap)}
.p5page .snote{
  max-inline-size:var(--wrap-mid);
  padding:clamp(1.35rem,1.1rem + .5vw,1.65rem) clamp(1.5rem,1.2rem + .8vw,1.95rem);
  border-radius:1.15rem;
}
.p5page .snote p{font-size:var(--t-body);line-height:1.58}
.p5page .snote-label{margin-block-end:.5rem;letter-spacing:.1em}
.p5page .snote-link{margin-top:.85rem;font-size:var(--t-sm)}

/* ═══════════════════════════════════════════════════════════
   28 · THE ADVISOR, IN CLAY'S SHAPE
   One question, one big field, a tray under it with the examples and a round
   send button. Clay's composition; this site's palette, type and machine.
   The console bar and the visible field label are gone — the heading asks the
   question and the placeholder shows the shape of an answer.
   ═══════════════════════════════════════════════════════════ */
.p5adv-head{text-align:center;max-inline-size:44ch;margin-inline:auto}
.p5adv-head h2{font-size:clamp(2.1rem,1.3rem + 2.6vw,3.6rem);letter-spacing:-.042em;
  line-height:1.02}
.p5adv-head{max-inline-size:none}
.p5adv-head .lead{max-inline-size:64ch;margin-inline:auto;margin-block-start:1rem;
  font-size:var(--t-body)}
.p5adv-head .eyebrow{justify-content:center}
.p5adv-head .eyebrow::before{display:none}

/* The panel stops being a console: no bar, no frame of its own. What the
   visitor sees is the field. */
.p5adv-panel{
  max-inline-size:62rem;margin-inline:auto;
  margin-block-start:clamp(1.6rem,1.1rem + 2vw,2.8rem);
  background:none;border:0;box-shadow:none;padding:0;
}
/* THE FIELD. A white card with a lot of room in it — the size says "a
   sentence or two", which is what the router reads best. */
.p5adv-box{
  position:relative;z-index:2;
  background:var(--pane-solid);
  border:1px solid var(--pane-line);
  border-radius:clamp(1.2rem,.9rem + 1vw,1.8rem);
  box-shadow:0 1px 2px rgba(26,25,23,.04),0 24px 48px -32px rgba(26,25,23,.28);
  padding:clamp(1.15rem,.9rem + .8vw,1.6rem);
  transition:border-color .25s var(--e-out),box-shadow .25s var(--e-out);
}
.p5adv-box:focus-within{border-color:rgba(26,25,23,.22);
  box-shadow:0 1px 2px rgba(26,25,23,.05),0 28px 56px -30px rgba(26,25,23,.34)}
.p5adv-box textarea{
  display:block;inline-size:100%;border:0;background:none;resize:none;
  font-family:var(--sans);font-size:clamp(1.02rem,.95rem + .35vw,1.18rem);
  line-height:1.55;color:var(--ink);letter-spacing:-.012em;
  min-block-size:5.5rem;padding:0;
}
.p5adv-box textarea::placeholder{color:var(--ink-3);opacity:1}
.p5adv-box textarea:focus{outline:0}
/* the label the heading replaced, kept for anything that reads rather than looks */
.p5adv-vh{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap}

/* THE TRAY. Sits under the field and slightly behind it, the way Clay's does,
   so the two read as one object with a lip rather than two stacked boxes. */
.p5adv-tray{
  position:relative;z-index:1;
  margin-inline:clamp(.9rem,.6rem + .8vw,1.6rem);
  margin-block-start:calc(-1 * clamp(.9rem,.7rem + .6vw,1.4rem));
  padding:clamp(1.1rem,.8rem + .9vw,1.7rem) clamp(.9rem,.7rem + .7vw,1.4rem)
          clamp(.7rem,.55rem + .5vw,1rem);
  background:var(--env-sink);
  border:1px solid var(--pane-line);border-block-start:0;
  border-radius:0 0 clamp(1rem,.8rem + .8vw,1.5rem) clamp(1rem,.8rem + .8vw,1.5rem);
  display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;
}
.p5adv-chips{display:flex;gap:.55rem;flex-wrap:wrap;flex:1;min-inline-size:0}
.p5adv-chip{
  padding:.62rem 1.05rem;border-radius:.8rem;
  background:var(--pane-solid);border:1px solid var(--pane-line);
  font-size:var(--t-sm);font-weight:500;color:var(--ink-2);white-space:nowrap;
  cursor:pointer;
  transition:border-color .2s var(--e-out),color .2s var(--e-out),
             transform .2s var(--e-out),box-shadow .2s var(--e-out);
}
.p5adv-chip:hover{color:var(--ink);border-color:rgba(26,25,23,.24);
  transform:translateY(-1px);box-shadow:0 2px 4px rgba(26,25,23,.05)}
.p5adv-chip.on{border-color:var(--sig);color:var(--ink)}
/* the send button: Clay's dark circle, in this site's near-black */
.p5adv-go{
  flex:none;display:grid;place-items:center;
  inline-size:3rem;block-size:3rem;border-radius:.9rem;
  background:var(--ink);color:var(--oat-50);border:0;cursor:pointer;
  transition:background .2s var(--e-out),transform .2s var(--e-out),
             box-shadow .25s var(--e-out);
}
.p5adv-go:hover{background:var(--sig);transform:translateY(-1px);
  box-shadow:0 8px 18px -8px rgba(212,43,48,.5)}
.p5adv-go .ico{inline-size:1.15rem;block-size:1.15rem}
.p5adv-form.busy .p5adv-go{opacity:.55;pointer-events:none}
.p5adv-hint{margin:.9rem 0 0;text-align:center;font-size:var(--t-xs);
  color:var(--ink-3)}
@media (max-width:620px){
  .p5adv-tray{margin-inline:.5rem}
  .p5adv-go{inline-size:2.7rem;block-size:2.7rem}
  .p5adv-chips{gap:.45rem}
  .p5adv-chip{padding:.5rem .8rem;font-size:var(--t-xs)}
}

/* The qualification stops being a card. It is one line of small print under
   the field, next to the line about where this runs — which is where a reader
   looks for that kind of statement, and it no longer reads as a panel with
   nothing in it. */
.p5page .p5adv-rest{
  margin:.35rem auto 0;padding:0;max-inline-size:60ch;
  background:none;border:0;box-shadow:none;
  text-align:center;font-size:var(--t-xs);color:var(--ink-3);
}


/* ═══════════════════════════════════════════════════════════
   29 · THE FOUR SYSTEMS, IN DAYLIGHT
   The chapter was one dark room with four graphite consoles in it. Between a
   cream hero, a cream tool wall, a paper instrument and a cream advisor, it
   was the only black thing left on the page — and a section that changes the
   lights to say "this bit is different" is a section arguing with the rest of
   the site.
   It becomes four tinted cards on the page's own ground: each one carries its
   family's colour as its paper, the way clay.com tints a section per subject,
   and each is laid out as words beside its diagram rather than words above it,
   so a card takes half the height and the whole width.
   Everything is a remap of the `--field-*` tokens the section already reads,
   plus the scene classes that hardcoded the light ink they were drawn in.
   ═══════════════════════════════════════════════════════════ */
.p5field{
  /* daylight values for the tokens the whole chapter is built on */
  --field:var(--env-base);
  --field-2:var(--pane-solid);
  --field-3:var(--env-lift);
  --field-ink:var(--oat-950);
  --field-ink-2:var(--oat-800);
  --field-ink-3:var(--oat-750);
  --field-line:rgba(26,25,23,.13);
  --field-line-2:rgba(26,25,23,.07);
  --brand:var(--pro);--on-brand:var(--oat-50);
  /* the ground below is already painted, blooms and grain and all; a section
     that paints its own is what made the page a stack of panels */
  background:none;
}
.p5field .eyebrow{color:var(--brand-text)}
/* the field carried a second measurement grid of its own — same vertical
   hairlines, same objection */
.p5field-grid{display:none}
/* the index is gone, so the column reserved for it is too */
@media (min-width:1040px){
  .p5field-body{grid-template-columns:minmax(0,1fr)}
}
/* the board measure the tool wall and the pillars use, so the three wide
   sections on this page start on one line */
@media (min-width:1150px){
  .p5field > .wrap{max-inline-size:min(100% - 5rem,1600px);padding-inline:0}
}

/* ── the card ────────────────────────────────────────────
   Family colour as paper at 10%, its own edge at 30%, and the page's
   elevation. Saturated enough that the four cards are four subjects at a
   glance; light enough that near-black type sits on them at 15:1. */
.p5field .p5demo-inner.con{
  background-image:none;
  background-color:color-mix(in srgb,var(--fam) 10%,var(--pane-solid));
  border:1px solid color-mix(in srgb,var(--fam) 32%,transparent);
  box-shadow:var(--el-2);
  color:var(--oat-950);
  --ink:var(--oat-950);--ink-2:var(--oat-800);--ink-3:var(--oat-750);
  --line:rgba(26,25,23,.13);--line-2:rgba(26,25,23,.07);
  --surface:var(--pane-solid);--surface-2:var(--env-lift);
  --brand:var(--pro);--on-brand:var(--oat-50);
}
/* the shade a card takes while the next one covers it: cream, not soot */
.p5field .p5demo-dim{background:var(--env-base)}
/* the family label becomes a pill, which is how clay.com labels a subject */
.p5field .p5demo-fam{
  padding:.4rem .85rem;border-radius:var(--r-pill);
  background:color-mix(in srgb,var(--fam) 20%,var(--pane-solid));
  color:color-mix(in srgb,var(--fam) 78%,var(--oat-950));
  font-weight:700;letter-spacing:.1em;
}
.p5field .p5demo-fam .sq{display:none}
.p5field .p5demo-lead{color:var(--oat-800)}

/* ── words beside the diagram ────────────────────────────
   Above 1100 the card is two columns: everything that is text on the left,
   the console on the right. It halves the height of a card that has to stick
   under the header while it is read, and it uses the width the board now has
   instead of leaving it beside a 66ch paragraph. Nothing is hidden — the
   stage list and its captions travel with the console. */
@media (min-width:1100px){
  .p5field .p5demo-inner{
    display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
    column-gap:clamp(1.8rem,1rem + 2.2vw,3.4rem);
    align-items:center;
  }
  .p5field .p5demo-top{grid-column:1;max-inline-size:46ch;margin-block-end:0}
  .p5field .p5console{grid-column:2}
  .p5field .p5demo-lead{margin-block-end:0}
}

/* ── the diagrams, re-inked ──────────────────────────────
   The scene classes hardcoded rgba(243,241,236,a) — the light ink they were
   drawn in — so on paper they were white on white. One token carries the ink
   now and every hairline is an alpha of it, exactly as § 21 did for the hero
   instrument. */
.p5field .p5stage{--sc-ink:26,25,23}
.p5field .sc-panel{fill:var(--pane-solid);stroke:rgba(var(--sc-ink),.14)}
.p5field .sc-panel-2{fill:var(--env-lift);stroke:rgba(var(--sc-ink),.10)}
.p5field .sc-line{stroke:rgba(var(--sc-ink),.20)}
.p5field .sc-dim{fill:rgba(var(--sc-ink),.28)}
.p5field .sc-dim-2{fill:rgba(var(--sc-ink),.15)}
.p5field .sc-txt{fill:rgba(var(--sc-ink),.62)}
.p5field .sc-txt-b{fill:rgba(var(--sc-ink),.92)}
.p5field .sc-sig{fill:var(--sig)}
.p5field .sc-sig-s{stroke:var(--sig)}

/* The panel's own overrides in § 12 reach past the --field-* tokens: the
   heading, the lead and the note take --con-* directly, and the console's
   surface is three literal darks. Those are the rules that kept the card's
   title white-on-mint and its screen graphite while everything around them
   had already come into daylight. Named individually here rather than by
   guessing a token. */
.p5field .p5demo h3{color:var(--oat-950)}
.p5field .p5demo-lead{color:var(--oat-800)}
.p5field .p5demo-note{color:var(--oat-750);
  border-inline-start-color:color-mix(in srgb,var(--fam) 45%,transparent)}
.p5field .p5console{
  background:linear-gradient(180deg,var(--pane-solid),var(--env-lift));
  border:1px solid rgba(26,25,23,.11);
  box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
             0 18px 40px -28px rgba(26,25,23,.35);
}
.p5field .p5demo.on .p5console{
  border-color:color-mix(in srgb,var(--fam) 34%,rgba(26,25,23,.11))}
.p5field .p5console-bar{
  color:var(--oat-750);background:rgba(26,25,23,.022);
  border-block-end:1px solid rgba(26,25,23,.08)}

/* The active stage was filled #211f1d — a black tile in the middle of a mint
   card, which is where the eye goes first and the last place it should. On
   paper the family's own colour marks the active one, and the rail's ticks
   come with it: their fill was a literal graphite behind a light stroke, so
   inverted they were a dark dot with no edge. */
.p5field [data-stage-part].on .sc-mod{
  fill:color-mix(in srgb,var(--fam) 10%,var(--pane-solid));
  stroke:var(--fam);
}
.p5field .sc-tick{fill:var(--pane-solid);stroke:rgba(26,25,23,.28)}
.p5field .sc-tick.lit{fill:var(--fam);stroke:var(--fam)}

/* ── family colour as INK, which is a different colour ───
   The pill, the stage number and the caption key were painted in the family's
   own hue. On graphite that was right — #12ab66 on near-black is 6:1. On the
   card it is 2.25:1, and the contrast audit caught all three. A hue chosen to
   glow on black cannot also be text on paper.
   So each family gets a second value, one level darker, for type only —
   drawn from the site's own 700-level tokens rather than invented — while the
   hue itself keeps doing the borders, the tiles and the dots. */
.p5field .p5demo[data-family="operations"]{--fam-ink:var(--matcha-700)}
.p5field .p5demo[data-family="media"]{--fam-ink:#855c05}
.p5field .p5demo[data-family="applications"]{--fam-ink:var(--berry-700)}
.p5field .p5demo[data-family="enterprise-ai"]{--fam-ink:var(--ube-700)}
.p5field .p5demo-fam{
  background:color-mix(in srgb,var(--fam) 18%,var(--pane-solid));
  color:var(--fam-ink);
}
.p5field .p5caption .k{color:var(--fam-ink)}
.p5field .p5step .n{color:var(--fam-ink)}
.p5field .p5step[aria-selected="true"]{color:var(--oat-950)}

/* ═══════════════════════════════════════════════════════════
   30 · THE LIFECYCLE ARRIVES A STAGE AT A TIME
   The ten stages were already walked stage by stage — experience.js adds
   `.lit` to each in turn, 110ms apart — but all ten were on screen before the
   walk began, so what the stagger lit was ten boxes a reader had already
   finished reading. They start hidden now and arrive in sequence, 01 to 10,
   which is the order the lifecycle actually runs in.

   The start-state is under `.js-on` and nowhere else. That is the rule the
   whole page follows: with no script, or with a script that failed, ten stages
   of a warehouse lifecycle must not be ten empty boxes. Reduced motion gets
   them all at once — experience.js already lights every step immediately in
   that case, so this is only the paint.
   ═══════════════════════════════════════════════════════════ */
.js-on .p5page .pstep{
  opacity:0;transform:translateY(12px);
  transition:opacity .5s var(--e-out),transform .5s var(--e-out),
             background .35s var(--e-out);
}
.js-on .p5page .pstep.lit{opacity:1;transform:none}
/* every way the script can fail to arrive, the stages are simply there */
html.reduce-motion .p5page .pstep,
html.motion-failed .p5page .pstep,
html.experience-failed .p5page .pstep{
  opacity:1 !important;transform:none !important;
}

/* ── and the strip takes the board's width ───────────────
   It sat on the page's reading measure, 1230px, while the tool wall, the four
   pillars and the four systems all take 1600 — so the one section that is a
   ten-column table was the narrowest thing on the page, and its cells were
   the tightest. Same measure as the rest, which is what closes the edge
   spacing. */
@media (min-width:1150px){
  .p5page .sec:has(> .wrap > .pstrip) > .wrap{
    max-inline-size:min(100% - 5rem,1600px);padding-inline:0;
  }
}

/* ── 31 · THE NOTES SIT IN THE MIDDLE ───────────────────
   § 27 pulled these to the page's text edge, on the argument that everything
   else on the page starts on that line. That was true when the page's widest
   thing was a 1230px column. It is not any more: the tool wall, the four
   pillars, the four systems and the lifecycle are all 1600px boards centred in
   the window, and a 960px note left-aligned under a centred board reads as a
   note that missed its column rather than one that chose its own.
   So they take the middle. The measure is unchanged — they are prose and prose
   keeps its line length — and the text inside them stays left-aligned, because
   centring a four-line paragraph is a different and worse idea. */
.p5page .snote{margin-inline:auto}
.p5page .snote.snote-verification{margin-inline:auto}

/* ── 32 · Rkieh Productions IN RED, ON A DARK PILL ──────────────────
   The brand red is #d42b30 and it does not go on this pill: measured against
   the pill's own near-black it is 3.5:1, and the name is 14px, so the contrast
   audit would fail it and a reader would be squinting at their own company's
   name. --sig-2 is the site's existing answer to "red, on something dark" —
   the same token the consoles used for their signal — and it measures 6.35:1
   there. Same red, one step up for the surface it sits on. */
.p5hero-kicker .kt-mark{color:var(--sig-2)}

/* ── 33 · WHY THERE ARE NO BANDS HERE ANY MORE ──
   Two mechanisms stood here and both are gone: a blurred copy of the frame
   stretched over the stage, and 90 lines of vertical gradient whose stops
   were sampled three pixels in from each edge of the master, left and right
   separately, averaged over twelve frames of the loop.

   Both were right for a film shot outdoors. A margin beside that picture had
   to become more sky and more hillside or it read as the end of a video, and
   only the film's own edge column could say what colour that was.

   Neither survives the change of subject. This scene is a studio render on
   flat cream whose outer bands sit within about six values of the page's own
   ground, so there is no landscape to continue — and worse, a fill and a
   picture agree only where their mappings agree, which past 16:9 they never
   do. Measured on the page, the fill stepped 12 of 255 down the left edge:
   the two mechanisms meant to hide a boundary were drawing one.

   The picture feathers its own edges now (see .p5hero-still), so the margin
   needs no filling at all. Nothing to re-measure if the render changes —
   only the ratio, if it is ever exported at a different shape. */

/* ═══════════════════════════════════════════════════════════
   34 · THE CLOSING FIELD
   The ending was a flat dark gradient with a telemetry diagram on it: four
   orbits, four dotted stations, four spokes and a pulsing core. The client
   removed that vocabulary across the page today, and this is the last of it.

   What replaces it is a room with light in it. One ring holds all four
   families — its hue runs green to amber across the top, blue to violet
   across the bottom — and each family is a glow in the dark where it sits on
   that line rather than a marked node. Cool light low and left, warm light
   high and right, a vignette to close the corners, and grain so the dark is
   film rather than a fill.

   EVERYTHING THAT MOVES IS TRANSFORM OR OPACITY. Four glows breathing on
   four different long cycles and the field itself drifting once every
   thirty-four seconds. No frame recomputes layout or repaints an SVG, which
   is the mistake the rotating orbits made.
   ═══════════════════════════════════════════════════════════ */
.p5close{
  /* THE ROOM IS BLACK, AND IT IS THE FOOTER'S BLACK.
     A cool lamp sat in the bottom-left corner at 10% blue. Measured at the
     seam it put rgb(36,43,54) against the footer's rgb(26,25,23) — a blue-grey
     panel meeting a warm near-black one, with a visible line between them
     down the left third of the page.
     The warm lift stays because it is high and right, nowhere near the join,
     and at 5% it never separates from the ground. The ramp ends on --oat-950,
     which is the footer's own colour, so the two are one black by the time
     they meet. The colour in this section comes from the ring and the four
     marks; the room does not need to be tinted as well. */
  background:
    radial-gradient(58% 68% at 96% 4%, rgba(214,158,88,.05), transparent 72%),
    linear-gradient(180deg,var(--con-2),var(--oat-950) 72%);
  background-color:var(--con-2);
}
.cl-field{position:absolute;inset:0;overflow:hidden;pointer-events:none}

/* ── the ring ──────────────────────────────────────────── */
.p5close-scene .cl-rings{
  /* Specificity, deliberately: two older rules size `.p5close-scene svg` — one
     here at §17 and one in phase5.css — and a bare class loses to a class plus
     an element. They capped this at 1040px and left the ring drawn small and
     hard against the left edge. */
  position:absolute;inset:0;
  inline-size:100%;block-size:100%;max-inline-size:none;
  /* the field drifts, as one composited layer. 0.7deg is under the threshold
     where a tilting ellipse looks like it is being animated; what registers
     is that the picture is not quite still. */
  animation:cl-drift 34s ease-in-out infinite alternate;
}
.cl-arc{fill:none;stroke-width:1.15;opacity:.62;stroke-linecap:round}
.cl-arc-in{stroke-width:.9;opacity:.3}
.cl-c-op{stop-color:var(--fam-operations)}
.cl-c-me{stop-color:var(--fam-media)}
.cl-c-ap{stop-color:var(--fam-applications)}
.cl-c-ai{stop-color:var(--fam-enterprise-ai)}
@keyframes cl-drift{
  from{transform:scale(1) translate3d(0,0,0) rotate(-.35deg)}
  to  {transform:scale(1.016) translate3d(0,-7px,0) rotate(.35deg)}
}

/* ── the four families, as marks riding the ring ────────── */
.cl-mark-halo{fill:var(--fam);opacity:.055}
.cl-mark-halo-2{opacity:.075}
/* the disc is opaque so the ring's line stops at the mark rather than running
   through the icon, which is what tells you the mark is ON the ring */
.cl-mark-disc{fill:#0b0b0e;stroke:var(--fam);stroke-width:1.5;opacity:.97}
.cl-ico{
  fill:none;stroke:var(--fam);stroke-width:1.35;
  stroke-linecap:round;stroke-linejoin:round;opacity:.92;
}

/* ── the room's depth and its grain ────────────────────── */
.cl-depth{
  position:absolute;inset:0;
  background:
    /* no cool lamp low and left: that corner is where this section meets the
       footer, and anything tinted there draws the join. */
    radial-gradient(40% 48% at 97% 6%, rgba(226,168,96,.06), transparent 72%),
    /* the vignette: the corners have to fall away or the panel reads as a
       rectangle of colour rather than as a space */
    radial-gradient(112% 128% at 50% 46%, transparent 44%, rgba(6,6,8,.62));
  animation:cl-lamp 26s ease-in-out infinite alternate;
}
@keyframes cl-lamp{from{opacity:.82}to{opacity:1}}
.cl-grain{
  position:absolute;inset:0;opacity:.5;mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* The scene fills the section now instead of sitting centred in it as a
   drawing, so the width rules that sized that drawing no longer apply. */
.p5close-scene{position:absolute;inset:0;display:block}
.p5close-scene .cl-field{position:absolute;inset:0}

/* Held still when the visitor has asked for that, or when the motion layer
   failed. The field keeps its light; it simply stops breathing. */
html.reduce-motion .cl-rings,html.motion-failed .cl-rings,
html.experience-failed .cl-rings,
html.reduce-motion .cl-depth,html.motion-failed .cl-depth,
html.experience-failed .cl-depth{animation:none!important}


@media (max-width:860px){
  /* NO RING ON A PHONE. Fitted to a 390px width it is a flat little oval
     sitting behind the button — read as a stray shape rather than as the room
     the ending happens in. The light stays and carries the field on its own,
     which is what a phone has the space for. */
  /* NO RING ON A PHONE, and so no marks either. Fitted to 390px the ellipse
     lands behind the lead — copy over a moving line — and the marks come out
     at eight pixels, which is a speck rather than an icon. Tried both: the
     ring alone read as a stray oval, the ring with marks read as clutter over
     the words.
     What a phone keeps is the room: the two lamps, the vignette and the
     grain. The ending is the sentence and the two actions at that width, and
     the light is there to seat them, not to compete. */
  .p5close-scene .cl-rings{display:none}
}

/* ═══════════════════════════════════════════════════════════
   35 · THE SCOPE NOTES ARE FOOTNOTES, AND A RUN OF THEM IS ONE BAND
   Two problems, and they were the same problem. Each note was a floating card
   — pane background, blur, shadow, a 3px accent bar down its left edge — and
   the three on the homepage sat in three separate full-width sections, 770px
   of page given to the small print, immediately before the ending.

   The site already had the answer written down. `.snote-verification` was
   pulled out of the card treatment long ago and set as a footnote: a hairline
   over it, a quiet label, no box. That was right, and it was right for all of
   them. So the card goes everywhere and the other tones join it, keeping only
   what distinguishes them — each label in its own tone's colour.

   And a run of them becomes a band: the claims side by side, the site-wide
   note across the full width beneath. 420px instead of 770.
   ═══════════════════════════════════════════════════════════ */
.p5page .snote{
  background:none;-webkit-backdrop-filter:none;backdrop-filter:none;
  border:0;border-radius:0;box-shadow:none;
  border-block-start:1px solid rgba(26,25,23,.18);
  padding:1.15rem 0 0;overflow:visible;
}
.p5page .snote::before{display:none}
/* the tone survives as the colour of its label, which is the one place it
   carries meaning — a 3px bar down the side of a card was decoration */
/* THE LABEL IS AN ANNOTATION, and it is set the way this site sets one: the
   mono face at .75rem, which is exactly what `.snote-verification` has always
   used. Two reasons beyond consistency. The site's rule is that no
   visitor-facing text goes under 14px unless it is on the mono annotation
   scale — a sans label at .68rem was 10.9px and broke it. And with all four
   labels on one face, the only thing separating them is the colour, which is
   the one distinction that carries meaning. */
.p5page .snote .snote-label{
  font-family:var(--mono);font-size:.75rem;letter-spacing:.13em;font-weight:500;
  color:var(--snote-acc,var(--pro-2));margin:0 0 .55rem;
}
/* THE DARK END OF EACH RAMP, because these are 12px labels on a light ground.
   The brand red measures 4.25:1 here and the site's floor is 4.5 — --pro-2 is
   the token that exists for exactly this, red where red has to be read. */
.p5page .snote-result{--snote-acc:var(--matcha-700)}
.p5page .snote-scope{--snote-acc:var(--pro-2)}
.p5page .snote-design{--snote-acc:var(--tang-700)}
/* The site-wide note is not one of the four families and must not borrow a
   family's colour, or it reads as belonging to one. It takes the ube ramp
   muted back toward ink: present enough to separate it from the two claim
   notes beside it, quiet enough that a page-level disclaimer does not shout.
   Its label keeps the mono face the footnote treatment already gave it. */
.p5page .snote-verification{--snote-acc:color-mix(in srgb,var(--ube-700) 58%,var(--ink-2))}
.p5page .snote p{margin:0;font-size:.95rem;line-height:1.62;color:var(--ink-2)}
.p5page .snote .snote-link{
  /* --t-xs, not .85rem. .85rem is 13.6px and the site's floor for anything
     off the mono annotation scale is 14. This link is neither mono nor an
     annotation; it is the note's call to action. */
  margin-block-start:.7rem;font-size:var(--t-xs);font-weight:600;color:var(--ink);
}
/* red text beside a red accent was most of why the old card read as busy */
.p5page .snote .snote-link:hover{color:var(--sig)}

/* ── the band ──────────────────────────────────────────── */
.snoteband-wrap{max-inline-size:min(100% - 3rem,1480px)}
.snoteband{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:clamp(2.4rem,1.4rem + 3vw,4.5rem);
  row-gap:clamp(2.2rem,1.6rem + 2vw,3.4rem);
  align-items:start;
}
/* THE NOTE THAT QUALIFIES THE WHOLE PAGE takes the whole width under the
   ones that qualify a single claim.

   Written at this weight on purpose. Two older rules hold this element: the
   footnote treatment caps it at 78ch, and § 31 centres every note with
   margin-inline:auto. Both are correct outside a band and both are wrong
   inside one — together they left it 1014px wide and floating in the middle
   of a 1372px row. `.p5page .snoteband > .snote.snote-verification` outranks
   them; a shorter selector loses and the cap silently wins. */
.p5page .snoteband > .snote.snote-verification{
  grid-column:1 / -1;max-inline-size:none;margin-inline:0;
}
/* an odd note left alone on the last row would sit in a half-width column
   with a half-width hole beside it; it takes the row instead */
.p5page .snoteband > .snote:last-child:nth-child(odd){
  grid-column:1 / -1;max-inline-size:none;margin-inline:0;
}
/* and every note in a band is placed by the grid, not by its own margins */
.p5page .snoteband > .snote{margin-inline:0}
@media (max-width:820px){
  .snoteband{grid-template-columns:minmax(0,1fr)}
}

/* ═══════════════════════════════════════════════════════════
   36 · THE AUDIT'S FINDINGS
   A pass over all 43 published pages at three widths. It found no overflow
   anywhere, no console errors, no broken links, no empty controls and no
   duplicate ids — and four things that were genuinely wrong. Three are here.
   ═══════════════════════════════════════════════════════════ */

/* THE DIAGRAM'S FAMILY LABELS were set in the family's display colour, which
   is tuned for a podium or a 6px dot, not for 11px letterspaced type on a
   tinted plate. Measured off the rendered pixels: media 2.72:1 and operations
   3.68:1, against a floor of 4.5. The four `--fam-ink` values already exist
   for exactly this — the four systems section uses them for the same reason —
   so the labels take them too. Applications and enterprise AI passed at 4.67
   and 5.51, but they move with the others: four labels in one row wants one
   rule, not two passing by luck and two by correction. */
.p5fams-scene .fe-op .fe-label{fill:var(--matcha-700)}
.p5fams-scene .fe-me .fe-label{fill:#855c05}
.p5fams-scene .fe-ap .fe-label{fill:var(--berry-700)}
.p5fams-scene .fe-ai .fe-label{fill:var(--ube-700)}

/* THE STAGE NUMBERS on unselected steps sat at opacity .7, which rendered
   them between 2.32:1 and 3.63:1 — the lowest contrast anywhere on the site.
   An unselected step should be quieter than the selected one, but the
   quietness has to come from the row's background and its border, not from
   making the number itself unreadable. The number goes to full strength; the
   selected state keeps its family colour and its filled background, which is
   what distinguishes it. */
.p5field .p5step .n{opacity:1}

/* ═══════════════════════════════════════════════════════════
   37 · THE ODOO MATERIAL ON /capabilities/erp/
   Nine pages under "ERP and warehouse operations" are Odoo work, and seven of
   them named Odoo once or not at all — the accounting page described chart of
   accounts, fiscal positions, analytic dimensions and landed costs without
   ever saying whose software that is. The kicker fixes the naming across all
   nine; these two blocks give the ERP page the substance the old Solutions
   site had and this one did not.
   ═══════════════════════════════════════════════════════════ */

/* ── the module honeycomb ──────────────────────────────── */
.hive{
  display:grid;grid-template-columns:minmax(0,26rem) minmax(0,1fr);
  gap:clamp(2rem,1.2rem + 2.6vw,4rem);align-items:center;
}
.hive-svg{inline-size:100%;block-size:auto;overflow:visible}
.hive-cell{
  fill:var(--pane-solid);stroke:rgba(26,25,23,.16);stroke-width:1.1;
}
.hive-t{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;
  text-anchor:middle;fill:var(--ink-2);
}
.hive-body{margin:0}
@media (max-width:900px){
  .hive{grid-template-columns:minmax(0,1fr)}
  /* the cells carry 10.5px labels; below this the drawing would scale them
     under legibility, so it steps back to a comfortable width and centres */
  .hive-svg{max-inline-size:26rem;margin-inline:auto}
}

/* ── product screenshots ───────────────────────────────── */
.shots{
  display:grid;grid-template-columns:1.55fr 1fr;
  gap:clamp(1rem,.7rem + 1.2vw,1.6rem);align-items:start;
}
.shot-col{display:grid;gap:clamp(1rem,.7rem + 1.2vw,1.6rem)}
.shot{margin:0}
.shot img{
  inline-size:100%;block-size:auto;display:block;border-radius:.6rem;
  border:1px solid rgba(26,25,23,.12);
  box-shadow:0 1px 2px rgba(26,25,23,.05),0 22px 50px -34px rgba(26,25,23,.5);
}
.shot figcaption{
  margin-block-start:.6rem;font-family:var(--mono);font-size:.72rem;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);
}
/* The attribution is not fine print to be skipped past. It is the thing that
   keeps a third party's product screenshots from reading as a partnership, so
   it sits on the page's own measure and at a size a reader can actually read. */
.shots-note{
  margin-block-start:1.5rem;font-size:.85rem;line-height:1.6;
  color:var(--ink-3);max-inline-size:78ch;
}
/* One screenshot is not a lead image with a column beside it; it is the
   figure, and it takes the measure. Capped short of full width because a
   1440px-wide interface screenshot on a 1480px board reads as a wall. */
.shots-one{grid-template-columns:minmax(0,1fr);max-inline-size:min(100%,58rem)}
@media (max-width:900px){
  .shots{grid-template-columns:minmax(0,1fr)}
}

/* ═══════════════════════════════════════════════════════════
   38 · THE INNER PAGES GET THE HOMEPAGE'S MEASURE AND RHYTHM
   The client's complaint was that every page except the homepage looks empty
   at the edges. Measured at 1907px, three separate faults were behind it:

     · the hero sat in a 1230px column and every section below it in a 960px
       one, so the headline and the first heading started 135px apart — a
       drift visible on any wide screen once you notice it
     · the homepage runs on 1600px; these ran on 1230, leaving about 950px of
       empty right side
     · --sp-sec tops out at 9.5rem, so a section with three lines in it stood
       152px clear top and bottom, against roughly 35 on the homepage. Sixteen
       pixels of page per word of content, against nine.

   The tokens are NOT overridden, deliberately. --wrap feeds --con-gut and a
   padding calculation in motion.css, and moving it would quietly re-space
   things that are not broken. These rules target the two wrappers and the two
   spacing rules directly, and stop at the body class the homepage carries.

   Prose is capped in characters rather than pixels, because the point of a
   wide measure is to let boards, grids and tables use the room — not to set
   paragraphs 1600px wide, which would trade one readability problem for a
   worse one.
   ═══════════════════════════════════════════════════════════ */
@media (min-width:1000px){
  body:not(.p5body) .wrap,
  body:not(.p5body) .wrap.mid{
    max-inline-size:min(100% - 5rem,1600px);
  }
  /* half the vertical air, which is still generous — the homepage's own
     sections sit at about a third of what these were using */
  body:not(.p5body) .sec{padding-block:clamp(2.8rem,2rem + 3vw,5rem)}
  body:not(.p5body) .sec.tight,
  body:not(.p5body) .sec-tight{padding-block:clamp(1.6rem,1.2rem + 1.6vw,2.6rem)}
  body:not(.p5body) .phero{
    padding-block:clamp(2.6rem,2rem + 2.4vw,4rem) clamp(1.4rem,1rem + 1.4vw,2.2rem);
  }

  /* ── prose keeps a reading measure inside the wide one ── */
  body:not(.p5body) .sec-head{max-inline-size:74ch}
  body:not(.p5body) .phero .lead{max-inline-size:70ch}
  body:not(.p5body) .rt{max-inline-size:76ch}
  body:not(.p5body) .snote{max-inline-size:80ch}
  /* a lone paragraph directly in a wrap is prose too */
  body:not(.p5body) .wrap > p,
  body:not(.p5body) .wrap.mid > p{max-inline-size:76ch}
}

/* ═══════════════════════════════════════════════════════════
   35 · THE MENU IS THE BAR, CONTINUED
   The panel used to be a card floating under whichever trigger opened it —
   a second object, with its own corners, its own shadow and its own left
   edge that moved as you read across the bar. Four triggers meant four
   different panels appearing in four different places.

   One panel now, the width of the bar, flush against its underside, in the
   bar's own fill and behind the bar's own ring. While it is open the bar
   gives up its bottom corners and the panel takes them, so the two are one
   card that grew rather than two that met. That is the whole trick, and it
   is why the seam between them cannot be seen: there is no seam.
   ═══════════════════════════════════════════════════════════ */

/* the panel's containing block is the BAR, not the trigger — which is what
   makes one full-width panel possible at all. */
.hdr .nav-item{position:static}
.hdr-in{position:relative}
/* the turn-around rules existed to stop a trigger-anchored panel running off
   the right of the window. A panel pinned to both edges cannot. */
.nav-item:nth-last-child(-n+2) .mega,
.nav-item:nth-last-child(-n+3) .mega{inset-inline:0}

.hdr .mega{
  position:absolute;top:100%;inset-inline:0;
  inline-size:auto;max-inline-size:none;min-inline-size:0;
  background:#fbf9f5;
  border:0;
  border-radius:0 0 var(--r-hdr) var(--r-hdr);
  box-shadow:0 0 0 1px rgba(26,25,23,.08),
             0 26px 44px -28px rgba(26,25,23,.34);
  padding:1.25rem 1.35rem 1.35rem;
  transform:translateY(-8px);
  transition:opacity .22s var(--e-out),transform .26s var(--e-out),visibility .22s;
}
/* the bar squares off underneath an open panel, so the corner belongs to the
   pair rather than to the bar. :has() is the only way to know from the bar
   that something inside it is open without asking JavaScript to say so. */
.hdr-in:has(.nav-item:hover > [data-mega]),
.hdr-in:has([data-mega].open){
  border-end-start-radius:0;border-end-end-radius:0;
}

/* THE ROWS SET THE HEIGHT AND THE CARD ADAPTS TO IT — not the other way
   round. Sized to its own picture the card ran a hundred pixels taller than
   two rows of links, and the panel carried that as empty space across two
   thirds of its width. Stretched instead, the card is exactly as tall as the
   menu beside it and its picture takes whatever is left over. */
.mega-inner{display:flex;gap:2rem;align-items:flex-start;justify-content:space-between}
/* the rows are a block, not a band. Stretched across the full width they
   left each label stranded at the head of a 580px row; capped, they read as
   one group with the card set against it and air between the two. */
.hdr .mega-cols{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  gap:.4rem 1.5rem;align-items:start;flex:0 1 38rem;min-inline-size:0}
/* a single-group panel has no columns to spread, so it reads as one list and
   gives the rest of the width back to the card. */
.hdr .mega-col-plain{grid-column:auto}

/* ── the column heading: a label, at label size ──────────── */
.hdr .mega-h{
  display:flex;align-items:center;gap:.5rem;margin:0 0 .55rem;padding:0 .55rem;
  font-size:.66rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3);
}
.hdr .mega-h .sq{inline-size:.42rem;block-size:.42rem;border-radius:.13rem;
  background:var(--fam,var(--brand));flex:none}

/* ── the row: a plate, and the name of the thing ─────────── */
/* ONE FAMILY PER PANEL, SO THE LINKS FLOW RATHER THAN SIT IN NAMED COLUMNS.
   Clay's panel is divided into four titled groups because its items are four
   different kinds of thing. Every panel here holds one kind — ERP systems is
   seven ERP pages — so a title over each column would be a label that
   labels nothing. The rows flow into as many columns as the width affords
   instead, which is the same scan with nothing invented on top of it. */
/* TWO COLUMNS, NOT THREE. Three fitted the count but not the words: at a
   third of the block "ERP and business operations" took two lines and its
   row stood taller than every other, which is a ragged menu. Two columns
   give every label in the set a single line. */
.hdr .mega-links{display:grid;gap:.12rem 1rem;
  grid-template-columns:repeat(2,minmax(0,1fr))}
.hdr .mega a:not(.mega-card){
  display:flex;align-items:center;gap:.7rem;
  padding:.5rem .55rem;border-radius:.7rem;
  transition:background .16s var(--e-out);
}
.hdr .mega a:not(.mega-card):hover,
.hdr .mega a:not(.mega-card):focus-visible{background:rgba(26,25,23,.045)}
.hdr .mega a strong{font-size:.925rem;font-weight:550;letter-spacing:-.012em;color:var(--ink)}

/* THE PLATE. Every capability on the first screen stands on a white podium
   plate on the cream field; these are those plates, at menu size. It is the
   one borrowed shape in here, and it is borrowed from the product's own
   picture rather than from another company's menu. */
/* EVERY ROW ITS OWN COLOUR, FROM A CLOSED SET. One accent per family made
   twenty rows of the same green: technically tinted, and grey at a 1.6px
   stroke and 17px. The plate is tinted to its icon instead, from a fixed
   palette of nine — not a hue per row picked at random, which is confetti,
   but one colour per KIND of thing, reused wherever that kind appears. Money
   is green everywhere in here; people are purple everywhere in here. */
.hdr .mega .plate{
  --i:var(--fam,var(--brand));
  inline-size:2rem;block-size:2rem;flex:none;
  display:grid;place-items:center;
  border-radius:.62rem;
  background:color-mix(in srgb,var(--i) 13%,#fff);
  color:var(--i);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--i) 20%,transparent),
             0 2px 6px -4px color-mix(in srgb,var(--i) 55%,transparent);
  transition:transform .16s var(--e-out),box-shadow .16s var(--e-out),
             background .16s var(--e-out);
}
.hdr .mega .plate .ico{stroke-width:1.85}
.hdr .mega a:hover .plate{background:color-mix(in srgb,var(--i) 20%,#fff)}
/* the closed set */
.hdr .mega .plate[data-i="layers"]   {--i:#d81f3c}   /* the system itself */
.hdr .mega .plate[data-i="wallet"]   {--i:#0f9d58}   /* money */
.hdr .mega .plate[data-i="scale"]    {--i:#0f9d58}
.hdr .mega .plate[data-i="target"]   {--i:#0a83f5}   /* customers */
.hdr .mega .plate[data-i="chart"]    {--i:#0a83f5}
.hdr .mega .plate[data-i="cart"]     {--i:#e8892b}   /* goods moving */
.hdr .mega .plate[data-i="cube"]     {--i:#e8892b}
.hdr .mega .plate[data-i="grid"]     {--i:#e8892b}
.hdr .mega .plate[data-i="users"]    {--i:#8358f4}   /* people */
.hdr .mega .plate[data-i="briefcase"]{--i:#8358f4}
.hdr .mega .plate[data-i="clock"]    {--i:#0fa3a3}   /* time and delivery */
.hdr .mega .plate[data-i="refresh"]  {--i:#0fa3a3}
.hdr .mega .plate[data-i="arrow"]    {--i:#0fa3a3}
.hdr .mega .plate[data-i="phone"]    {--i:#2b6cf0}   /* software surfaces */
.hdr .mega .plate[data-i="link"]     {--i:#2b6cf0}
.hdr .mega .plate[data-i="server"]   {--i:#2b6cf0}
.hdr .mega .plate[data-i="sparkle"]  {--i:#8358f4}   /* the model */
.hdr .mega .plate[data-i="lock"]     {--i:#6b52d6}
.hdr .mega .plate[data-i="pin"]      {--i:#d81f3c}   /* places */
.hdr .mega .plate[data-i="quote"]    {--i:#6b7cff}
.hdr .mega a:hover .plate{
  transform:translateY(-1px);
  box-shadow:0 1px 0 rgba(26,25,23,.05),
             0 6px 14px -6px rgba(26,25,23,.42);
}
.hdr .mega .plate .ico{inline-size:1.05rem;block-size:1.05rem;margin:0}

/* ── the card: the scene itself ──────────────────────────── */
.hdr .mega .mega-card{
  display:block;flex:0 0 18.5rem;padding:0;overflow:hidden;
  border-radius:.9rem;background:var(--env-base);
  box-shadow:0 0 0 1px rgba(26,25,23,.07);
  transition:box-shadow .18s var(--e-out);
}
.mega-card:hover{background:var(--env-base);box-shadow:0 0 0 1px rgba(26,25,23,.14)}
/* 16:10, not the crop's own 4:3 — the panel's height is whatever the card
   needs, and a 4:3 card made it half again as tall as the rows beside it,
   which left a third of the panel empty. */
/* the drawn scene takes its accent from the panel it is in, and sits on a
   wash of the same colour so the card is one temperature. */
.mega-card-art{display:block;overflow:hidden;aspect-ratio:16/10;
  --art:var(--fam,var(--brand));
  --wash:color-mix(in srgb,var(--fam,var(--brand)) 8%,#faf7f2)}
.mega-card-art img{display:block;inline-size:100%;block-size:100%;object-fit:cover;
  transition:transform .5s var(--e-out)}
.mega-card:hover .mega-card-art img{transform:scale(1.03)}
/* `.mega span{display:block}` in site.css is one class and one element, so
   it outranks a lone `.mega-card-go` and forced the arrow onto its own line.
   Scoped past it rather than fought with !important. */
.hdr .mega .mega-card-body{display:block;padding:.8rem .9rem .9rem}
.hdr .mega .mega-card-body strong{display:block;font-size:.95rem;font-weight:600;
  letter-spacing:-.016em;color:var(--ink);line-height:1.25}
.hdr .mega .mega-card-lead{display:block;margin-top:.28rem;font-size:.8rem;
  line-height:1.45;color:var(--ink-3)}
.hdr .mega .mega-card-go{display:inline-flex;align-items:center;gap:.34rem;
  margin-top:.55rem;white-space:nowrap;
  font-size:.78rem;font-weight:600;letter-spacing:-.01em;color:var(--brand)}
.hdr .mega .mega-card-go svg{inline-size:.85rem;block-size:.85rem;flex:none;
  transition:transform .2s var(--e-out)}
.mega-card:hover .mega-card-go svg{transform:translateX(3px)}

/* Below the desktop bar the drawer owns navigation, and none of this exists. */
@media (max-width:999px){ .hdr .mega{display:none} }
@media (prefers-reduced-motion:reduce){
  .hdr .mega{transform:none;transition:opacity .01s,visibility .01s}
  .hdr .mega .plate,.mega-card-art img,.mega-card-go svg{transition:none}
  .hdr .mega a:hover .plate{transform:none}
}

/* ═══════════════════════════════════════════════════════════
   34. CLAY PARITY — the hero's measure, and the section that
       rises into it
   ───────────────────────────────────────────────────────────
   Asked for on 2026-09-05: Clay's type and "how the second section is
   inherited in the first one". Everything below is a value read off
   clay.com at four widths on that date, not an approximation:

     viewport    container   inner pad  title col  gap  hero skirt  radius
     1920x1080   1280 @x320     48        720      24      264        48
     1440x900    1280 @x80      48        720      24      228        48
     1280x800    1216 @x32      48        720      24      208        48
     1024x768     973 @x26      48        649      24      202        48
      390x844     371 @x10      28        315      16       48        28

   Two facts drive the whole block. First, their container is a fixed 1280
   that centres — the side gutter only bites below 1280 + 2·32. Second, the
   card that follows the hero is pulled up by EXACTLY the hero's bottom
   padding, at every width: -228 against 228, -264 against 264, -48 against
   48. So the card's top edge always lands on the hero copy's bottom edge and
   the skirt below the copy is the part it covers. That is the whole effect —
   not a magic number, a rule.

   What is NOT copied: their green, their white type, and Roobert. The first
   two are brand (#DE1940 / #1D1D1E stand), and Roobert VF is a licensed face
   from Displaay — it is not ours to ship. Plus Jakarta Sans keeps the three
   settings that were already theirs and are free to be: 575 weight, a 1.0
   line, -0.04em.
   ═══════════════════════════════════════════════════════════ */

:root{
  /* the skirt: the band of hero below the copy that the next card covers.
     ~25vh on a desktop is what Clay's four desktop widths average out to
     (25.3, 24.4, 26.0, 26.3); their phone uses a flat 48px and so does ours. */
  --hero-skirt:3rem;
  /* THE PEEK — how much of the next card the first screen shows. Theirs is
     56px at 1440x900: hero copy ends at 844, the card starts at 844, the fold
     is at 900. That is the whole reason their second section reads as part of
     the first rather than as the thing after it, so it is a published number
     here rather than whatever the padding happened to leave over. */
  --hero-peek:3.5rem;
  --clay-gutter:clamp(.625rem,2.5vw,2rem);   /*  10px -> 32px  */
  --clay-inner:clamp(1.75rem,1.2rem + 1.6vw,3rem);   /*  28px -> 48px  */
}
@media (min-width:1000px){
  :root{--hero-skirt:clamp(9rem,25vh,16.5rem)}   /* 144px -> 264px */
}
/* 56px is what their arithmetic yields at 1440x900; it is not a constant of
   theirs. Their hero is a fixed ~1072 tall, so the card shows 48px at 768 and
   800-tall windows and 272px at 1080 — what actually holds at every width is
   the card's top sitting on the copy's bottom, which it does here too. So a
   short window takes their 768/800 figure rather than their 900 one, and the
   40px it gives back is what keeps the copy in the lower half of the frame at
   1152x700, where it was landing on the 50% line exactly. */
@media (max-height:800px){
  :root{--hero-peek:2.5rem}
}

/* ── the hero gets its skirt ─────────────────────────────── */
/* Three lines, and between them they place both edges:

     hero height      = 100svh - peek + skirt
     copy's bottom    = hero height - skirt  = 100svh - peek
     card's top       = hero height - skirt  = 100svh - peek

   so the copy ends `peek` above the fold, the card starts on exactly that
   edge, and the skirt is the band of hero it covers. It is their arrangement
   stated as arithmetic: their negative margin equals their hero's bottom
   padding at every width, which is the same thing as saying the card's top
   sits on the copy's bottom.

   The hero's own bottom padding is now the skirt itself rather than a
   separate value added to it. The two short-viewport rules that used to set
   it are withdrawn above: they existed to keep the primary action off the
   fold on a short screen, and the peek does that unconditionally now — the
   copy ends 56px clear of the bottom at every height, which is more than
   either of them was buying. */
.p5hero{
  min-block-size:calc(100svh - var(--hero-peek) + var(--hero-skirt));
  padding-block-end:var(--hero-skirt);
}
/* Stacked, the hero is content-height (min-block-size:auto at ≤999) — the
   skirt is still real padding there, so the card still has something to
   climb over. */
@media (max-width:999px){
  .p5hero{min-block-size:auto}
}

/* ── Clay's container, exactly ───────────────────────────── */
/* DESKTOP ONLY, and the reason is our lead, not their container. Theirs is a
   371px phone container with 28px of inner padding — 315px of measure — and
   it holds because their lead is three lines. Ours is nine at that width and
   ten at 315, and the tenth put the second action 2px under the fold at
   390x844. The phone keeps the measure it was tuned for; parity starts where
   the two-column composition does. */
@media (min-width:1000px){
  .p5hero-in{
    max-inline-size:min(1280px, 100% - (var(--clay-gutter) * 2));
    margin-inline:auto;
    padding-inline:var(--clay-inner);
  }
}
/* 720 / 24 / the rest — their split, and the reason our headline can hold two
   lines at all. 40rem (640px) was the old cap and "Where Your Business"
   measures 811px at 88px, so it broke to four; 720 is Clay's own column and
   takes it to three, and the 16:9 rule below still widens to 54rem where the
   window is wide enough for two. */
/* 680, NOT THEIR 720 — and the 40px is our copy, not a rounding. Inside the
   1280 container a 720 column leaves 440 for the body, which is exactly what
   theirs has and exactly what ours cannot use: at 440 the lead runs to eight
   lines instead of seven, its top climbs from 537 to 435 and lands on the
   film's server podium, and "Start a conversation" and "See what we do" stop
   fitting side by side and stack. Measured 720 / 700 / 693 / 680: 680 is the
   widest column where the buttons still sit on one line and the lead still
   starts at 537, clear of the podiums. It still buys the headline the third
   line the old 640 cap could not — that was the point of widening at all. */
/* THE TWO-COLUMN BREAKPOINT MOVES 1150 -> 1344, because the column that
   splits them is now a fixed 680 rather than a 1.3fr that shrank with the
   window. 1344 is not a taste: Clay's container is capped at 1280 and its
   gutter is 32, so 1280 + 64 is precisely the width below which the container
   starts shrinking — and every pixel it loses comes out of the body column,
   which is the only one that is not fixed. Under it the body falls below the
   462px that "Start a conversation" and "See what we do" need to sit on one
   line, and by 1152 it is down to 315px, the lead runs long enough to push
   the headline to 47% of the window, and the composition test that holds the
   words to the lower half fails.
   One column from 1150 to 1343 instead, which is what the original rule
   already did below 1150 and for the same stated reason. It also returns the
   two actions to a single line at 1250 and 1280, where they had been stacking
   since before any of this. */
@media (min-width:1150px) and (max-width:1343px){
  .p5hero-in{display:block}
  .p5hero-head,.p5hero-body{max-inline-size:none}
}
@media (min-width:1344px){
  .p5hero-in{grid-template-columns:680px minmax(0,1fr);column-gap:24px}
  .p5hero-head{max-inline-size:680px}
  /* the column is the measure now, as it is on theirs */
  .p5hero .lead{max-inline-size:none}

  /* TOP-ALIGNED, not bottom-aligned. The two columns used to hang from the
     same baseline — align-items:end — which reads correctly only while the
     headline is the taller of the two. It is 264px at 88px over three lines
     and the body is 218, so on a tall window the headline started 22px ABOVE
     the description and looked roughly level. Under 841px tall the type steps
     to ~50px, the headline becomes 100px, and hanging it from the bottom drops
     its first line more than a hundred pixels below the description's — the
     two stop reading as one row at exactly the sizes a laptop with browser
     chrome actually has.
     Starting them together fixes it at every height: the headline's first line
     and the description's first line begin on the same edge, and the slack
     falls at the bottom of whichever column is shorter. The h1's top margin
     goes with it — 14px of it, which would otherwise sit between the two tops
     and undo the alignment it is meant to create. */
  .p5hero-in{align-items:start}
  .p5hero h1{margin-block-start:0;
    /* BOXES LEVEL IS NOT INK LEVEL. Measured off the rendered page: the
       headline's first dark pixel falls 12.1px below its own box top and the
       description's falls 7.6px below its own, because the headline is set
       solid at line-height 1 while the description carries half a line of
       leading. Matching the boxes therefore leaves the two first lines 4.5px
       apart, which at 88px is exactly the kind of miss that reads as "not
       quite aligned" without being nameable.
       -0.05em is that 4.5px at 88px and shrinks with the type, and it is set
       as a relative offset rather than a margin so it moves the headline
       without changing the row's height — a margin would have shortened the
       column and pushed the description down by the same amount instead. */
    position:relative;top:-.05em}
}
/* Section 10's 16:9 widening has to be restated, because it is declared ABOVE
   this block and the 720 would otherwise win by source order and cost
   1920x1080 the two-line break it already had. Theirs is a flat 720 at every
   width and still sets in two, because "Build systems to grow revenue" is
   four words. Ours needs 811px for "Where Your Business", so past 16:9 the
   column takes the 54rem the aspect can afford and the headline reads as
   Clay's does. */
/* SECTION 10'S 16:9 WIDENING IS WITHDRAWN, not restated. It existed to give
   the old eight-word headline a third line instead of a fourth, and it worked
   because the hero container was then 1568px wide at 1920 — 864 for the head
   still left 682 for the body. Clay's container is 1280, so the same 864 now
   leaves 296: the lead would run twelve lines over the film and the buttons
   would stack. And under 841px tall, where the type has already stepped to
   ~50px, 864 of measure put the whole sentence on ONE line and dropped the
   block to 84-86% of the window — measured failing at 1440x700, 1366x768 and
   1280x720. So the head is held to 680 at every desktop aspect. The headline
   sets in three lines throughout rather than two here and four there, which
   is also the more consistent first screen. */
@media (min-width:1000px) and (min-aspect-ratio:16/9){
  .p5hero-head{max-inline-size:min(100%,680px)}
}

/* ── the second section rises into the first ─────────────── */
/* THE PULL-UP IS THE HOMEPAGE HERO'S, NOT EVERY PAGE'S. This card rises over
   the hero's skirt — the band of ground the hero leaves below its copy for
   exactly this. /capabilities/erp/ has no such skirt: its first block is the
   split clay card, so the wall climbed 225px over the film instead. `p5body`
   is set only when the first section is the flow hero, which is the condition
   that guarantees a skirt to climb. */
.p5body .twall-sec{
  margin-block-start:calc(-1 * var(--hero-skirt));
}
.twall-sec{position:relative;z-index:3}
/* The section's top padding has to go to zero or the card lands that far
   BELOW the copy instead of on it — measured 35px adrift, which is what took
   the peek from 56px down to 21. `.twall-sec` alone cannot do it: the padding
   comes from `.p5page .sec.tight` at (0,3,0) and loses to nothing weaker, so
   this is stated at the same weight and later. The card keeps its own inner
   padding — that is where the space above the statement belongs, and it is
   48px on theirs. */
.p5page .sec.twall-sec{padding-block-start:0}
.twall{
  margin-block-start:0;
  max-inline-size:min(1280px, 100% - (var(--clay-gutter) * 2));
  /* 48px flat from 1024 up — measured at 1024, 1280, 1440 and 1920, all 48 —
     and 28px on a phone, which is the only place theirs steps down. A clamp
     between the two lands on 40-42px across the desktop range and is simply
     the wrong number, so this is two steps rather than a ramp. */
  border-radius:1.75rem;
  padding-block-start:var(--clay-inner);
}
@media (min-width:1000px){
  .twall{padding-block-start:3rem}   /* theirs, flat 48 */
}
@media (min-width:1000px){
  .twall{border-radius:3rem}
}
@media (max-width:760px){
  .twall{margin-inline:auto}
}

/* ═══════════════════════════════════════════════════════════
   35. THE SYSTEM WALL — Clay's tabbed section
   ───────────────────────────────────────────────────────────
   Values read off clay.com on 2026-09-05, not approximated:

     heading      72px / 500 / line-height 1.0 / -0.03em / centred
     pill         44px tall, 12px radius, 10px 16px, 16px / 500
     pill (off)   #F4F3F0 on #1B1A18
     pill (on)    a pale tint of that tab's accent
     plate        1280 x 413, 48px radius, the accent at full strength

   The plate is the same 1280 container and the same 48px radius as the tool
   wall above it, so the page keeps one geometry rather than acquiring a
   second one.
   ═══════════════════════════════════════════════════════════ */

/* Clipped on the inline axis only. The rail is deliberately wider than the
   page and must not widen it; the screen is deliberately TALLER than its
   plate and must not be cut. `clip` on one axis with `visible` on the other
   is the one pairing that does not silently become `auto`. */
.ctabs-sec{overflow-x:clip;overflow-y:visible}
.ctabs-head{text-align:center;display:grid;justify-items:center}
.ctabs-h{
  /* theirs, and it is a step down from the hero's 88 rather than a match —
     a section heading that equals the page's h1 flattens the hierarchy. */
  font-size:clamp(2.2rem,1.1rem + 3.1vw,4.5rem);
  line-height:1;letter-spacing:-.03em;font-weight:500;
  text-wrap:balance;max-inline-size:20ch;margin:0;
}
.ctabs-sub{
  margin-block:clamp(.9rem,.7rem + .9vw,1.4rem) 0;
  max-inline-size:46ch;color:var(--ink-2);text-wrap:balance;
  /* The sentence changes with the tab and the tabs change on a timer, so the
     swap is a crossfade rather than a jump. Height is not animated: these are
     one- and two-line sentences and settling the block on every tick reads as
     the page twitching. */
  transition:opacity .22s var(--e-out);
}
[data-ctabs][data-js] .ctabs-sub.is-out{opacity:0}

/* ── the rail ────────────────────────────────────────────── */
/* Edge-masked rather than cut: the row is wider than the page at every width
   worth having eight pills at, and a hard edge reads as a bug where a fade
   reads as "there is more of this". */
.ctabs-rail{
  margin-block-start:clamp(1.4rem,1.1rem + 1.4vw,2.2rem);
  overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.ctabs-rail::-webkit-scrollbar{display:none}
/* Dragged by hand. `grab` is the affordance; `grabbing` only appears once a
   drag actually starts, so a plain click on a pill never flickers the cursor.
   Touch is left alone — it already scrolls, with momentum this cannot match. */
@media (hover:hover) and (pointer:fine){
  .ctabs-rail{cursor:grab}
  .ctabs-rail.is-dragging{cursor:grabbing;scroll-behavior:auto}
  .ctabs-rail.is-dragging .ctabs-pill{pointer-events:none}
}
.ctabs-track{
  display:flex;gap:.5rem;width:max-content;
  padding-inline:max(var(--clay-inner), calc((100vw - 1280px) / 2));
  padding-block:.25rem;
}
.ctabs-pill{
  flex:none;min-block-size:44px;padding:10px 16px;border-radius:12px;
  border:0;background:#F4F3F0;color:#1B1A18;
  font:inherit;font-size:1rem;font-weight:500;letter-spacing:-.01em;
  cursor:pointer;white-space:nowrap;
  transition:background .25s var(--e-out),color .25s var(--e-out);
}
.ctabs-pill:hover{background:#EBE9E4}
/* The selected tab is the solid accent with white type, as every other pill
   on the site now is — a pale tint read as a disabled state beside them. */
.ctabs-pill.is-on{background:var(--accent);color:#fff}
.ctabs-pill:focus-visible{outline:2px solid var(--ink);outline-offset:3px}

/* ── the plate and the screen on it ──────────────────────── */
/* The overhang needs somewhere to go, so the stage carries it as padding —
   otherwise the screen's top edge lands on the pills and its bottom edge on
   whatever section follows. */
.ctabs-stage{
  margin-block-start:clamp(1.6rem,1.2rem + 1.6vw,2.6rem);
  padding-block:clamp(2.5rem,1.6rem + 4.6vw,7.6rem) 0;
  /* The same container the hero and the tool wall use. Left on `.wrap` the
     plate ran to 1520 at 1920 and the ratio stopped being theirs — measured,
     plate 1520x490 and the overhang down to 19px. */
  max-inline-size:min(1280px, 100% - (var(--clay-gutter) * 2));
  margin-inline:auto;padding-inline:0;
}
.ctabs-plate{
  position:relative;
  border-radius:3rem;background:var(--accent);
  /* 1280 x 413 is theirs, and it has to be the plate's REAL height. As a grid
     with the screen inside it, the box grew to the screen's 529 instead and
     the overhang came out as zero — measured, plate 1280x529, overhang 0 top
     and bottom. Taking the screen out of flow is what makes the ratio hold:
     the plate is a colour behind a screen, not a frame around one. */
  aspect-ratio:1280 / 413;
}
/* THE FADE IS THE WHOLE TRICK. Their plate is fully saturated — measured
   rgb(59,211,253), rgb(203,216,16), rgb(161,123,249), rgb(255,119,20) — and
   it only LOOKS pale because a gradient runs up from the bottom, transparent
   to that same colour, and takes the screen with it. `home-uses_shade` on
   their page is 257px of it against a 413px plate: 62%.
   So the screen is anchored to the plate's bottom rather than centred, sticks
   out only at the top, and dissolves into the colour before the plate's lower
   edge. Nothing is cropped and no bottom edge is ever drawn — which is why it
   reads as a screen going on past the frame rather than a picture stuck on a
   rectangle. */
.ctabs-plate::after{
  content:"";position:absolute;inset-inline:0;inset-block-end:0;
  block-size:62%;border-radius:0 0 3rem 3rem;
  /* 62% is their height. The extra transparent stop at the top is the part
     that keeps the screen readable: a straight two-stop ramp starts tinting
     at the halfway line and the table goes green while it is still the thing
     being looked at. Theirs holds full opacity down to roughly two thirds and
     spends the last third dissolving. */
  background:linear-gradient(to bottom,
    rgb(255 255 255 / 0) 0%, rgb(255 255 255 / 0) 34%, var(--accent) 94%);
  pointer-events:none;
}
.ctabs-shot{
  position:absolute;inset-block-end:0;inset-inline-start:50%;
  translate:-50% 0;
  /* 74% of 1280 is 947, which at 16:9 stands 533 against a 413 plate. Bottom-
     anchored, that is 116px of overhang at the top and none at the bottom. */
  inline-size:74%;max-inline-size:940px;block-size:auto;
  border-radius:.9rem .9rem 0 0;
  /* Lifted from the top and the sides only. A downward shadow would draw the
     bottom edge the fade exists to remove. */
  box-shadow:0 1px 2px rgba(26,25,23,.06),
             0 -2px 10px rgba(26,25,23,.05),
             0 12px 34px -14px rgba(26,25,23,.28);
}

/* ── one panel at a time, but only once script says so ───── */
/* Without JS every panel is in flow and all eight are readable, stacked. The
   attribute is set by phase5.js after it binds, so there is no window in
   which a panel is hidden and nothing can reveal it. */
.ctabs-panel + .ctabs-panel{margin-block-start:1rem}
[data-ctabs][data-js] .ctabs-panel{display:none;margin-block-start:0}
[data-ctabs][data-js] .ctabs-panel.is-on{display:block}

@media (max-width:860px){
  /* A 1672-wide screen at 311px is a texture, not a screenshot — nothing in
     it can be read on a phone whatever the ratio. So the plate gets taller and
     the screen gets nearly the full width: the point on a phone is that this
     IS a working screen, and the tab label says which one. */
  .ctabs-plate{aspect-ratio:1280 / 600;border-radius:1.75rem}
  .ctabs-shot{inline-size:92%;border-radius:.5rem}
  .ctabs-h{max-inline-size:none}
  .ctabs-stage{padding-block:clamp(1rem,4vw,2rem)}
}
@media (prefers-reduced-motion:reduce){
  .ctabs-sub{transition:none}
}

/* ── the floating cards ──────────────────────────────────
   Theirs sit half on and half off the plate, at two different heights, with a
   dotted line running between them. The effect is depth: the screen is a
   surface and these are things standing in front of it.

   Positioned against the PLATE, not the screen. The screen is 74% of the
   plate and bottom-anchored; hanging the cards off it would move them every
   time the ratio changed and would put them inside the fade, which is the one
   place a card must not be — the fade exists to dissolve the screen, and a
   card dissolving with it reads as a rendering fault. */
.ctabs-card{
  position:absolute;z-index:2;
  inline-size:clamp(11rem,17vw,17.5rem);block-size:auto;
  border-radius:.85rem;background:#fff;
  border:1px solid rgba(26,25,23,.07);
  box-shadow:0 2px 6px rgba(26,25,23,.07),
             0 18px 40px -12px rgba(26,25,23,.26);
}
/* Left card low, right card high — their asymmetry, and it is what stops the
   pair reading as a caption bar under the screen. */
.ctabs-card-a{inset-inline-start:-1.5%;inset-block-end:-9%}
.ctabs-card-b{inset-inline-end:-1%;inset-block-start:-16%}

/* The dotted run between the two cards is gone (2026-09-05). Theirs joins a
   checklist card to a "Send to CRM" pill — two things in a sequence, so a line
   means something. Ours joins a stock panel to a low-stock badge, which are not
   steps in anything, and the line just crossed the screen behind them. */

/* Under the two-column breakpoint the plate is short and the cards would sit
   on top of the screen rather than beside it, so they step out of the way.
   The screen alone still makes the point. */
@media (max-width:1099px){
  .ctabs-card{display:none}
}

/* ═══════════════════════════════════════════════════════════
   36. THE FOUR SYSTEMS — Clay's section, exactly
   ───────────────────────────────────────────────────────────
   Their shape, measured on clay.com: a pale tinted card at 48px radius, copy
   in the left column and one square illustration in the right, the two
   columns roughly even. A small pill eyebrow in the accent, a headline whose
   SECOND line takes that accent, one paragraph, then a filled accent button
   beside a white one.

   The cards still stack and stick — that was already the mechanic here and it
   is theirs as well; the previous card's edge stays visible above the next,
   which is what makes the set read as one run rather than four sections.
   ═══════════════════════════════════════════════════════════ */

.p5demo-inner.p5clay{
  background:var(--tint);
  border:1px solid rgb(26 25 23 / .05);
  border-radius:3rem;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  align-items:center;
  gap:clamp(1.5rem,1rem + 3vw,4rem);
  padding:clamp(1.6rem,1rem + 3.4vw,4.5rem);
  overflow:hidden;
}
.p5clay-copy{min-inline-size:0}

/* THE STACKED PILL. Theirs is not one pill — it is three, the label in a
   solid accent with two paler copies fanned out behind it to the right, each
   a step lighter and a step wider. It reads as a card at the top of a deck.

   The ghosts are pseudo-elements at z-index:-1, which paints them behind this
   element's own background but in front of the card: `.p5clay-pill` is
   positioned with z-index:auto, so it creates no stacking context of its own
   and they resolve against the panel instead. Give this a z-index and they
   vanish behind the tint. */
.p5clay-pill{
  /* ISOLATE, unlike the eyebrow's pill. `.p5demo` is sticky with z-index:2, so
     it opens a stacking context; the ghosts at z-index:-1 then landed at the
     BOTTOM of that context, underneath `.p5demo-inner`'s opaque tint, and the
     pill rendered as a plain rounded rectangle while every other pill on the
     site had a deck behind it. Raising their opacity did nothing — they were
     not faint, they were covered.
     `isolation:isolate` gives the pill a context of its own, so -1 resolves
     against the pill's own background rather than the card's. */
  position:relative;isolation:isolate;
  display:inline-block;padding:.45rem 1.05rem;border-radius:var(--r-pill);
  background:var(--accent);color:#fff;
  font-size:var(--t-xs);font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;
}
.p5clay-pill::before,
.p5clay-pill::after{
  content:"";position:absolute;z-index:-1;
  inset-block:0;inset-inline-start:0;
  border-radius:var(--r-pill);
  background:var(--accent);
}
/* Nearer ghost: half out, half strength. */
/* HEAVIER THAN THE ONES ON WHITE, and the ground is why. The eyebrow's ghosts
   sit on the page's white at 42% and 18% and read clearly. These sit on a pale
   tint of their OWN accent — a blue ghost at 18% over #E9F0FB is within a few
   values of the card, so the pill looked like a plain rounded rectangle while
   every other pill on the site had a deck behind it. Same two steps, moved up
   the scale until they clear the ground they are on. */
.p5clay-pill::before{inset-inline-end:-1.15rem;opacity:.42}
.p5clay-pill::after{inset-inline-end:-2.2rem;opacity:.18}
/* THEIR NUMBERS, AND THE SELECTOR HAS TO WIN TO USE THEM. Measured on
   clay.com at 1440: 48px, weight 500, line-height exactly 48 — a 1.0 line —
   and -1.92px of tracking, which is -0.04em. Three things make it read as
   solid: the size, the leading set solid, and tracking tight enough that the
   words close up into a block.

   `.p5clay-h` alone lost to `.p5demo h3` at (0,1,1) further up this file and
   computed to 37.6px — 22% under theirs, which is exactly the "not powerful
   enough" that was visible. Scoped to the panel it outranks that rule.

   The paragraph is 16/22.4 on theirs, a 1.4 line; ours was on 1.5. At a 1:3
   ratio against a 48px headline the heading is meant to dominate, and half a
   step of leading is the difference between supporting copy and competing
   copy. */
.p5clay .p5clay-h{
  margin-block:clamp(1rem,.8rem + 1vw,1.6rem) 0;
  font-size:clamp(1.9rem,1.35rem + 1.85vw,3rem);
  line-height:1;letter-spacing:-.04em;font-weight:500;
  text-wrap:balance;color:#1D1D1E;
}
.p5clay .p5clay-lead{line-height:1.4}
/* The second line in the accent. A block rather than an inline span so the
   break is the sentence's, not the measure's — theirs always turns exactly
   where the colour starts. */
.p5clay-h .acc{display:block;color:var(--accent)}
.p5clay-lead{
  margin-block:clamp(.9rem,.7rem + .8vw,1.3rem) 0;
  max-inline-size:44ch;
  /* NOT --ink-2, and not a light alpha either. That token is tuned for body
     copy on the page's cream; on these pale tints it read as disabled text,
     and 78% was still grey enough to look faded. Theirs is body copy at full
     strength — the tint is pale enough that near-black is not heavy on it. */
  color:#1D1D1E;
}
.p5clay-cta{
  display:flex;flex-wrap:wrap;gap:.7rem;
  margin-block-start:clamp(1.3rem,1rem + 1.4vw,2.2rem);
}
.btn-accent{
  --bg:var(--accent);--fg:#fff;--bd:transparent;
  box-shadow:0 1px 2px rgb(26 25 23 / .12);
}
.btn-accent .arw{margin-inline-start:.45rem;display:inline-block;
  transition:translate .25s var(--e-out)}
.btn-accent:hover .arw{translate:.2rem 0}
/* The second action is white, as theirs is. `.btn-light` inherits the hero's
   inverted ink here and came out near-black on the tint, which read as two
   primaries competing. Restated inside the card so it cannot inherit that. */
.p5clay-cta .btn-light{
  --bg:#fff;--fg:#1a1917;--bd:rgb(26 25 23 / .10);
  box-shadow:0 1px 2px rgb(26 25 23 / .06);
}
.p5clay-cta .btn-light:hover{--bd:rgb(26 25 23 / .24)}

/* One square illustration, bled to the column. No frame and no shadow: it is
   already a rendered object standing on its own cream ground, and a card
   around it would be a picture of a picture. */
.p5clay-art{min-inline-size:0;display:grid;place-items:center}
.p5clay-art img{
  inline-size:100%;max-inline-size:34rem;block-size:auto;
  border-radius:2rem;
  mix-blend-mode:multiply;   /* the render's cream ground melts into the tint */
}

/* Stacked, the illustration leads and the words follow it — the same order
   the hero uses on a phone, and for the same reason. */
@media (max-width:900px){
  .p5demo-inner.p5clay{
    grid-template-columns:minmax(0,1fr);
    border-radius:1.75rem;
  }
  .p5clay-art{order:-1}
  .p5clay-art img{max-inline-size:22rem}
  .p5clay .p5clay-h{font-size:clamp(1.7rem,1.2rem + 2.2vw,2.4rem)}
}

/* ═══════════════════════════════════════════════════════════
   37. CLAY'S WIDE SECTION — header over one full-width picture
   ───────────────────────────────────────────────────────────
   Their other section shape: a pale card, a two-column header inside it —
   eyebrow, two-line headline with the second line in the accent, and a text
   LINK rather than a button on the left; the paragraph on the right — and one
   wide illustration filling the card underneath.

   The type is the same 48/500/1.0/-0.04em as section 36, for the same reason:
   solid leading and tight tracking are what make it read as a block.
   ═══════════════════════════════════════════════════════════ */

.claysec-card{
  background:var(--tint);border-radius:3rem;
  padding:clamp(1.6rem,1rem + 3.4vw,4.5rem);
}
.claysec-head{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(1.5rem,1rem + 3vw,4rem);align-items:start;
}
.claysec-eyebrow{
  display:block;color:var(--accent);
  font-size:var(--t-xs);font-weight:700;letter-spacing:.11em;text-transform:uppercase;
}
.claysec-h{
  margin-block:clamp(.9rem,.7rem + .9vw,1.4rem) 0;
  font-size:clamp(1.9rem,1.35rem + 1.85vw,3rem);
  line-height:1;letter-spacing:-.04em;font-weight:500;
  color:#1D1D1E;text-wrap:balance;
}
.claysec-h .acc{display:block;color:var(--accent)}
/* A link, not a button — theirs is underlined text with an arrow, which is
   what keeps the section from having two competing primary actions when it
   sits under a run of cards that each already have one. */
.claysec-link{
  display:inline-flex;align-items:center;gap:.4rem;
  margin-block-start:clamp(1rem,.8rem + 1vw,1.6rem);
  color:#1D1D1E;font-weight:600;
  text-decoration:underline;text-underline-offset:.35em;
  text-decoration-thickness:1px;text-decoration-color:rgb(26 25 23 / .3);
}
.claysec-link:hover{text-decoration-color:currentColor}
.claysec-link .arw{transition:translate .25s var(--e-out)}
.claysec-link:hover .arw{translate:.22rem 0}
.claysec-para{
  margin:0;color:#1D1D1E;line-height:1.4;max-inline-size:42ch;
}
.claysec-art{
  margin-block-start:clamp(1.6rem,1.1rem + 2.6vw,3.5rem);
  border-radius:1.75rem;overflow:hidden;
}
.claysec-art img{display:block;inline-size:100%;block-size:auto}

@media (max-width:900px){
  .claysec-card{border-radius:1.75rem}
  .claysec-head{grid-template-columns:minmax(0,1fr)}
  .claysec-art{border-radius:1.1rem}
}

/* ═══════════════════════════════════════════════════════════
   38. THE CLOSE — the page's own style, not the console's
   ───────────────────────────────────────────────────────────
   One pale card, centred, on the white ground. The heading takes the same
   settings as every other section heading on this page — 500 weight, a solid
   1.0 line, -0.04em — a step down in size because a closing line is a
   send-off, not a second headline.

   Everything the dark version carried is gone: the orbital ring, the four
   glowing family marks, the dusk band that darkened the page above it. The
   marks were a colour key for names already in the header and on the four
   cards; the dusk existed only to ease into a dark section that no longer
   exists.
   ═══════════════════════════════════════════════════════════ */

.p5close{background:transparent;color:var(--ink);padding-block:0}
.p5close-card{
  background:#F4F3F0;border-radius:3rem;
  padding:clamp(2.4rem,1.6rem + 4.4vw,6rem) clamp(1.6rem,1rem + 3.4vw,4.5rem);
  display:grid;justify-items:center;text-align:center;
}
/* SCOPED, because `.p5close h2` in phase5.css is (0,1,1) and this is (0,1,0):
   unscoped it lost and the heading rendered at 66.4px in the old dark scale
   with -.045em, which is a second page headline rather than a send-off. Same
   trap that capped the system-card heading at 37.6px earlier today. */
.p5close .p5close-h{
  margin:0;max-inline-size:20ch;text-wrap:balance;color:#1D1D1E;
  font-size:clamp(1.8rem,1.25rem + 1.7vw,2.75rem);
  line-height:1;letter-spacing:-.04em;font-weight:500;
}
.p5close-lead{
  margin-block:clamp(.9rem,.7rem + .9vw,1.4rem) 0;
  max-inline-size:52ch;color:#1D1D1E;line-height:1.4;
}
.p5close-cta{
  display:flex;flex-wrap:wrap;gap:.75rem;justify-content:center;
  margin-block-start:clamp(1.4rem,1.1rem + 1.4vw,2.2rem);
}
/* The secondary is white here, as it is on the system cards — .btn-light
   inherits an inverted ink from the hero and would otherwise come out
   near-black beside the red. */
.p5close-cta .btn-light{
  --bg:#fff;--fg:#1a1917;--bd:rgb(26 25 23 / .10);
  box-shadow:0 1px 2px rgb(26 25 23 / .06);
}
.p5close-cta .btn-light:hover{--bd:rgb(26 25 23 / .24)}

@media (max-width:900px){
  .p5close-card{border-radius:1.75rem}
}

/* The four objects closing the page. Multiply is what lets four separate
   renders share one card: each was shot on its own cream ground, and against
   the card's #F4F3F0 that ground would otherwise read as four pale squares in
   a row. Blended, only the objects survive. */
.p5close-marks{
  list-style:none;margin:clamp(1.8rem,1.2rem + 2.4vw,3.4rem) 0 0;padding:0;
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:clamp(.5rem,.2rem + 1.6vw,2.2rem);
}
.p5close-marks li{margin:0}
.p5close-marks img{
  inline-size:clamp(5.5rem,3.5rem + 6.5vw,10rem);block-size:auto;
  /* MULTIPLY WAS NOT ENOUGH. Each render carries its own cream ground, and
     against the card's #F4F3F0 that ground multiplies to something slightly
     darker than the card rather than disappearing into it — four pale squares
     in a row, which is what a strip of stickers looks like.
     A radial mask dissolves the square edge instead, so what is left on the
     card is the object and its shadow. It works whatever the two grounds
     happen to be, which multiply alone does not. */
  mix-blend-mode:multiply;
  -webkit-mask-image:radial-gradient(ellipse 62% 62% at 50% 52%,#000 58%,transparent 88%);
          mask-image:radial-gradient(ellipse 62% 62% at 50% 52%,#000 58%,transparent 88%);
}
@media (prefers-reduced-motion:no-preference){
  .p5close-marks img{transition:translate .4s var(--e-out)}
  .p5close-marks li:hover img{translate:0 -4px}
}

/* A product film in the wide section. The still underneath is not a fallback
   for a failed load — it is what a reader who asked for reduced motion gets
   instead, which is why it is a real element and not a poster attribute
   alone. */
.claysec-film{position:relative}
.claysec-film video{display:block;inline-size:100%;block-size:auto}
/* `.claysec-art img` sets display:block at (0,2,0) and beat this at (0,1,0),
   so the poster drew UNDERNEATH the playing video — the page appeared to
   carry the same film twice. Scoped to the film, it wins. */
.claysec-film .claysec-film-still{display:none}
@media (prefers-reduced-motion:reduce){
  .claysec-film video{display:none}
  .claysec-film .claysec-film-still{display:block;inline-size:100%;block-size:auto}
}

/* A product screenshot in a system card. The clay renders opposite it are
   objects on their own ground and want no frame; a screenshot is a rectangle
   of somebody's interface and wants one, or it reads as bleeding into the
   tint. No multiply either — that would tint a white UI. */
.p5clay-art.is-shot img{
  mix-blend-mode:normal;
  border-radius:1rem;
  border:1px solid rgb(26 25 23 / .07);
  box-shadow:0 1px 2px rgb(26 25 23 / .06),
             0 16px 40px -14px rgb(26 25 23 / .3);
  max-inline-size:none;
}

/* ── the use-case hero: copy left, picture right ──────────
   Their /use-cases/ pages open this way — the same card as the wide section
   but with the picture beside the words instead of under them. The header's
   two columns collapse to one so the paragraph sits under the headline where
   it belongs, and the art takes the right half of the card. */
.claysec.is-split .claysec-card{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  align-items:center;gap:clamp(1.5rem,1rem + 3vw,4rem);
}
.claysec.is-split .claysec-head{
  display:block;grid-template-columns:none;
}
.claysec.is-split .claysec-para{
  margin-block-start:clamp(.9rem,.7rem + .9vw,1.4rem);
  max-inline-size:46ch;
}
.claysec.is-split .claysec-art{margin-block-start:0}
@media (max-width:900px){
  .claysec.is-split .claysec-card{grid-template-columns:minmax(0,1fr)}
}

/* ═══════════════════════════════════════════════════════════
   39. CLAYPAGE — a composition per section, not one painted four ways
   ───────────────────────────────────────────────────────────
   Twice now this page has been "redesigned" by putting every section in the
   same shape and changing the colour: copy left, panel right, white chips,
   next colour. That is a template with a paint swap, and it read as one.

   The section's shape has to say what its content IS. Four kinds live on this
   page and each gets its own:

     a SET      six services, four outcomes — equal things, no order
                → a full-width colour band, heading centred over a row of cards
     a SYSTEM   ten modules on one data model — things that connect
                → no panel at all; the diagram at full size on white, which is
                  the one thing on the page that explains itself by being seen
     a SEQUENCE seven stages, first to last — order carries meaning
                → a dark track across the page, numbered, because here the
                  numbers are information and not decoration
     a LIST     the engagement's scope — inclusions, nothing more
                → plain ticked lines on white, no panel, no card

   The boldness is spent in ONE place: the dark sequence track. Everything
   around it is quiet on purpose. Chanel's rule — take one thing off before
   leaving the house.
   ═══════════════════════════════════════════════════════════ */

.claypage .blk > .sec > .wrap{
  max-inline-size:min(1280px, 100% - (var(--clay-gutter) * 2));
  margin-inline:auto;
}
.claypage .blk > .sec{padding-block:clamp(2.4rem,1.6rem + 3.2vw,5rem)}

/* Shared type. One scale for every section heading on the page. */
.claypage .sec-head h2,
.claypage .sec-head .h2{
  font-size:clamp(1.9rem,1.35rem + 1.85vw,3rem);
  line-height:1;letter-spacing:-.04em;font-weight:500;color:#1D1D1E;
  text-wrap:balance;margin-block:.7rem 0;
}
.claypage .sec-head .lead{
  color:#1D1D1E;line-height:1.4;
  margin-block-start:clamp(.7rem,.5rem + .7vw,1.1rem);
}

/* THE PILL TAKES THE SECTION'S COLOUR, not the brand red. `--eyebrow-accent`
   is read by the base rule in site.css; every section that has a colour of its
   own hands it over here, so the label belongs to its section rather than
   being one red mark repeated down the page. */
.claypage .blk--module_hive{--sec-accent:#E0A32E}
.claypage .blk--feature_grid{--sec-accent:#6FB77A}
.claypage .blk--feature_grid:last-of-type{--sec-accent:#DE1940}
.claypage .blk .sec-head .eyebrow{--eyebrow-accent:var(--sec-accent)}
/* the clay cards already carry an accent; the pill inside one follows it */
.p5clay .p5clay-pill,
.claysec .claysec-eyebrow{--eyebrow-accent:var(--accent)}

/* ── A SET · the colour band ─────────────────────────────── */
/* Heading centred over the row, because six equal things have no left-hand
   argument to make — they are a set, and a set reads as a block. */
.claypage .blk--feature_grid > .sec > .wrap{
  /* THE FILL IS MIXED FROM THE ACCENT, not held as a second variable. It was
     `--band`, set once for every feature_grid, so a page with three of them
     drew three identical pale-green panels while their pills were correctly
     green, violet and red — the label and the ground it sat on disagreed.
     Mixing means a section has one colour and everything in it follows. */
  background:color-mix(in srgb, var(--sec-accent) 13%, #fff);
  border-radius:3rem;
  padding:clamp(1.8rem,1.2rem + 3.4vw,4rem);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E");
  background-size:140px 140px;
}
/* CENTRED, BUT NOT NARROW. The head was capped at 34ch, which at 48px broke
   "What the module covers" and "What the desk is wired to" into two lines in a
   thin column with empty space either side of it. Centring is the band's
   design; the measure was an accident of reusing one rule for the heading and
   the paragraph. The heading takes the full width and wraps where the sentence
   wants to; the paragraph keeps a readable 52ch. */
.claypage .blk--feature_grid .sec-head{text-align:center;max-inline-size:none;margin-inline:auto}
.claypage .blk--feature_grid .sec-head h2{max-inline-size:none}
.claypage .blk--feature_grid .sec-head .lead{margin-inline:auto;max-inline-size:52ch}
.claypage .blk--feature_grid .grid{
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(.7rem,.5rem + .7vw,1.1rem);
  margin-block-start:clamp(1.4rem,1rem + 1.6vw,2.4rem);
}
.claypage .blk--feature_grid .card{
  background:#fff;border:0;border-radius:1.15rem;
  padding:clamp(1rem,.8rem + .7vw,1.4rem);
  box-shadow:0 1px 2px rgb(26 25 23 / .05), 0 10px 26px -12px rgb(26 25 23 / .2);
}
.claypage .blk--feature_grid .card h3{font-size:1.05rem;font-weight:600;
  letter-spacing:-.02em;margin:0 0 .35rem;color:#1D1D1E}
.claypage .blk--feature_grid .card p{font-size:.92rem;line-height:1.45;margin:0;color:var(--ink-2)}

/* ── CLAIMS · quiet, and the page's widest measure ───────── */
/* These four are claims about what changes for the reader, not a catalogue of
   what the firm sells. Given the services' colour band they read as more of
   the same, and the page ended on two look-alike sections.
   They were briefly set on near-black. That is out: no black anywhere on this
   page. What separates them now is restraint rather than contrast — no band,
   no card, no fill. Four statements set large on the page's own white, each
   under a rule in that section's accent. It is the only section here with
   nothing behind it, which after five filled ones is its own kind of emphasis.
   The icons stay: they were already in the markup and they carry the only
   colour the section needs. */
.claypage .blk--feature_grid:last-of-type > .sec > .wrap{
  background:none;padding-inline:0;
}
/* FULL WIDTH, AND ON ONE LINE. This head was inheriting the colour band's
   `max-inline-size:34ch; margin-inline:auto` from the rule above — a narrow
   centred column, which set "Four operational outcomes" in three lines
   floating in the middle of an otherwise empty row. Nothing constrains it
   here: the four claims below start at the left edge, so the heading starts
   there too and runs as far as it needs. */
.claypage .blk--feature_grid:last-of-type .sec-head{
  text-align:start;max-inline-size:none;margin-inline:0;
}
.claypage .blk--feature_grid:last-of-type .sec-head h2{max-inline-size:none}
.claypage .blk--feature_grid:last-of-type .sec-head .lead{
  max-inline-size:56ch;margin-inline:0;
}
.claypage .blk--feature_grid:last-of-type .sec-head h2{color:#1D1D1E}
.claypage .blk--feature_grid:last-of-type .sec-head .lead{color:var(--ink-2)}
.claypage .blk--feature_grid:last-of-type .grid{
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:0 clamp(1rem,.7rem + 1.4vw,2.2rem);
  margin-block-start:clamp(1.8rem,1.2rem + 2.4vw,3.2rem);
}
.claypage .blk--feature_grid:last-of-type .card{
  background:none;box-shadow:none;border:0;border-radius:0;
  padding:1.1rem 0 0;
  border-block-start:2px solid var(--sec-accent);
}
.claypage .blk--feature_grid:last-of-type .card h3{
  color:#1D1D1E;
  font-size:clamp(1.2rem,.95rem + .85vw,1.75rem);
  font-weight:500;letter-spacing:-.03em;line-height:1.1;margin:0 0 .5rem;
}
.claypage .blk--feature_grid:last-of-type .card p{
  color:var(--ink-2);font-size:.94rem;line-height:1.5;margin:0;
}

/* ── A SYSTEM · let the diagram be the thing ─────────────── */
/* No panel. Ten modules sharing one data model is the only claim on this page
   that a picture makes better than a sentence, so the picture gets the width
   and the words get out of its way. */
.claypage .blk--module_hive > .sec > .wrap{background:none;padding-inline:0}
.claypage .blk--module_hive .sec-head{text-align:center;max-inline-size:30ch;margin-inline:auto}
.claypage .blk--module_hive .hive{
  display:grid;grid-template-columns:minmax(0,1fr);justify-items:center;
  gap:clamp(1rem,.8rem + 1vw,1.6rem);
  margin-block-start:clamp(1.4rem,1rem + 1.6vw,2.4rem);
}
.claypage .blk--module_hive .hive-svg{inline-size:min(100%,720px);block-size:auto}
.claypage .blk--module_hive .hive-body{
  max-inline-size:60ch;text-align:center;color:var(--ink-2);
  font-size:1rem;line-height:1.5;
}

/* ── A SEQUENCE · the dark track ─────────────────────────── */
/* EVERY RULE HERE EXCLUDES `.claysec`. The page hero is also a `process`
   block — it is B("process", style="clay", layout="split") — so once the
   seven-stage section was removed these rules fell straight through onto the
   hero and painted it near-black with its own dark type on top. Unreadable,
   and invisible in code review: the selector was correct the day it was
   written and only became wrong when its section went away. */
/* The one loud thing on the page. Seven stages in order, on near-black, with
   the numbers doing real work: this is the only content here where order
   carries information, so it is the only place numbering is earned. */
.claypage .blk--process > .sec:not(.claysec) > .wrap{
  background:#1A1817;border-radius:3rem;color:var(--oat-100);
  padding:clamp(1.8rem,1.2rem + 3.4vw,4rem);
}
.claypage .blk--process > .sec:not(.claysec) .sec-head{text-align:center;max-inline-size:32ch;margin-inline:auto}
.claypage .blk--process > .sec:not(.claysec) .sec-head h2,
.claypage .blk--process > .sec:not(.claysec) .sec-head .lead{color:var(--oat-100)}
.claypage .blk--process > .sec:not(.claysec) .sec-head .eyebrow{color:var(--sig,#E0A32E)}
.claypage .blk--process > .sec:not(.claysec) .pstrip{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  gap:0;margin-block-start:clamp(1.6rem,1.2rem + 1.8vw,2.6rem);
  list-style:none;padding:0;
  /* The strip carries its own cream panel and a fixed height for the light
     design. On the dark track that panel put light type on cream and clipped
     every caption. The track IS the background here. */
  background:none;border:0;box-shadow:none;
  min-block-size:0;max-block-size:none;overflow:visible;
  -webkit-mask-image:none;mask-image:none;
}
.claypage .blk--process > .sec:not(.claysec) .pstep{
  background:none;border:0;box-shadow:none;padding:0 .6rem;
  display:grid;gap:.5rem;align-content:start;position:relative;
}
/* THE TRACK, AND ITS DRAWING.
   One hairline segment behind every node. Each segment scales from its left
   edge, so with a stagger the whole run reads as a single line drawn across
   the page rather than seven pieces appearing at once. The first and last are
   half-length: a sequence has ends, and a line running off both sides would
   say it does not.

   `data-seq` is set by phase5.js. Until it is, every rule below is inert and
   the finished track is what renders — no script, no empty box. */
.claypage .blk--process > .sec:not(.claysec) .pstep::before{
  content:"";position:absolute;inset-block-start:.72rem;inset-inline:0;
  block-size:1px;background:rgb(244 241 235 / .22);
  transform-origin:left center;
}
.claypage .blk--process > .sec:not(.claysec) .pstep:first-child::before{inset-inline-start:50%}
.claypage .blk--process > .sec:not(.claysec) .pstep:last-child::before{inset-inline-end:50%}

@media (prefers-reduced-motion:no-preference){
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq] .pstep::before{
    transform:scaleX(0);
    transition:transform .5s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i) * 110ms);
  }
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq] .pnum{
    scale:.6;opacity:0;
    transition:scale .42s cubic-bezier(.34,1.56,.64,1), opacity .32s ease-out;
    transition-delay:calc(var(--i) * 110ms + 180ms);
  }
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq] .ptitle,
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq] .ptext{
    opacity:0;translate:0 6px;
    transition:opacity .4s ease-out, translate .4s cubic-bezier(.22,1,.36,1);
    transition-delay:calc(var(--i) * 110ms + 260ms);
  }
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq].is-on .pstep::before{transform:scaleX(1)}
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq].is-on .pnum{scale:1;opacity:1}
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq].is-on .ptitle,
  .claypage .blk--process > .sec:not(.claysec) .pstrip[data-seq].is-on .ptext{opacity:1;translate:0 0}
}

/* The node a reader is pointing at brightens, and its own segment with it —
   a small confirmation that the run is one path and not seven labels. */
@media (hover:hover){
  .claypage .blk--process > .sec:not(.claysec) .pstep{transition:opacity .25s var(--e-out)}
  .claypage .blk--process > .sec:not(.claysec) .pstrip:hover .pstep{opacity:.55}
  .claypage .blk--process > .sec:not(.claysec) .pstrip .pstep:hover{opacity:1}
  .claypage .blk--process > .sec:not(.claysec) .pstep:hover .pnum{background:var(--brand);color:#fff}
}
.claypage .blk--process > .sec:not(.claysec) .pnum{
  position:relative;justify-self:start;margin-inline-start:calc(50% - .72rem);
  inline-size:1.45rem;block-size:1.45rem;border-radius:50%;
  display:grid;place-items:center;
  background:var(--oat-100);color:#1A1817;
  font-size:.72rem;font-weight:700;font-variant-numeric:tabular-nums;
}
.claypage .blk--process > .sec:not(.claysec) .ptitle{
  color:var(--oat-100);font-size:.95rem;font-weight:600;letter-spacing:-.02em;
  text-align:center;
}
.claypage .blk--process > .sec:not(.claysec) .ptext{
  color:rgb(244 241 235 / .62);font-size:.82rem;line-height:1.4;text-align:center;
}

/* ── A LIST · say it and stop ────────────────────────────── */
.claypage .blk--checklist > .sec > .wrap{background:none;padding-inline:0}
.claypage .blk--checklist .sec-head{max-inline-size:28ch}
.claypage .blk--checklist .checklist{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:.5rem 2.4rem;list-style:none;padding:0;
  margin-block-start:clamp(1.2rem,.9rem + 1.2vw,1.9rem);
}
.claypage .blk--checklist .checklist li{
  background:none;border:0;box-shadow:none;padding:.55rem 0;
  border-block-end:1px solid rgb(26 25 23 / .1);
  font-size:.98rem;color:#1D1D1E;
}

@media (max-width:900px){
  .claypage .blk--feature_grid .grid{grid-template-columns:minmax(0,1fr)}
  .claypage .blk--process > .sec:not(.claysec) .pstrip{grid-auto-flow:row;gap:.9rem}
  .claypage .blk--process > .sec:not(.claysec) .pstep::before{content:none}
  .claypage .blk--process > .sec:not(.claysec) .pnum{margin-inline-start:0}
  .claypage .blk--process > .sec:not(.claysec) .ptitle,
  .claypage .blk--process > .sec:not(.claysec) .ptext{text-align:start}
  .claypage .blk--checklist .checklist{grid-template-columns:minmax(0,1fr)}
  .claypage .blk--feature_grid > .sec > .wrap,
  .claypage .blk--process > .sec:not(.claysec) > .wrap{border-radius:1.75rem}
}

@media (max-width:900px){
  .claypage .blk--feature_grid:last-of-type .grid{grid-template-columns:minmax(0,1fr)}
}

/* ── the use-case hero, second pass ──────────────────────
   It was copy in one half and a film in the other, both inside a pale card:
   correct, and inert. The film is the most characteristic thing on this page —
   the product actually moving — so it stops being a column and becomes the
   ground the section stands on.

   The card loses its fill and the film takes the full width beneath the words,
   bleeding wider than the text column. The copy sits above it at the page's
   own measure rather than squeezed into 45% of it, so the headline gets the
   room its 48px asks for. */
.claysec.is-split .claysec-card{
  display:block;background:none;padding-inline:0;
  padding-block:clamp(1rem,.6rem + 1.6vw,2.2rem) 0;
}
.claysec.is-split .claysec-head{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  gap:clamp(1.5rem,1rem + 3vw,4rem);align-items:end;
}
.claysec.is-split .claysec-lead-col{max-inline-size:none}
.claysec.is-split .claysec-h{max-inline-size:none}
.claysec.is-split .claysec-para{
  max-inline-size:46ch;margin-block-start:0;align-self:end;
}
.claysec.is-split .claysec-link{margin-block-start:clamp(1rem,.8rem + 1vw,1.5rem)}
/* the film, wide and framed like a screen rather than a column */
.claysec.is-split .claysec-art{
  margin-block-start:clamp(1.6rem,1.1rem + 2.4vw,3.2rem);
  border-radius:1.75rem;overflow:hidden;
  border:1px solid rgb(26 25 23 / .08);
  box-shadow:0 2px 4px rgb(26 25 23 / .05),
             0 30px 70px -30px rgb(26 25 23 / .45);
}
@media (max-width:900px){
  .claysec.is-split .claysec-head{grid-template-columns:minmax(0,1fr)}
  .claysec.is-split .claysec-lead-col{max-inline-size:none}
  .claysec.is-split .claysec-art{border-radius:1.1rem}
}

/* ── SEQUENCE STRIPS, IN DAYLIGHT ──────────────────────────────────────────
   The strip above was written for the ERP page's stages section and put the
   run on near-black, which was right when it was the one loud thing on an
   otherwise pale page. That section is gone, and the instruction since has
   been that nothing on these pages is black — so the accounting page, the only
   claypage that still carries strips, gets the same pale band every other
   section here uses, tinted from its own --sec-accent.

   Same selectors as the dark rules, appended after them: equal specificity,
   later wins. The track, the numbers and the captions all move to ink so the
   contrast survives the flip. */
.claypage .blk--process > .sec:not(.claysec) > .wrap{
  background:color-mix(in srgb, var(--sec-accent, var(--sig)) 13%, #fff);
  color:var(--ink);
}
.claypage .blk--process > .sec:not(.claysec) .sec-head{max-inline-size:none}
.claypage .blk--process > .sec:not(.claysec) .sec-head h2,
.claypage .blk--process > .sec:not(.claysec) .sec-head .lead{color:var(--ink)}
.claypage .blk--process > .sec:not(.claysec) .sec-head .lead{
  max-inline-size:62ch;margin-inline:auto;
}
/* The line the numbers sit on. Accent rather than cream, at an alpha that
   reads as a rule and not as a border. */
.claypage .blk--process > .sec:not(.claysec) .pstep::before{
  background:color-mix(in srgb, var(--sec-accent, var(--sig)) 42%, transparent);
}
.claypage .blk--process > .sec:not(.claysec) .pnum{
  background:var(--sec-accent, var(--sig));color:#fff;
}
.claypage .blk--process > .sec:not(.claysec) .ptitle{color:var(--ink)}
.claypage .blk--process > .sec:not(.claysec) .ptext{color:var(--ink-3)}
@media (hover:hover){
  .claypage .blk--process > .sec:not(.claysec) .pstep:hover .pnum{
    background:var(--ink);color:#fff;
  }
}

/* Checklist section heads were capped at 28ch, which is fine for a two-word
   heading and wrong for "What the warehouse connects to" — it came out three
   ragged lines in a narrow column, the same fault already fixed on the band
   heads. The warehouse page has eight of these, so the cap goes. */
.claypage .blk--checklist .sec-head{max-inline-size:none}

/* ══ THE LONG DOCUMENT, DESIGNED ══════════════════════════════════════════
   The warehouse page is 85 blocks and 52 of them were `rich`, `workflow_table`,
   `checklist` and `scope_note` — none of which had any claypage styling at all.
   Bands and strips had been given a design; the prose, the twelve tables, the
   ten chip rows and the fourteen qualifications had not, so the page read as
   two designs stacked on each other.

   Everything below is driven by --sec-accent, which is now set per source
   section, so seventeen sections read as seventeen chapters rather than one
   undifferentiated scroll. No block changes what it says. */

/* ── Section openers: a chapter plate ─────────────────────────────────────
   A rule that starts solid in the accent and fades, the numbered eyebrow, and
   the source's section number set large and pale behind the heading. The
   numeral is `content: attr(data-num)` — decoration drawn from data that is
   already in the eyebrow, never a second copy in the markup. */
.claypage .blk--rich > .sec > .wrap{position:relative}
.claypage .blk--rich .sec-head{position:relative;padding-block-start:2.4rem;isolation:isolate}
.claypage .blk--rich .sec-head::after{
  content:"";position:absolute;inset-block-start:0;inset-inline:0;block-size:2px;
  background:linear-gradient(90deg,
    var(--sec-accent, var(--brand)) 0 5rem,
    color-mix(in srgb, var(--sec-accent, var(--brand)) 20%, transparent) 5rem);
}
.claypage .blk--rich .sec-head[data-num]::before{
  content:attr(data-num);
  position:absolute;inset-block-start:1.5rem;inset-inline-end:-.4rem;z-index:-1;
  font-size:clamp(3.6rem, 2rem + 6.5vw, 7rem);font-weight:800;line-height:.78;
  letter-spacing:-.06em;font-variant-numeric:tabular-nums;
  color:color-mix(in srgb, var(--sec-accent, var(--brand)) 15%, #fff);
  pointer-events:none;
}
.claypage .blk--rich .sec-head .h2{
  font-size:clamp(1.85rem, 1.25rem + 2.1vw, 2.9rem);
  letter-spacing:-.028em;line-height:1.08;max-inline-size:none;
}
.claypage .blk--rich .rt{max-inline-size:68ch}
@media (max-width:720px){
  .claypage .blk--rich .sec-head[data-num]::before{inset-block-start:1.1rem;opacity:.75}
}

/* ── The twelve tables ────────────────────────────────────────────────────
   These carry the densest material on the page — picking methods, control
   behaviours, what each module contributes. A black header bar on white made
   twelve of them look like raw output. They are the section's own colour now:
   tinted head, a wash on alternate rows, and the row's subject in the accent
   so the first column reads as the label it is. */
.claypage .blk--workflow_table .wtable-wrap{
  border-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 24%, transparent);
  border-radius:1.4rem;background:#fff;
  box-shadow:0 1px 2px rgb(26 25 23 / .04), 0 20px 44px -34px rgb(26 25 23 / .38);
}
.claypage .blk--workflow_table .wtable caption{
  padding:1rem 1.3rem .2rem;color:var(--ink-3);
}
.claypage .blk--workflow_table .wtable thead th{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 13%, #fff);
  color:var(--ink);padding:.95rem 1.3rem;
  font-size:.72rem;letter-spacing:.09em;text-transform:uppercase;font-weight:700;
  border-block-end:1px solid color-mix(in srgb, var(--sec-accent, var(--brand)) 28%, transparent);
}
.claypage .blk--workflow_table .wtable tbody th,
.claypage .blk--workflow_table .wtable tbody td{
  padding:.92rem 1.3rem;border-top-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 14%, transparent);
}
.claypage .blk--workflow_table .wtable tbody tr:nth-child(even) th,
.claypage .blk--workflow_table .wtable tbody tr:nth-child(even) td{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 5%, #fff);
}
.claypage .blk--workflow_table .wtable tbody th{
  color:color-mix(in srgb, var(--sec-accent, var(--brand)) 78%, #1A1817);
  font-weight:680;
}
@media (max-width:640px){
  .claypage .blk--workflow_table .wtable tbody tr{
    border-top-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 26%, transparent);
  }
}

/* ── The ten capability sets ──────────────────────────────────────────────
   Chips were small, grey and identical everywhere. Given room and the
   section's colour they read as a set of named capabilities. */
.claypage .blk--checklist .chips{gap:.62rem}
.claypage .blk--checklist .chip{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 7%, #fff);
  border-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 26%, transparent);
  color:var(--ink);padding:.62rem 1.05rem;font-size:.93rem;font-weight:500;
}
.claypage .blk--checklist .chip .ico{color:var(--sec-accent, var(--brand))}
.claypage .blk--checklist .chip:hover{
  border-color:var(--sec-accent, var(--brand));
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 12%, #fff);
}

/* ── The fourteen qualifications ──────────────────────────────────────────
   These are the honest part of the page and the source insists they sit
   beside the claim rather than collect at the foot. Quiet, but built: the
   section's colour on the rule and the label, a faint wash, and a shape that
   says aside rather than afterthought. */
.claypage .blk--scope_note .snote{
  border-inline-start:3px solid var(--sec-accent, var(--brand));
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 6%, #fff);
  border-radius:0 1.1rem 1.1rem 0;padding:1.05rem 1.35rem;
}
.claypage .blk--scope_note .snote-label{color:var(--sec-accent, var(--brand))}

/* Twelve tables on a 46,000px page: a row that lights under the pointer is
   the difference between reading across and losing the line. Pointer only —
   it would fire on tap and stick on touch. */
@media (hover:hover){
  .claypage .blk--workflow_table .wtable tbody tr:hover th,
  .claypage .blk--workflow_table .wtable tbody tr:hover td{
    background:color-mix(in srgb, var(--sec-accent, var(--brand)) 11%, #fff);
  }
}
/* Seventeen anchors, and a sticky header to clear when one is jumped to. */
.claypage .blk--rich > .sec[id],
.claypage .blk--checklist > .sec[id],
.claypage .blk--workflow_table > .sec[id]{scroll-margin-block-start:6rem}

@media (max-width:640px){
  /* Hygiene, not a bug fix. The mobile rules hide the table head with the old
     clip pattern and re-attach each column name to its cell, but the hidden
     cells still laid out at full text width inside their clipped parent. That
     turned out to cause nothing — the 7px the warehouse page appeared to
     overflow by was the vertical scrollbar on a 62,000px document, which
     widens innerWidth and so the inset:0 nav drawer with it; scrollX never
     moves. Constrained anyway, because a visually hidden row should not be
     laying out a table's worth of boxes. */
  .wtable thead th{max-inline-size:1px;overflow:hidden}
}

/* ══ THE ALTERNATING FIGURE ═══════════════════════════════════════════════
   Clay's own device, and the one this page was missing. Copy in one column,
   the picture in the other sitting on a saturated panel of the section's
   colour, sides swapped on every other figure so a long page never settles
   into a single rhythm. The card is white; the colour is inside it, which is
   what makes the screenshot read as a specimen rather than a decoration. */
.claysec.is-beside > .wrap > .claysec-card{
  background:#fff;
  border:1px solid rgb(26 25 23 / .07);
  padding:clamp(1.4rem,1rem + 1.6vw,2.2rem);
}
.claysec.is-beside .claysec-head{
  display:grid;grid-template-columns:1fr;gap:0;
  align-content:center;padding:clamp(.6rem,.4rem + 1.4vw,2rem);
}
.claysec.is-beside .claysec-para{margin-block-start:.9rem;max-inline-size:46ch}
@media (min-width:900px){
  .claysec.is-beside > .wrap > .claysec-card{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.06fr);
    gap:clamp(1.2rem,.8rem + 1.6vw,2.4rem);align-items:stretch;
  }
  /* every other figure swaps sides */
  .claysec.is-beside.is-flip > .wrap > .claysec-card > .claysec-head{order:2}
  .claysec.is-beside.is-flip > .wrap > .claysec-card > .claysec-art{order:1}
}
/* THE SATURATED PANEL. The section's accent at full strength, with the
   screenshot floated on it and lifted — Clay puts the specimen on colour, not
   on the page ground, and that single move is most of the difference. */
.claysec.is-beside .claysec-art{
  margin-block-start:0;border-radius:1.5rem;overflow:hidden;
  background:linear-gradient(155deg,
    color-mix(in srgb, var(--accent) 88%, #fff) 0%,
    var(--accent) 55%,
    color-mix(in srgb, var(--accent) 82%, #1A1817) 100%);
  display:grid;place-items:center;
  padding:clamp(1.1rem,.7rem + 2vw,2.6rem);
  min-block-size:clamp(15rem,12rem + 14vw,23rem);
}
.claysec.is-beside .claysec-art img{
  inline-size:100%;block-size:auto;border-radius:.7rem;
  box-shadow:0 2px 6px rgb(26 25 23 / .18), 0 26px 54px -22px rgb(26 25 23 / .55);
}
.claysec.is-beside .claysec-h{
  font-size:clamp(1.75rem,1.2rem + 2vw,2.7rem);line-height:1.06;
}
.claysec.is-beside .claysec-eyebrow{margin-block-end:.7rem}
@media (max-width:899px){
  .claysec.is-beside .claysec-art{margin-block-start:1.2rem;min-block-size:0}
}

/* Reading order inside the figure. The link lives in the lead column with the
   eyebrow and heading, so it rendered between the heading and the paragraph —
   a call to action before the sentence that earns it. `display:contents` on
   that column promotes all three to flex items so the four parts can be put in
   the order a reader wants them. */
.claysec.is-beside .claysec-head{
  display:flex;flex-direction:column;align-items:flex-start;
}
.claysec.is-beside .claysec-lead-col{display:contents}
.claysec.is-beside .claysec-eyebrow{order:1}
.claysec.is-beside .claysec-h{order:2}
.claysec.is-beside .claysec-para{order:3;margin-block-start:.9rem}
.claysec.is-beside .claysec-link{order:4;margin-block-start:1.35rem}
/* The column is roughly half the card, so the hero's display size put every
   accent line onto a third row. */
.claysec.is-beside .claysec-h{
  font-size:clamp(1.6rem, 1.15rem + 1.35vw, 2.2rem);line-height:1.1;
}

/* ══ THE TABLES GET A GROUND ══════════════════════════════════════════════
   Clay's foundation is a white card on a coloured ground; ours had a white
   table on a white page, so twelve of the densest sections on the site had
   nothing holding them. The band is the section's colour, the table is the
   card, and the page now alternates — prose on white, then a panel — instead
   of running as one sheet for 43,000px. */
.claypage .blk--workflow_table > .sec > .wrap{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 11%, #fff);
  border-radius:3rem;
  padding:clamp(1.6rem,1.1rem + 2.6vw,3.4rem);
}
.claypage .blk--workflow_table .sec-head{
  text-align:center;margin-inline:auto;max-inline-size:none;
}
.claypage .blk--workflow_table .sec-head .lead{
  max-inline-size:62ch;margin-inline:auto;
}
/* On the band the table's own tint would double up, so it goes white. */
.claypage .blk--workflow_table .wtable-wrap{
  border-color:rgb(26 25 23 / .08);
  box-shadow:0 1px 2px rgb(26 25 23 / .05), 0 22px 48px -34px rgb(26 25 23 / .42);
}
.claypage .blk--workflow_table .wtable thead th{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 16%, #fff);
}
@media (max-width:720px){
  .claypage .blk--workflow_table > .sec > .wrap{border-radius:1.6rem}
}

/* ══ THE PROGRESS METER ═══════════════════════════════════════════════════
   The chapter rail that used to live here is gone (2026-09-06). It floated
   seventeen labels over the content it was meant to help with, and a reader
   cannot tell furniture from page. The meter stays: one hairline, no
   horizontal footprint, covers nothing. */
.docmeter{
  position:fixed;inset-block-start:0;inset-inline:0;block-size:2px;z-index:120;
  background:rgb(26 25 23 / .06);pointer-events:none;
}
.docmeter i{
  display:block;block-size:100%;transform-origin:0 50%;transform:scaleX(0);
  background:linear-gradient(90deg, var(--sig, var(--brand)), #DE1940);
}

/* The numeral's drift, written by script into --num-shift. Undeclared it is
   0, so the numeral is exactly where the static design put it. */
.claypage .blk--rich .sec-head[data-num]::before{
  translate:0 var(--num-shift, 0px);
}


/* ── The section index, as furniture ──────────────────────────────────────
   Was a chapter: a pill, a heading that repeated the hero, a paragraph and a
   seventeen-item list. It is navigation, so it is built like navigation —
   one line closed, the chapters as chips open. The rail supersedes it on a
   desktop; on a phone, where the rail does not run, this is the only way to
   move through seventeen chapters. */
.claypage .blk--rich .rt:has(> .pageindex){max-inline-size:none}
.claypage .blk--rich .sec-head:empty{display:none}
.pageindex{
  border:1px solid rgb(26 25 23 / .1);border-radius:1.2rem;
  background:#fff;padding:.2rem .35rem;
}
.pageindex > summary{
  display:flex;align-items:center;gap:.55rem;cursor:pointer;list-style:none;
  padding:.72rem .95rem;border-radius:.95rem;
  font-size:.9rem;font-weight:560;color:var(--ink-2);
}
.pageindex > summary::-webkit-details-marker{display:none}
.pageindex > summary::after{
  content:"";inline-size:.5rem;block-size:.5rem;margin-inline-start:auto;
  border-inline-end:1.6px solid currentColor;border-block-end:1.6px solid currentColor;
  rotate:45deg;translate:0 -2px;transition:rotate .25s var(--ease);
}
.pageindex[open] > summary::after{rotate:-135deg;translate:0 1px}
.pageindex > summary:hover{background:rgb(26 25 23 / .04);color:var(--ink)}
.pageindex > summary span{
  font-size:.7rem;font-weight:700;letter-spacing:.04em;
  padding:.1rem .42rem;border-radius:999px;
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 15%, #fff);
  color:color-mix(in srgb, var(--sec-accent, var(--brand)) 75%, #1A1817);
}
.pageindex .anchor-index{
  list-style:none;margin:0;padding:.15rem .95rem 1rem;
  display:flex;flex-wrap:wrap;gap:.45rem;
}
.pageindex .anchor-index a{
  display:inline-block;padding:.4rem .8rem;border-radius:999px;
  border:1px solid rgb(26 25 23 / .12);
  font-size:.82rem;color:var(--ink-2);text-decoration:none;
  transition:border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease);
}
.pageindex .anchor-index a:hover{
  border-color:var(--sec-accent, var(--brand));color:var(--ink);
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 8%, #fff);
}

/* `.rt ul li{list-style:disc}` is right for prose and wrong here — the index
   is a row of chips, and every one was trailing a bullet. */
.pageindex .anchor-index li{list-style:none}
.pageindex .anchor-index{padding-left:.95rem}

/* ══ THE FOLDED PROFILE ═══════════════════════════════════════════════════
   Seventeen chapters, closed. The page above is what a visitor reads; this is
   what a buyer opens when they want the detail. Each chapter carries its own
   section colour, so an open one reads as the chapter it is rather than as a
   drawer of loose blocks. */
.wdoc > .wrap > .sec-head{text-align:center;max-inline-size:none}
.wdoc > .wrap > .sec-head .lead{max-inline-size:64ch;margin-inline:auto}
.wdoc-list{
  display:grid;gap:.55rem;
  margin-block-start:clamp(1.6rem,1.2rem + 1.8vw,2.6rem);
}
.wchapter{
  border:1px solid rgb(26 25 23 / .1);border-radius:1.35rem;background:#fff;
  overflow:clip;
  transition:border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.wchapter[open]{
  border-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 34%, transparent);
  box-shadow:0 1px 2px rgb(26 25 23 / .04), 0 24px 52px -34px rgb(26 25 23 / .4);
}
.wchapter > summary{
  display:flex;align-items:center;gap:.9rem;cursor:pointer;list-style:none;
  padding:1.05rem 1.4rem;
}
.wchapter > summary::-webkit-details-marker{display:none}
.wchapter > summary::after{
  content:"";inline-size:.55rem;block-size:.55rem;margin-inline-start:auto;flex:none;
  border-inline-end:1.7px solid var(--ink-3);border-block-end:1.7px solid var(--ink-3);
  rotate:45deg;translate:0 -2px;transition:rotate .25s var(--ease);
}
.wchapter[open] > summary::after{rotate:-135deg;translate:0 2px}
.wchapter > summary:hover{background:color-mix(in srgb, var(--sec-accent, var(--brand)) 6%, #fff)}
.wchapter-n{
  font-family:var(--mono, monospace);font-size:.74rem;font-weight:700;
  font-variant-numeric:tabular-nums;flex:none;
  inline-size:2rem;block-size:2rem;border-radius:.6rem;
  display:grid;place-items:center;
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 15%, #fff);
  color:color-mix(in srgb, var(--sec-accent, var(--brand)) 78%, #1A1817);
}
.wchapter-t{font-size:1.02rem;font-weight:560;letter-spacing:-.015em;color:var(--ink)}
.wchapter-body{
  padding:.2rem clamp(.4rem,.2rem + .8vw,1rem) 1rem;
  border-block-start:1px solid color-mix(in srgb, var(--sec-accent, var(--brand)) 16%, transparent);
}
/* Inside a chapter the blocks are already in a card, so they drop their own
   full-page rhythm: no 3rem bands, no chapter plates, tighter vertical space. */
.wchapter-body .sec{padding-block:clamp(1.1rem,.8rem + 1.2vw,1.8rem)}
.wchapter-body .wrap{padding-inline:clamp(.6rem,.3rem + 1.2vw,1.4rem)}
.wchapter-body .blk--rich .sec-head{padding-block-start:0}
.wchapter-body .blk--rich .sec-head::after,
.wchapter-body .blk--rich .sec-head[data-num]::before{display:none}
.wchapter-body .blk--rich .sec-head .h2{font-size:clamp(1.25rem,1.05rem + .7vw,1.6rem)}
.wchapter-body .blk--workflow_table > .sec > .wrap,
.wchapter-body .blk--feature_grid > .sec > .wrap,
.wchapter-body .blk--process > .sec:not(.claysec) > .wrap{
  background:none;border-radius:0;padding:0;
}
.wchapter-body .blk--feature_grid .sec-head,
.wchapter-body .blk--workflow_table .sec-head{text-align:start}

/* The jump index sits with the chapter list it navigates, and inside this
   section it needs none of a block's own spacing. */
.wdoc-jump .sec{padding-block:0}
.wdoc-jump .wrap{padding-inline:0;max-inline-size:none}
.wdoc-jump{max-inline-size:44rem;margin:0 auto clamp(.9rem,.6rem + 1vw,1.5rem)}

/* ══ THE COMMISSIONED RENDERS ═════════════════════════════════════════════
   Ten clay objects, one per section, in the same language as img/field/ — one
   accent each, matched to the section they sit in. They live inside the
   section head so no block's markup had to change; here they are lifted out
   to the side of it, which turns a heading into a plate.

   They are decorative and marked aria-hidden: every one restates a heading
   already on the page, and describing "a green box inside four white ones" to
   a screen reader would be noise, not information. */
.claypage .sec-head:has(> .sec-illus){
  position:relative;
  padding-inline-end:clamp(9rem, 5rem + 12vw, 16rem);
  min-block-size:clamp(8rem, 6rem + 7vw, 12rem);
  display:flex;flex-direction:column;justify-content:center;
}
.claypage .sec-illus{
  position:absolute;inset-inline-end:0;inset-block-start:50%;
  translate:0 -50%;
  inline-size:clamp(8rem, 4.5rem + 11vw, 15rem);block-size:auto;
  /* The renders ship with their ground keyed to transparency, so they sit on
     the band directly. Multiply was doing that job badly before — it cannot
     remove a #F2EFE9 ground, only darken it, which left a visible rectangle
     on every tinted section and dulled the bone-white objects with it. */
  pointer-events:none;
}
/* Centred band heads keep their centring; the render goes to the edge. */
.claypage .blk--workflow_table .sec-head:has(> .sec-illus),
.claypage .blk--feature_grid .sec-head:has(> .sec-illus){
  text-align:start;align-items:flex-start;
}
.claypage .blk--workflow_table .sec-head:has(> .sec-illus) .lead,
.claypage .blk--feature_grid .sec-head:has(> .sec-illus) .lead{margin-inline:0}
@media (max-width:780px){
  .claypage .sec-head:has(> .sec-illus){
    padding-inline-end:0;min-block-size:0;
  }
  .claypage .sec-illus{
    position:static;translate:none;display:block;
    inline-size:min(11rem, 46%);margin:1rem 0 0;
  }
}

/* ══ THE HERO, AS CLAY BUILDS ONE ═════════════════════════════════════════
   Copy in the left column at display size, the picture filling a saturated
   panel on the right — the same `beside` composition the figures use, scaled
   up and carrying the h1. `split` (every other page's hero) is untouched. */
.claysec.is-beside.is-hero > .wrap > .claysec-card{
  background:none;border:0;padding:0;box-shadow:none;
}
@media (min-width:900px){
  .claysec.is-beside.is-hero > .wrap > .claysec-card{
    grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
    gap:clamp(1.6rem,1rem + 2.4vw,3.4rem);
    align-items:center;
  }
}
.claysec.is-beside.is-hero .claysec-head{padding:0}
.claysec.is-beside.is-hero .claysec-h{
  font-size:clamp(2.5rem, 1.5rem + 4.2vw, 4.6rem);
  line-height:.98;letter-spacing:-.04em;
}
.claysec.is-beside.is-hero .claysec-para{
  font-size:clamp(1rem, .95rem + .25vw, 1.18rem);
  line-height:1.5;max-inline-size:38ch;margin-block-start:1.4rem;
}
/* Clay's call to action is a solid pill, not a text link. */
.claysec.is-beside.is-hero .claysec-link{
  margin-block-start:1.9rem;
  background:var(--ink);color:#fff;
  padding:.85rem 1.5rem;border-radius:999px;
  text-decoration:none;font-weight:560;
  box-shadow:0 1px 2px rgb(26 25 23 / .16), 0 12px 26px -14px rgb(26 25 23 / .6);
  transition:transform .22s var(--ease), box-shadow .22s var(--ease);
}
.claysec.is-beside.is-hero .claysec-link:hover{
  transform:translateY(-2px);
  box-shadow:0 2px 4px rgb(26 25 23 / .18), 0 18px 34px -16px rgb(26 25 23 / .65);
}
.claysec.is-beside.is-hero .claysec-link .arw{transition:translate .22s var(--ease)}
.claysec.is-beside.is-hero .claysec-link:hover .arw{translate:3px 0}
/* The panel is the hero's whole right half. */
.claysec.is-beside.is-hero .claysec-art{
  border-radius:1.9rem;
  min-block-size:clamp(19rem, 14rem + 20vw, 34rem);
  padding:clamp(1.4rem, .8rem + 2.4vw, 3rem);
}

/* The copy column was narrow enough to put the headline on four lines where
   Clay's sits on three, and the panel held the picture at arm's length. Both
   are the same fix: give the left column its share and let the picture fill
   what it is standing on. */
@media (min-width:900px){
  .claysec.is-beside.is-hero > .wrap > .claysec-card{
    grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
  }
}
.claysec.is-beside.is-hero .claysec-art{
  padding:clamp(1rem, .5rem + 1.6vw, 2rem);
}
.claysec.is-beside.is-hero .claysec-art img{
  inline-size:100%;border-radius:.9rem;
  box-shadow:0 3px 8px rgb(26 25 23 / .2), 0 30px 60px -24px rgb(26 25 23 / .6);
}

/* The hero panel is now one commissioned image that carries its own saturated
   ground edge to edge, so the art frame stops being a coloured box with a
   picture inside it and becomes the picture. `cover` on a slightly wide panel
   trims the empty ground above and below the composition rather than letting
   it letterbox. */
.claysec.is-beside.is-hero .claysec-art{
  padding:0;background:none;display:block;overflow:hidden;
}
.claysec.is-beside.is-hero .claysec-art img{
  inline-size:100%;block-size:100%;
  object-fit:cover;object-position:center;
  border-radius:0;box-shadow:none;
}

/* ── Regression: the section head became a flex column when it grew an
   illustration slot, and a flex column stretches its children. Every eyebrow
   pill on a strip section went full width — a 1,100px lozenge with four words
   in the middle of it. The head goes back to being a block; the vertical
   centring it needed is padding, which was all it ever needed. */
.claypage .sec-head:has(> .sec-illus){
  display:block;
  padding-block:clamp(.6rem, .3rem + 1vw, 1.4rem);
}
.claypage .blk--workflow_table .sec-head:has(> .sec-illus),
.claypage .blk--feature_grid .sec-head:has(> .sec-illus){display:block}

/* ── Twelve stages did not fit on one line. The strip lays its steps out in a
   single row of equal columns, which is right for six and impossible for
   twelve: at 1,100px each stage had 92px, and Pack, Dispatch, Return and
   Count printed on top of one another. Past eight steps it wraps to six per
   row — the track draws per step, so each row keeps its own line. */
.claypage .blk--process > .sec:not(.claysec) .pstrip:has(.pstep:nth-child(9)){
  grid-auto-flow:row;
  grid-template-columns:repeat(6, minmax(0, 1fr));
  row-gap:clamp(1.4rem, 1rem + 1.4vw, 2.4rem);
}
@media (max-width:900px){
  .claypage .blk--process > .sec:not(.claysec) .pstrip:has(.pstep:nth-child(9)){grid-template-columns:repeat(3, minmax(0,1fr))}
}
@media (max-width:560px){
  .claypage .blk--process > .sec:not(.claysec) .pstrip:has(.pstep:nth-child(9)){grid-template-columns:repeat(2, minmax(0,1fr))}
}

/* ══ THREE SEQUENCES, THREE SHAPES ════════════════════════════════════════
   A numbered line said the same thing about all three of these, and it was
   only true of one. What each one IS decides how it is drawn.

   B = .claypage .blk--process > .sec:not(.claysec) — the base rules sit at
   five classes, so every rule here has to as well. Written at three, the first
   attempt lost silently and the numbers kept the offset that centres them over
   a track.  =========================================================== */

/* ── THE CYCLE. Plan, Purchase, Receive, Inspect, Put away, Store, Replenish,
   Pick, Pack, Dispatch, Return, Count — and Count returns to Plan. It is a
   loop, so it is drawn as one: twelve positions around a ring, thirty degrees
   apart, each label counter-rotated back to level. The `--i` the template
   already writes on every step is what places them. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring{
  --r:clamp(8.5rem, 6rem + 13vw, 14.5rem);
  position:relative;display:block;
  inline-size:min(100%, calc(var(--r) * 2 + 13rem));
  aspect-ratio:1;margin-inline:auto;
  grid-template-columns:none;gap:0;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring::before{
  content:"";position:absolute;inset:calc(50% - var(--r));
  border-radius:50%;
  border:1.5px dashed color-mix(in srgb, var(--sec-accent, var(--brand)) 34%, transparent);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring .pstep{
  position:absolute;inset:0;margin:auto;
  inline-size:max-content;block-size:max-content;padding:0;
  display:grid;justify-items:center;gap:.3rem;
  transform:rotate(calc(var(--i) * 30deg)) translateY(calc(var(--r) * -1))
            rotate(calc(var(--i) * -30deg));
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring .pstep::before{display:none}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring .pnum{
  position:static;margin:0;justify-self:center;
  inline-size:1.75rem;block-size:1.75rem;
  box-shadow:0 0 0 5px color-mix(in srgb, var(--sec-accent, var(--brand)) 9%, #fff);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring .ptitle{
  font-size:.82rem;text-align:center;white-space:nowrap;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring .ptext{display:none}

/* ── THE CONTAINMENT. Company holds Warehouse holds Zone holds Aisle holds
   Shelf holds Bin. Not six steps — six frames, each drawn inside the last,
   which is the only picture of the thing that is actually true. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest{
  --step:clamp(1.5rem, 1rem + 1.6vw, 2.6rem);
  position:relative;display:block;
  inline-size:min(100%, 40rem);margin-inline:auto;
  aspect-ratio:16 / 10;
  grid-template-columns:none;gap:0;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest .pstep{
  position:absolute;
  inset:calc(var(--i) * var(--step) * .62) calc(var(--i) * var(--step));
  padding:0;display:block;
  border:1.5px solid color-mix(in srgb, var(--sec-accent, var(--brand))
         calc(24% + var(--i) * 11%), transparent);
  border-radius:calc(1.1rem - var(--i) * .12rem);
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 5%, transparent);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest .pstep::before{display:none}
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest .pnum{
  position:absolute;margin:0;
  inset-block-start:.55rem;inset-inline-start:.6rem;
  inline-size:1.5rem;block-size:1.5rem;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest .ptitle{
  position:absolute;inset-block-start:.72rem;inset-inline-start:2.5rem;
  font-size:.88rem;text-align:start;white-space:nowrap;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-nest .ptext{display:none}

/* ── THE PLAN. Discover to Go live is a project, and a project is read down a
   page, not across one. A spine with the stages alternating either side of
   it — the shape every delivery plan has ever been drawn in. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine{
  position:relative;display:grid;
  grid-template-columns:1fr auto 1fr;
  gap:.5rem 1.2rem;align-items:center;
  inline-size:min(100%, 46rem);margin-inline:auto;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine::before{
  content:"";position:absolute;inset-block:1rem;inset-inline-start:50%;
  inline-size:2px;translate:-50% 0;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--sec-accent, var(--brand)) 55%, transparent),
    color-mix(in srgb, var(--sec-accent, var(--brand)) 18%, transparent));
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep{
  display:grid;grid-template-columns:auto 1fr;align-items:center;gap:.7rem;
  padding:.62rem .95rem;border-radius:.85rem;
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 8%, #fff);
  border:1px solid color-mix(in srgb, var(--sec-accent, var(--brand)) 22%, transparent);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep::before{display:none}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep:nth-child(odd){
  grid-column:1;justify-self:end;direction:rtl;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep:nth-child(odd) > *{direction:ltr}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep:nth-child(even){
  grid-column:3;justify-self:start;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pnum{
  position:static;margin:0;inline-size:1.6rem;block-size:1.6rem;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .ptitle{
  text-align:start;font-size:.98rem;white-space:nowrap;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .ptext{display:none}
@media (max-width:640px){
  .claypage .blk--process > .sec:not(.claysec) .pstrip-spine{grid-template-columns:1fr}
  .claypage .blk--process > .sec:not(.claysec) .pstrip-spine::before{inset-inline-start:.9rem}
  .claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep:nth-child(n){
    grid-column:1;justify-self:stretch;direction:ltr;margin-inline-start:2rem;
  }
}

/* Polish on the three shapes. The ring's circle and the spine's line were
   drawn at the alpha a divider gets, but here they are the structure — they
   are what says "this returns to its start" and "this runs top to bottom" —
   so they carry the weight. Both were also holding more empty band than they
   needed. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring::before{
  border-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 52%, transparent);
  border-width:2px;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring{
  --r:clamp(8rem, 5.5rem + 12vw, 13rem);
  inline-size:min(100%, calc(var(--r) * 2 + 11rem));
}
/* The centre of a cycle is not empty space — it is the thing the cycle is
   about, so it says so. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-ring::after{
  content:"";position:absolute;inset:calc(50% - 2.6rem);
  border-radius:50%;
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 13%, #fff);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine{
  inline-size:min(100%, 54rem);
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine::before{
  inline-size:3px;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--sec-accent, var(--brand)) 70%, transparent),
    color-mix(in srgb, var(--sec-accent, var(--brand)) 28%, transparent));
  border-radius:2px;
}
/* a node where each stage meets the spine */
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep::after{
  content:"";position:absolute;inset-block-start:50%;
  inline-size:.45rem;block-size:.45rem;border-radius:50%;
  background:var(--sec-accent, var(--brand));translate:0 -50%;
}
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep{position:relative}
/* Both sides use inset-inline-START and both land on the spine, because the
   odd cards are flipped to `direction:rtl` so their inline start IS their
   physical right. Using `end` for the odd ones put every node on the far side
   of the card, out in the empty band. */
.claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep::after{
  inset-inline-start:-1.42rem;
}
@media (max-width:640px){
  .claypage .blk--process > .sec:not(.claysec) .pstrip-spine .pstep:nth-child(n)::after{
    inset-inline:auto auto;inset-inline-start:-1.35rem;
  }
}

/* ══ CLAY'S FIGURE COMPOSITION, FOR A SEQUENCE ════════════════════════════
   Copy in one column, the diagram in the other on a panel of the section's
   colour, sides swapped on the middle one. What sits on the panel is the live
   diagram — the ring, the frames, the spine — built from the page's own text
   rather than a picture of a diagram with text baked into it. */
.claypage .blk--process > .sec.is-figure > .wrap{
  background:none;padding:0;
}
@media (min-width:960px){
  .claypage .blk--process > .sec.is-figure > .wrap{
    display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
    gap:clamp(1.6rem,1rem + 2.4vw,3.4rem);align-items:center;
  }
  .claypage .blk--process > .sec.is-figure-flip > .wrap > .sec-head{order:2}
  .claypage .blk--process > .sec.is-figure-flip > .wrap > .pstrip{order:1}
}
.claypage .blk--process > .sec.is-figure > .wrap > .sec-head{
  text-align:start;max-inline-size:none;margin:0;
  display:block;padding-block:0;
}
.claypage .blk--process > .sec.is-figure .sec-head .h2{
  font-size:clamp(1.7rem,1.2rem + 1.7vw,2.5rem);line-height:1.08;
  letter-spacing:-.028em;color:var(--ink);
}
.claypage .blk--process > .sec.is-figure .sec-head .lead{
  color:var(--ink-2);max-inline-size:38ch;margin-inline:0;
}
/* the illustration goes back into the flow here — the copy column is narrow
   and an absolutely-placed render would sit on top of the paragraph. */
.claypage .blk--process > .sec.is-figure .sec-head:has(> .sec-illus){padding-inline-end:0}
.claypage .blk--process > .sec.is-figure .sec-illus{
  position:static;translate:none;display:block;
  inline-size:clamp(6rem,4rem + 6vw,9rem);margin:1.2rem 0 0;
}
/* THE PANEL. The section's colour, holding the live diagram. */
.claypage .blk--process > .sec.is-figure > .wrap > .pstrip{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 12%, #fff);
  border-radius:2rem;
  padding:clamp(1.4rem,1rem + 2.2vw,2.8rem);
  margin-block-start:0;
}
@media (max-width:959px){
  .claypage .blk--process > .sec.is-figure > .wrap > .pstrip{margin-block-start:1.6rem}
}

/* ══ THE PANELS, AS CLAY DRAWS THEM ═══════════════════════════════════════
   Clay's figure panels are a saturated ground carrying white cards joined by
   dotted lines. Theirs are images with the labels baked in; these are the same
   picture built in CSS, so every stage name is real text — selectable,
   searchable, and never misspelled by a generator. */
.claypage .blk--process > .sec.is-figure > .wrap > .pstrip{
  background:linear-gradient(158deg,
    color-mix(in srgb, var(--sec-accent, var(--brand)) 84%, #fff) 0%,
    var(--sec-accent, var(--brand)) 58%,
    color-mix(in srgb, var(--sec-accent, var(--brand)) 86%, #1A1817) 100%);
  box-shadow:0 2px 6px rgb(26 25 23 / .12), 0 30px 60px -34px rgb(26 25 23 / .5);
}
/* Every stage becomes a white card on the colour. */
.claypage .blk--process > .sec.is-figure .pstrip .pstep{
  background:#fff;border-radius:.7rem;
  box-shadow:0 1px 2px rgb(26 25 23 / .12), 0 8px 18px -10px rgb(26 25 23 / .45);
}
.claypage .blk--process > .sec.is-figure .pstrip .ptitle{color:var(--ink)}
.claypage .blk--process > .sec.is-figure .pstrip .pnum{
  background:color-mix(in srgb, var(--sec-accent, var(--brand)) 16%, #fff);
  color:color-mix(in srgb, var(--sec-accent, var(--brand)) 76%, #1A1817);
  box-shadow:none;
}
/* THE RING on colour: white cards at the twelve positions, a white dashed
   orbit, and a white disc at the centre. */
.claypage .blk--process > .sec.is-figure .pstrip-ring .pstep{
  padding:.4rem .7rem;display:grid;grid-auto-flow:column;align-items:center;gap:.45rem;
}
.claypage .blk--process > .sec.is-figure .pstrip-ring .ptitle{font-size:.78rem}
.claypage .blk--process > .sec.is-figure .pstrip-ring .pnum{
  inline-size:1.25rem;block-size:1.25rem;font-size:.6rem;
}
.claypage .blk--process > .sec.is-figure .pstrip-ring::before{
  border-color:rgb(255 255 255 / .55);
}
.claypage .blk--process > .sec.is-figure .pstrip-ring::after{
  background:rgb(255 255 255 / .16);
  inset:calc(50% - 3.2rem);
}
/* THE FRAMES on colour: white outlines deepening inward, labels in white. */
.claypage .blk--process > .sec.is-figure .pstrip-nest .pstep{
  background:rgb(255 255 255 / .1);
  border-color:rgb(255 255 255 / .5);
  box-shadow:none;
}
.claypage .blk--process > .sec.is-figure .pstrip-nest .ptitle{color:#fff}
.claypage .blk--process > .sec.is-figure .pstrip-nest .pnum{
  background:#fff;color:color-mix(in srgb, var(--sec-accent, var(--brand)) 76%, #1A1817);
}
/* THE SPINE on colour: a white line, white cards either side, white nodes. */
.claypage .blk--process > .sec.is-figure .pstrip-spine::before{
  background:rgb(255 255 255 / .6);
}
.claypage .blk--process > .sec.is-figure .pstrip-spine .pstep{
  border-color:transparent;
}
.claypage .blk--process > .sec.is-figure .pstrip-spine .pstep::after{
  background:#fff;box-shadow:0 0 0 3px color-mix(in srgb, var(--sec-accent, var(--brand)) 70%, #fff);
}

/* White type on a mid-green needs weight to hold — the frames sit behind the
   labels and were washing them out. */
.claypage .blk--process > .sec.is-figure .pstrip-nest .ptitle{
  font-weight:600;text-shadow:0 1px 3px rgb(26 25 23 / .28);
}
.claypage .blk--process > .sec.is-figure .pstrip-nest .pnum{
  box-shadow:0 1px 3px rgb(26 25 23 / .25);
}

/* The three commissioned panels carry their own coloured ground edge to edge,
   the way the hero panel does, so the frame must not add a second one behind
   them or pad them away from its own corners. */
.claysec.is-beside .claysec-art:has(img[src*="panel-"]){
  padding:0;background:none;display:block;overflow:hidden;
}
.claysec.is-beside .claysec-art:has(img[src*="panel-"]) img{
  inline-size:100%;block-size:100%;object-fit:cover;object-position:center;
  border-radius:0;box-shadow:none;
}

/* ══ THE CARDS ════════════════════════════════════════════════════════════
   Three problems in one rule. The grid was pinned to three columns whatever
   the block asked for, so every four-item set broke 3 + 1 with an orphan on
   its own row. The cards were stark white with no border, which on a pale
   tinted band reads as a hole rather than a card. And the type was set small
   enough to look like a caption under a heading three times its size. */
.claypage .blk--feature_grid .grid.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.claypage .blk--feature_grid .grid.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.claypage .blk--feature_grid .grid.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:1180px){
  .claypage .blk--feature_grid .grid.g4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:820px){
  .claypage .blk--feature_grid .grid.g3{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .claypage .blk--feature_grid .grid.g2,
  .claypage .blk--feature_grid .grid.g3,
  .claypage .blk--feature_grid .grid.g4{grid-template-columns:minmax(0,1fr)}
}
.claypage .blk--feature_grid .card{
  /* warm, not stark — and a real edge, so the card is an object on the band
     rather than a rectangle punched out of it */
  background:#FEFCFA;
  border:1px solid color-mix(in srgb, var(--sec-accent, var(--brand)) 22%, transparent);
  border-radius:1.15rem;
  padding:clamp(1.25rem, 1rem + .9vw, 1.75rem);
  /* four across need to line up, so they share a floor */
  min-block-size:clamp(11rem, 9rem + 6vw, 14rem);
  display:flex;flex-direction:column;
  box-shadow:0 1px 2px rgb(26 25 23 / .05), 0 14px 30px -16px rgb(26 25 23 / .26);
}
.claypage .blk--feature_grid .card:hover{
  border-color:color-mix(in srgb, var(--sec-accent, var(--brand)) 45%, transparent);
}
.claypage .blk--feature_grid .card .ico-badge{
  inline-size:2.5rem;block-size:2.5rem;margin-bottom:1rem;
}
.claypage .blk--feature_grid .card h3{
  font-size:clamp(1.12rem, 1rem + .35vw, 1.3rem);
  font-weight:600;letter-spacing:-.02em;margin:0 0 .5rem;line-height:1.22;
}
.claypage .blk--feature_grid .card p{
  font-size:clamp(.95rem, .9rem + .2vw, 1.04rem);
  line-height:1.55;color:var(--ink-2);margin:0;
}

/* A ten-item set at two across is five rows of very wide cards; five across
   reads as one board. `g5` has no base rule, so it gets one here. */
.claypage .blk--feature_grid .grid.g5{grid-template-columns:repeat(5,minmax(0,1fr))}
@media (max-width:1180px){
  .claypage .blk--feature_grid .grid.g5{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:820px){
  .claypage .blk--feature_grid .grid.g5{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .claypage .blk--feature_grid .grid.g5{grid-template-columns:minmax(0,1fr)}
}
/* Five across is a narrower column, so its type steps back down a little. */
.claypage .blk--feature_grid .grid.g5 .card{
  min-block-size:clamp(9.5rem, 8rem + 4vw, 12rem);
  padding:clamp(1rem, .85rem + .6vw, 1.35rem);
}
.claypage .blk--feature_grid .grid.g5 .card h3{font-size:clamp(1rem,.95rem + .2vw,1.1rem)}
.claypage .blk--feature_grid .grid.g5 .card p{font-size:clamp(.88rem,.85rem + .12vw,.95rem)}

/* ══ THE FIGURE CARDS ═════════════════════════════════════════════════════
   Same three faults the grid cards had. The card was #fff with a 7% border on
   a white page — an edge you cannot see holding a background that is not
   there — and the paragraph beside a 44px heading was set at 16px, so the
   column read as a caption rather than as the copy. */
.claysec.is-beside:not(.is-hero) > .wrap > .claysec-card{
  background:color-mix(in srgb, var(--accent, var(--brand)) 6%, #fff);
  border:1px solid color-mix(in srgb, var(--accent, var(--brand)) 20%, transparent);
  padding:clamp(1.5rem, 1.1rem + 1.8vw, 2.6rem);
  box-shadow:0 1px 2px rgb(26 25 23 / .04), 0 18px 40px -22px rgb(26 25 23 / .24);
}
.claysec.is-beside:not(.is-hero) .claysec-para{
  font-size:clamp(1rem, .94rem + .28vw, 1.12rem);
  line-height:1.58;color:var(--ink-2);max-inline-size:44ch;
}
.claysec.is-beside:not(.is-hero) .claysec-h{
  font-size:clamp(1.75rem, 1.2rem + 1.5vw, 2.4rem);
}
.claysec.is-beside:not(.is-hero) .claysec-eyebrow{
  font-size:.76rem;letter-spacing:.1em;
}
/* The panel keeps its own corners inside the card's padding. */
.claysec.is-beside:not(.is-hero) .claysec-art{border-radius:1.4rem}

/* A clay render on a saturated panel is a framed inset, not a cut-out. The
   objects are bone-white on an off-white ground and no fill separates them
   from it without biting into them — keying left a pale ring that reads as
   fringing on colour. Framed, with the panel's colour around it, the ground
   is part of the picture. */
.claysec.is-beside .claysec-art img[src*="/apps/fig-"]{
  border-radius:1.1rem;
  box-shadow:0 2px 6px rgb(26 25 23 / .16), 0 22px 44px -20px rgb(26 25 23 / .5);
}

/* Larion's renders are framed insets for the same reason the app ones are:
   bone-white objects on an off-white ground cannot be keyed off it without
   biting into them, so the ground stays and the panel's colour goes around. */
.claysec.is-beside .claysec-art img[src*="/larion/"]{
  border-radius:1.1rem;
  box-shadow:0 2px 6px rgb(26 25 23 / .16), 0 22px 44px -20px rgb(26 25 23 / .5);
}

/* ── Sub-columns only when a column is long enough to need them ───────────
   `.hdr .mega-links` split every column into two, which is right for the one
   wide column of eight the capability menus carry and wrong for the About
   panel, whose four columns hold one to five links each — those overlapped,
   printing "Insta" over "Facebook". Two sub-columns from six links up; one
   below that. */
.hdr .mega-links{grid-template-columns:minmax(0,1fr)}
.hdr .mega-links:has(> a:nth-child(6)){grid-template-columns:repeat(2,minmax(0,1fr))}
/* Four columns plus the promo card is a tight panel; give each a floor so a
   label never has to wrap mid-word. */
.hdr .mega-cols{grid-auto-columns:minmax(9.5rem,1fr)}

/* ── The service picker ───────────────────────────────────────────────────
   Radios styled as chips. The input stays in the DOM and keeps its keyboard
   behaviour and its focus ring; only its box is hidden, so arrow keys still
   move through the set and a screen reader still hears a radio group. */
.topicset{border:0;padding:0;margin:0}
.topicset > legend{
  font-size:var(--t-sm);font-weight:560;color:var(--ink-2);
  padding:0;margin-bottom:.6rem;
}
.topics{display:flex;flex-wrap:wrap;gap:.5rem}
.topic{position:relative;display:inline-flex}
.topic input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.topic span{
  display:inline-block;padding:.55rem 1rem;border-radius:999px;
  border:1px solid rgb(26 25 23 / .14);background:#fff;
  font-size:.9rem;color:var(--ink-2);
  transition:border-color .18s var(--ease), background .18s var(--ease),
             color .18s var(--ease);
}
.topic:hover span{border-color:rgb(26 25 23 / .3);color:var(--ink)}
.topic input:checked + span{
  border-color:var(--brand);background:color-mix(in srgb, var(--brand) 8%, #fff);
  color:var(--ink);font-weight:560;
}
.topic input:focus-visible + span{outline:2px solid var(--focus);outline-offset:2px}

/* ── Site assistant ───────────────────────────────────────────────────────
   A conversation panel, not a floating bubble. It sits in the page as a
   section because it is one of the two ways to reach the team, and a widget
   that hovers over the corner reads as an upsell rather than an offer. */
/* The section sits on its own tinted ground with a centred head, the same
   move the capability pages make for a band that is one idea rather than a
   list. Left-aligned head plus a centred panel read as a widget dropped into
   the page; this reads as a part of it. */
.blk--chat > .sec{
  background:linear-gradient(180deg,#F6F4F0 0%, #F2EFE9 100%);
  border-block:1px solid rgb(26 25 23 / .07);
}
.blk--chat .sec-head{
  text-align:center;max-inline-size:46rem;margin-inline:auto;
}
.blk--chat .sec-head .lead{margin-inline:auto}

.chat{
  border:1px solid rgb(26 25 23 / .1);border-radius:var(--r-lg,20px);
  background:var(--pane-solid,#fff);overflow:hidden;
  box-shadow:var(--el-2);max-inline-size:62rem;margin-inline:auto;
}
.chat-log{
  padding:clamp(1.3rem,1rem + 1.2vw,2rem);
  display:flex;flex-direction:column;gap:.9rem;
  min-block-size:13rem;max-block-size:32rem;
  overflow-y:auto;overscroll-behavior:contain;
}
.cmsg{display:flex}
.cmsg--me{justify-content:flex-end}
.cmsg-body{
  max-inline-size:min(44ch,88%);padding:.8rem 1.05rem;border-radius:16px;
  font-size:var(--t-body);line-height:1.62;
}
.cmsg-body > p + p{margin-block-start:.7em}
.cmsg--bot .cmsg-body{background:color-mix(in srgb, var(--ink) 4%, #fff);color:var(--ink)}
.cmsg--me  .cmsg-body{background:var(--ink);color:#fff;border-end-end-radius:5px}
.cmsg--bot .cmsg-body{border-end-start-radius:5px}
.cmsg--sys .cmsg-body{
  background:color-mix(in srgb, var(--brand) 7%, #fff);
  border:1px solid color-mix(in srgb, var(--brand) 22%, transparent);
}

/* The general-knowledge block. Tinted, inset and labelled, so the boundary
   between "the site says" and "ERP generally works like this" is a thing you
   can see rather than a sentence you have to notice. */
.cgen{
  margin-block-start:.9rem;padding:.75rem .9rem;border-radius:12px;
  background:color-mix(in srgb, #3E8EA8 8%, #fff);
  border-inline-start:3px solid #3E8EA8;
}
.cgen-tag{
  display:block;font-size:.72rem;font-weight:640;letter-spacing:.05em;
  text-transform:uppercase;color:#2C6C82;margin-block-end:.4rem;
}
.cgen p{font-size:.94rem}

.csrc{
  margin-block-start:.9rem;padding-block-start:.7rem;
  border-block-start:1px solid rgb(26 25 23 / .1);
  display:flex;flex-wrap:wrap;align-items:center;gap:.45rem;
}
.csrc-tag{
  font-size:.72rem;font-weight:640;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-3);margin-inline-end:.2rem;
}
.csrc a{
  font-size:.85rem;padding:.24rem .6rem;border-radius:999px;
  border:1px solid rgb(26 25 23 / .14);color:var(--ink-2);
}
.csrc a:hover{border-color:var(--brand);color:var(--brand)}

.cdots{display:flex;gap:.3rem;padding-block:.35rem}
.cdots span{
  inline-size:.42rem;block-size:.42rem;border-radius:50%;
  background:var(--ink-3);animation:cdot 1.1s var(--ease) infinite;
}
.cdots span:nth-child(2){animation-delay:.16s}
.cdots span:nth-child(3){animation-delay:.32s}
@keyframes cdot{0%,60%,100%{opacity:.25;transform:translateY(0)}
                30%{opacity:1;transform:translateY(-3px)}}

.chat-sugg{
  display:flex;flex-wrap:wrap;gap:.45rem;
  padding:0 clamp(1.1rem,.9rem + 1vw,1.8rem) .9rem;
}
/* `display:flex` beats the UA sheet's `[hidden]{display:none}`, so the chips
   came back after the first question. Measured, not assumed. */
.chat-sugg[hidden]{display:none}
.csugg{
  font:inherit;font-size:.85rem;cursor:pointer;
  padding:.42rem .85rem;border-radius:999px;
  border:1px solid rgb(26 25 23 / .14);background:#fff;color:var(--ink-2);
  transition:border-color .18s var(--ease), color .18s var(--ease);
}
.csugg:hover{border-color:var(--brand);color:var(--brand)}

.chat-form{
  display:flex;gap:.6rem;align-items:center;
  padding:clamp(.8rem,.6rem + .6vw,1.1rem) clamp(1.1rem,.9rem + 1vw,1.8rem);
  border-block-start:1px solid rgb(26 25 23 / .1);
  background:color-mix(in srgb, var(--ink) 2%, #fff);
}
.chat-form input{
  flex:1;min-inline-size:0;font:inherit;font-size:var(--t-body);
  padding:.7rem .95rem;border-radius:12px;
  border:1px solid rgb(26 25 23 / .16);background:#fff;color:var(--ink);
}
.chat-form input:focus{outline:2px solid var(--focus);outline-offset:1px;
  border-color:transparent}
.chat-form input:disabled{opacity:.55}
.chat-form .btn{flex:none}
.chat-note{
  max-inline-size:62rem;margin:.9rem auto 0;text-align:center;
  font-size:.82rem;line-height:1.6;color:var(--ink-3);
}
@media (max-width:640px){
  .chat-log{max-block-size:26rem}
  .cmsg-body{max-inline-size:94%}
}
@media (prefers-reduced-motion:reduce){
  .cdots span{animation:none;opacity:.5}
}

/* ── Menu plates that are pictures ────────────────────────────────────────
   A commissioned render in the icon slot. It gets no tint and no coloured
   ring: the render carries its own accent, and a coloured box around a
   coloured object is two accents fighting in 32 square pixels. The plate is
   a little larger than a glyph plate because the objects need the room —
   measured at 2rem and the shapes turned to mush. */
.hdr .mega .plate--img{
  --i:transparent;
  inline-size:2.35rem;block-size:2.35rem;padding:0;overflow:hidden;
  background:#F2EFE9;                       /* the renders' own ground */
  box-shadow:inset 0 0 0 1px rgb(26 25 23 / .08);
}
.hdr .mega .plate--img img{
  inline-size:100%;block-size:100%;object-fit:cover;
  transform:scale(1.16);                    /* crop the render's margin */
  transition:transform .18s var(--e-out);
}
.hdr .mega a:hover .plate--img{background:#EDE9E1}
.hdr .mega a:hover .plate--img img{transform:scale(1.24)}
@media (prefers-reduced-motion:reduce){
  .hdr .mega .plate--img img,
  .hdr .mega a:hover .plate--img img{transition:none;transform:scale(1.16)}
}

/* Drawer rows carry the same marks as the desktop panel. The plate rules in
   the panel are scoped `.hdr .mega`, and the drawer is a sibling of .hdr, so
   the whole set is restated here rather than reached for with a longer
   selector — the two live in different stacking contexts and will keep
   drifting otherwise. */
.mnav .sub a,
.mnav .sub-links a{display:flex;align-items:center;gap:.7rem}
.mnav .plate{
  --i:var(--fam,var(--ink-3));
  inline-size:1.9rem;block-size:1.9rem;flex:none;
  display:grid;place-items:center;border-radius:.55rem;
  background:color-mix(in srgb,var(--i) 13%,#fff);color:var(--i);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--i) 20%,transparent);
}
.mnav .plate .ico{stroke-width:1.85}
.mnav .plate--img{
  --i:transparent;inline-size:2.2rem;block-size:2.2rem;
  padding:0;overflow:hidden;background:#F2EFE9;
  box-shadow:inset 0 0 0 1px rgb(26 25 23 / .08);
}
.mnav .plate--img img{
  inline-size:100%;block-size:100%;object-fit:cover;transform:scale(1.16);
}

/* A render in a card, where a glyph badge would otherwise sit. Larger than the
   menu plate because a card has the room and the object earns it. */
.card-plate{
  display:block;inline-size:3.1rem;block-size:3.1rem;
  border-radius:.8rem;overflow:hidden;background:#F2EFE9;
  box-shadow:inset 0 0 0 1px rgb(26 25 23 / .08);
  margin-block-end:.9rem;
}
.card-plate img{
  inline-size:100%;block-size:100%;object-fit:cover;transform:scale(1.14);
}

/* A one-card grid. Without this, `g1` matches no rule and falls through to the
   three-column default, so the single warehouse card rendered at a third width
   against an empty two thirds. The card turns horizontal at the same time —
   a full-width card with the text in a narrow column at the top left is worse
   than the narrow card it replaced. */
/* Scoped `.claypage .blk--feature_grid` like its g2/g3/g4/g5 siblings, not
   plain `.grid.g1`: the base rule at .claypage .blk--feature_grid .grid is
   three classes and wins against two. Measured — the first attempt still
   reported three columns of 372px. */
.grid.g1,
.claypage .blk--feature_grid .grid.g1{grid-template-columns:minmax(0,1fr)}
@media (min-width:720px){
  .grid.g1 .card,
  .claypage .blk--feature_grid .grid.g1 .card{
    display:grid;grid-template-columns:auto minmax(0,1fr);
    column-gap:clamp(1.2rem,1rem + 1.4vw,2.2rem);align-items:start;
  }
  .grid.g1 .card .card-plate,
  .claypage .blk--feature_grid .grid.g1 .card .card-plate{
    grid-row:1 / span 3;margin-block-end:0;
    inline-size:5.2rem;block-size:5.2rem;border-radius:1rem}
  .grid.g1 .card p{margin-block-start:.45rem}
}

/* ── Not found ────────────────────────────────────────────────────────────
   A 404 is a visitor who wanted something and did not get it. The page owes
   them the routes, not an apology, so the families sit under the heading as
   real destinations. */
.err-page{padding-block:clamp(4rem,3rem + 6vw,8rem)}
.err-head{max-inline-size:44rem;margin-inline:auto;text-align:center}
.err-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));
  gap:.9rem;margin-block-start:clamp(2.4rem,2rem + 2vw,3.6rem);
  max-inline-size:62rem;margin-inline:auto;
}
.err-card{
  display:flex;flex-direction:column;gap:.25rem;
  padding:1.05rem 1.2rem;border-radius:14px;
  border:1px solid rgb(26 25 23 / .12);background:var(--pane-solid,#fff);
  transition:border-color .18s var(--ease), transform .18s var(--ease),
             box-shadow .18s var(--ease);
}
.err-card:hover{border-color:var(--brand);transform:translateY(-2px);
  box-shadow:0 8px 20px -12px rgb(26 25 23 / .4)}
.err-card strong{font-size:1.02rem;color:var(--ink)}
.err-card span{font-size:.85rem;color:var(--ink-3)}
.err-cta{
  display:flex;flex-wrap:wrap;gap:.7rem;justify-content:center;
  margin-block-start:clamp(2rem,1.6rem + 1.6vw,3rem);
}

/* ── Responsive repairs, 2026-09-06 ───────────────────────────────────────
   Found by walking every published page at 320/360/390/768/1024/1440 and
   asking the browser which element crossed the viewport edge, rather than by
   looking at screenshots. */

/* The Larion pages copied `.p5page .card-plain`'s edge-bleed — a negative
   inline margin that lets a card sit proud of its column — but not the mobile
   reset that goes with it. So on a phone the card was 340px inside a 305px
   grid and hung 17.6px off both sides. Same reset, same breakpoint. */
@media (max-width:700px){
  .p5larion .card-plain{margin-inline:0;padding-inline:0}
}

/* `repeat(auto-fit, minmax(13rem, 1fr))` cannot shrink below 13rem per column,
   and `.sec` is a grid whose items default to `min-width:auto`, so the 404's
   wrap resolved to its min-content — 912px inside a 360px viewport. `min()`
   lets a column collapse to the container instead. */
.err-grid{grid-template-columns:repeat(auto-fit,minmax(min(13rem,100%),1fr))}
/* `.sec` is a grid and `.wrap` is a grid item, so its default `min-width:auto`
   stops it shrinking below its own min-content — and `max-inline-size:min(...,
   100%)` inside it is circular, because the 100% resolves against a box being
   sized by the content it contains. `min-width:0` breaks the circle: the wrap
   takes the viewport, and everything inside measures against that. */
.err-page > .wrap{min-inline-size:0}
.err-head{max-inline-size:44rem}

/* The eyebrow pill trails two ghost shapes, `::before` reaching 2.2rem past
   its right edge. The pill itself is bounded by its container, so on a wide
   screen the ghosts land in the margin and nobody notices — but at 320px a
   long eyebrow ("WHAT THAT MEANS IN PRACTICE") fills the line and the ghosts
   are what push the page sideways. This was the whole of the remaining
   horizontal overflow: /about/offices/ 11px, two capability pages 17px, all
   three Larion pages 25px. Reserving the ghosts' own width fixes every one of
   them and changes nothing above ~420px, where no eyebrow is that long. */
.eyebrow{max-inline-size:calc(100% - 2.4rem)}
