/* ==========================================================
   /capabilities (VLP-1226) : the capabilities page layer only.

   WHAT THIS FILE OWNS
   Everything that is this page and no other: the two-column hero and its
   family index, the archive bed that rises behind it, the two sample panels
   built from real markup (the ingest handoff ledger and the photo select
   board), the two product crops this page authors, the rules grids, the peak
   and the closer, this page's act seams by id, and the no-JS, static and
   reduced-motion restatements for exactly those moves.

   WHAT IT DEPENDS ON
   /folio.css, loaded first: tokens, reset, base type, the section formula,
   buttons, the nav, frames and the window device, the grids, the footer, the
   modal, the sticky CTA. This file adds to that layer and never restates it.

   LOAD ORDER
   critical fallback <style> -> /folio.css -> /capabilities-v2.css ->
   /scrollcraft.css. The engine sheet is last so the page can override its
   tokens; folio.css restates every engine base rule it changes at a higher
   specificity.

   CANDIDATES FOR PROMOTION INTO folio.css
   .cap-rules-2 / .cap-rules-3 (a .rules list laid out as a grid) and .pair-rev
   (a pair whose media half comes first on a phone) are page-scoped here
   because the shared layer has no grid form of .rules and no pair order
   control. Both are general; see docs/capabilities-v2.md.
   ========================================================== */

/* ---------------- hero ----------------
   Two columns: the claim on the left, the six family names on the right. The
   archive itself sits behind both, far back, and rises across the pin. */
.hero{position:relative;min-height:100svh}
/* The act is only a length. Everything the reader sees lives on the stage, which is what the
   engine sticks; when the hero is not pinned (phones, coarse pointers, reduced motion) the same
   block simply flows, because every rule here is on the stage rather than on the act.
   clip, not hidden: an overflow:hidden ancestor turns into the scrollport a sticky stage
   measures itself against, and the pin stops engaging. */
/* min-height, not just on the act: the bed is anchored to the STAGE's bottom, and when the act
   is demoted to flow (a phone, a coarse pointer, reduced motion) the stage is only as tall as its
   own content, which would park the archive directly behind the lead. A full viewport of stage
   keeps the horizon under the copy in every mode. */
.hero-stage{position:relative;overflow:clip;min-height:100svh;display:flex;flex-direction:column;
  justify-content:flex-start;background:var(--ink);padding:calc(var(--nav-h) + var(--nav-inset) + 38px) 0 0}
.hero-stage::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(ellipse at 50% 0%,rgba(244,241,234,.05),transparent 62%)}
/* margin-inline:auto on a flex item cancels the cross-axis stretch, so a .wrap inside a stage
   shrinks to its own content and a centred frame comes out narrow. */
.hero-stage>.wrap,.fit-stage>.wrap,.closer-stage>.wrap{width:100%}
.cap-hero-grid{position:relative;z-index:2;width:100%;display:grid;
  grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr);gap:56px;align-items:start}
.hero-in{min-width:0;display:flex;flex-direction:column;align-items:flex-start;text-align:left}
/* Line masks reserve descender room. Instrument Serif hangs its g, y and p a long way below the
   baseline, and the engine's default 0.14em shears them at this line-height. */
.hero h1 .sc-split--line{padding-bottom:.26em;margin-bottom:-.26em}
.hero h1{margin-top:20px;max-width:17ch}
.hero-lead{margin-top:26px;max-width:48ch;font-size:clamp(15.5px,1.25vw,17px)}
.hero-cta{margin-top:24px;display:flex;align-items:center;gap:20px;flex-wrap:wrap}
/* The offer, in the fold, at the size the Free Build page now sets it: 13.5px in --text rather
   than the 10.5px --dim of a .fine. This page asks for the application and used to be the one
   page carrying that CTA without ever stating what it commits the reader to. */
.cap-terms{margin-top:20px;text-align:left;letter-spacing:.12em;text-transform:uppercase;
  font-size:13.5px;color:var(--text)}

/* ---------------- the family index ----------------
   The page's table of contents, set as display type. Each name is a real link into its own
   section, so the thing that grounds the hero is also the way in. The rows and their numbers are
   always there; only the words are cued, so at p = 0 the reader sees an index with one entry
   written in and five waiting, rather than an empty column. */
.cap-index{min-width:0}
.cap-index ol{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.cap-index li{display:flex;align-items:baseline;gap:18px;padding:7px 0 9px;
  border-bottom:1px solid var(--line)}
.cap-i-n{flex:none;font-family:var(--mono);font-size:10.5px;letter-spacing:.15em;color:var(--dim)}
.cap-i-w{display:block;min-width:0;font-family:var(--serif);font-weight:400;line-height:1.04;
  letter-spacing:-.01em;color:var(--text);font-size:clamp(26px,3.3vw,44px);
  padding-bottom:.06em;transition:color .2s}
.cap-i-w:hover{color:var(--blue)}
/* The index writes itself in under the hand, but a list with one name and five empty rows reads
   as a gap on landing. Each row carries a dim ghost of its name under the cued one, so the list is
   whole from the first frame and brightens as the reader scrolls. The link stays one element. */
.cap-i-w{position:relative}
.cap-i-w::before{content:attr(data-name);position:absolute;inset:0 auto auto 0;color:var(--text);
  opacity:.2;pointer-events:none}
.cap-i-t{position:relative;display:inline-block}
html.no-js .cap-i-w::before,html.hv-static .cap-i-w::before{display:none}

/* ---------------- the bed ----------------
   A real product screen, rising into the bottom of the stage. It carries no cue: it is the
   ground the pinned act needs at p = 0, and a ground is a thing that is simply there. Only its
   top band is ever visible, so the copy and the index sit on clean ink and the archive reads as
   a horizon under them rather than as a photograph behind them. Its lift and its pan are both
   driven from the act's own progress. */
.cap-bed{position:absolute;left:0;right:0;bottom:0;height:38%;z-index:1;pointer-events:none;
  overflow:clip;padding:0 var(--pad)}
.cap-bed-lift{max-width:1180px;margin:0 auto;
  /* --sc-p defaults to 1 so the bed is already resolved before the engine writes anything, and
     stays resolved for a browser that never runs the script. */
  --u:clamp(0,calc(var(--sc-p,1) / .82),1);
  transform:translate3d(0,calc((1 - var(--u)) * 26%),0);
  transform-origin:50% 0%}
.cap-bed-frame{opacity:.5;box-shadow:none;border-color:var(--line-2);border-bottom:0;
  border-radius:18px 18px 0 0}
/* The scrim keeps the horizon a horizon: the picture fades out downward, so the frame never
   collides with the section seam under it. */
.cap-bed::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(11,15,20,.35) 46%,rgba(11,15,20,.86) 84%,var(--ink))}
/* --- the hero when nothing is pinned ---
   The bed is a horizon only while the stage is stuck: an absolutely positioned band across the
   bottom of a viewport-tall stage. Take the pin away, which is what ?static=1, reduced motion, a
   coarse pointer and any width under 900px all do, and the stage is only as tall as its content
   while the bed is still nailed to its bottom edge, so the lead, the cream CTA and the offer line
   printed straight over the product window: the one broken layout on the site, and the state
   every reduced-motion visitor and every crawler saw. So in that state there is no absolute
   stage at all. The window becomes an ordinary block under the copy, in flow, the way the
   homepage's demoted hero already worked, and it becomes a whole frame rather than a horizon:
   nothing is fading into a seam that is not there. .sc-stage is the class the engine puts on a
   pinned stage, so this is exactly "not pinned", in every one of those four ways at once. */
.hero-stage:not(.sc-stage){min-height:0}
.hero-stage:not(.sc-stage) .cap-bed{position:relative;height:auto;overflow:visible;
  /* The bed is authored first in the markup, because a pinned stage paints it behind the copy.
     In flow it has to come after: order, not a second copy of the markup. */
  order:2;margin-top:clamp(38px,5vh,64px)}
.hero-stage:not(.sc-stage) .cap-bed::after{display:none}
.hero-stage:not(.sc-stage) .cap-bed-frame{opacity:1;border-bottom:1px solid var(--line-2);
  border-radius:18px;box-shadow:var(--shadow)}

/* ---------------- this page's seams ----------------
   Stated by id so the value survives the hero and the close being demoted to flow on a phone or
   under reduced motion. #foundation's heading is what the hero's index hands over to, and the
   last family has to hand over to the peak rather than to half a screen of ground. */
/* This page used to run at 0.40 of the old rhythm, less than half of every other page, because
   the shared seam was 227px and six near-identical family sections separated by that read as the
   page having run out. The shared seam is now 150px, which is a breath rather than a screen, so
   this page takes it like the others and the families stop running together. */
#foundation{padding-top:calc(var(--sec-pad) * .5)}
#integrations{padding-bottom:calc(var(--sec-pad) * .62)}
.pair,.more{margin-top:42px}
.stage-mid{margin-top:40px}
.head .display{margin-top:15px}
.head .eyebrow+.display{margin-top:17px}
.head .lead{margin-top:16px}
.card{padding:22px 22px 0}
.card-plain{padding-bottom:22px}
.card .rules li{padding:16px 0 18px}
#archive .stage-mid{max-width:1040px}

/* ---------------- the foundation panel ----------------
   Four inherited pieces, two by two. No media: this is the breather between the hero and the
   first family, and its whole job is to say that the six families sit on one thing. */
.cap-panel{max-width:900px;margin:40px auto 0;padding:26px 28px 28px;background:var(--surface);
  border:1px solid var(--line);border-radius:20px}
.cap-panel-k{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);display:block}

/* ---------------- rules as a grid ----------------
   folio.css lays .rules out as a column inside the text half of a pair. These two forms lay the
   same list out as a grid, for a panel of four and for a row of three under a wide frame. */
.rules.cap-rules-2,.rules.cap-rules-3{display:grid;margin-top:22px;border-top:1px solid var(--line)}
.rules.cap-rules-2{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:36px}
.rules.cap-rules-3{grid-template-columns:repeat(3,minmax(0,1fr));column-gap:32px;margin-top:40px}
.rules.cap-rules-2 li,.rules.cap-rules-3 li{padding:20px 0 22px;border-top:0}
.rules.cap-rules-2 li+li,.rules.cap-rules-3 li+li{border-top:0}
/* Only the rows below the first get a rule, so the grid reads as rows rather than as a table. */
.rules.cap-rules-2 li:nth-child(n+3){border-top:1px solid var(--line)}
.rules.cap-rules-2 li:nth-last-child(-n+2){padding-bottom:0}
.rules.cap-rules-3 li:last-child,.rules.cap-rules-3 li{padding-bottom:0}
.rules.cap-rules-3 li p,.rules.cap-rules-2 li p{max-width:34ch}

/* ---------------- the pair, media first on a phone ----------------
   Two families put their rules before their frame in the markup, so the reading order stays
   text then evidence. On one column that leaves a phone with two screens of list before the
   first picture, so the media half comes up. */
@media(max-width:900px){
  .pair-rev>*:last-child{order:-1}
  .pair-rev{display:flex;flex-direction:column}
}

/* ---------------- this page's product crops ----------------
   Each crop is chosen so the claim above it is the thing you can actually see: the transcript
   excerpts in the search results, the one cut standing in its review stage. These screenshots
   are 16:10 at 1600 wide, the same shape as the shared /free-build/ set, but they are different
   screens, so the numbers are authored here rather than inherited. */
.cap-shot-search{aspect-ratio:4/3;--zoom:200%;--sx:-31%;--sy:-22%;--w-from:0px;--w-to:-88px}
.cap-shot-review{aspect-ratio:4/3;--zoom:320%;--sx:-99%;--sy:-32%;--w-from:0px;--w-to:-30px}

/* ---------------- the relay window ----------------
   The relay screen's content stops about 72% of the way down its own picture, and the shared
   16:8.6 window shows 86% of it and then pans further. Cropped to what is actually drawn, the
   pan stays inside the console instead of travelling into empty canvas. */
#relay .frame-window{aspect-ratio:16/7.2}
#relay .frame-window img{--w-from:0px;--w-to:-22px}

/* ---------------- the ingest ledger ----------------
   Real markup, not a picture of another screen: no honest screenshot of this family exists, and
   a borrowed one would be a claim we cannot support. Labelled as sample data on its face. */
.cap-wipe{display:flex}
.cap-ledger{flex:1 1 auto;display:flex;flex-direction:column;padding:0;background:var(--surface)}
.cap-ledger-head,.cap-board-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:16px;padding:20px 24px 16px;border-bottom:1px solid var(--line)}
.cap-ledger-k{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text)}
.cap-ledger-d{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim)}
.cap-ledger-rows{flex:1 1 auto;display:flex;flex-direction:column}
.cap-row{flex:1 1 auto;display:flex;flex-direction:column;gap:8px;padding:20px 24px 22px}
.cap-row+.cap-row{border-top:1px solid var(--line)}
.cap-row dt{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim)}
.cap-row dd{display:flex;flex-direction:column;gap:7px;color:var(--text);font-size:15.5px;
  line-height:1.35;letter-spacing:-.01em;word-break:break-word}
.cap-row code{font-family:var(--mono);font-size:14px;letter-spacing:.02em;color:var(--blue)}
.cap-row-n{color:var(--muted);font-size:13.5px;line-height:1.5;letter-spacing:normal}

/* ---------------- the photo board ----------------
   The photo module's first-run state is empty, so the evidence here is the family's own
   vocabulary in real markup, labelled the same way. */
.cap-board{padding:0;background:var(--surface)}
.cap-board-cols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
  background:var(--line)}
.cap-col{background:var(--surface);padding:20px 22px 24px;display:flex;flex-direction:column;gap:12px;
  min-width:0}
.cap-col-h{font-family:var(--mono);font-size:10.5px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--dim)}
.cap-tile{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;
  padding:14px 15px;display:flex;flex-direction:column;gap:7px;min-width:0}
.cap-tile b{font-size:14.5px;font-weight:600;letter-spacing:-.015em;line-height:1.3;
  color:var(--text);word-break:break-word}
/* --dim on --surface-2 measures 4.33:1, and .cap-tile span outranked the .cap-state rule that was
   meant to lift it, so every state label in this board sat under AA. The ink is lifted here rather
   than the tile ground, and the two state colours are restated at the same weight so they win. */
.cap-tile span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:#838D9B}
.cap-tile .cap-state{color:#9AA5B2}
.cap-tile .cap-state-ok{color:var(--blue)}
.cap-tile-empty{background:transparent;border-style:dashed}

/* ---------------- the peak ----------------
   Four agreements, one per line, arriving in the same place under a held heading. */
.fit-stage{display:flex;flex-direction:column;justify-content:center;background:var(--ink);
  padding:calc(var(--nav-h) + var(--nav-inset) + 26px) 0 46px}
.fit-stage .act-mark{margin-bottom:0}
.fit-stage .act-in{margin-top:17px}
.fit-stage .head{margin-top:0}
.fit-stage .head .display{font-size:clamp(30px,3.6vw,50px);margin-top:0}
.fit-lines{margin-top:40px;max-width:1000px;margin-left:auto;margin-right:auto}
.line{font-size:clamp(21px,2.5vw,34px);line-height:1.2;letter-spacing:-.025em;font-weight:500;
  color:var(--text);text-align:center;text-wrap:balance;padding:22px 0;
  border-top:1px solid var(--line)}
.line:first-child{border-top:0;padding-top:0}
.fit-stage .inline-cta{margin-top:32px}
/* Stacked in one box, not down a column. Four lines crossing over in the same place is the
   beat; four rows lit one at a time marches the reader's eye down the screen and leaves a hole
   above whichever one is lit. The hairline column is the static layout, and it comes back
   whenever the stage is not actually pinned (no script, ?static=1, a capture tool). */
.fit-stage.sc-stage .fit-lines{position:relative;min-height:clamp(112px,19vh,180px)}
/* Centred with the `translate` property, not with flex and not with `transform`. Flex turns each
   run of text into its own anonymous item and a sentence comes apart; transform is what the
   engine writes on a cue element. */
.fit-stage.sc-stage .line{position:absolute;left:0;right:0;top:50%;translate:0 -50%;
  margin:0;padding:0;border-top:0}

/* ---------------- the close ----------------
   The hero's own picture again, so the last screen shows what the first one promised. */
/* clip, not hidden: see the note on .hero-stage. */
.sec-closer{border-top:1px solid var(--line);padding-bottom:0;overflow:clip}
.closer-stage{display:flex;flex-direction:column;background:var(--ink);
  padding:calc(var(--nav-h) + var(--nav-inset) + 24px) 0 0}
.closer-in{max-width:820px;margin:0 auto;text-align:center;display:flex;flex-direction:column;align-items:center}
.closer-in .display{margin-top:22px}
.closer-stage .closer-in .display{font-size:clamp(30px,3.4vw,50px)}
.closer-in .lead{margin-top:20px;text-align:center;margin-left:auto;margin-right:auto}
.closer-in .inline-cta{margin-top:32px}
.stage-closer{position:relative;max-width:900px;margin:56px auto 0;perspective:1500px}
/* The window's bottom edge is the page's edge: the footer's own hairline sits on it. A gradient
   that is still translucent when it gets there cuts the console through whatever row happens to be
   under it, and a screenshot cut mid-row reads as a rendering fault rather than as a crop. So the
   fade reaches solid ground well before the edge and holds it: whatever the console is showing,
   the cut lands on ink. */
.stage-closer::after{content:"";position:absolute;left:0;right:0;bottom:0;height:38%;z-index:3;
  pointer-events:none;background:linear-gradient(180deg,transparent,rgba(11,15,20,.62) 34%,var(--ink) 67%,var(--ink))}
.closer-stage .stage-closer{margin-top:auto;max-width:820px;padding-top:34px}
/* The frame is cut by the bottom of the stage rather than by its own fade, so the fade moves to
   the stage edge; otherwise the window ends on a hard line. */
.closer-stage.sc-stage .stage-closer::after{display:none}
/* The fade has to reach solid ink on the gutter BETWEEN two card rows, not part way through
   one: a console that dims out half way down a row of thumbnails reads as a rendering fault,
   and a fade still translucent at the footer's hairline is the guillotine the crop was meant
   to avoid. The stops below are this console's own row boundaries. */
.closer-stage.sc-stage::after{content:"";position:absolute;left:0;right:0;bottom:0;height:26%;
  z-index:3;pointer-events:none;
  background:linear-gradient(180deg,transparent 66%,var(--ink) 73%,var(--ink))}
.closer-lift{
  --l:clamp(0,calc(var(--sc-p,1) / .6),1);
  transform-origin:50% 100%;
  transform:rotateX(calc((1 - var(--l)) * 9deg))
            scale(calc(.96 + .04 * var(--l)))
            translate3d(0,calc((1 - var(--l)) * 40px),0)}

/* ---------------- the landing ----------------
   A greet cue is already at full opacity when the act begins, so the engine has nothing to
   animate on the one screen every visitor sees. One CSS animation, played once, gives the hero
   its arrival; animation-fill-mode is backwards only, so the engine's inline values take over
   the instant it ends and scroll owns the element from then on. */
@keyframes cap-rise{from{opacity:0;transform:translate3d(0,112%,0)}}
@keyframes cap-greet{from{opacity:0;transform:translate3d(0,14px,0)}}
@media(prefers-reduced-motion:no-preference){
  .hero h1 .sc-split__i{animation:cap-rise 980ms var(--ease-out) backwards}
  .hero h1 .sc-split--line:nth-child(2) .sc-split__i{animation-delay:100ms}
  .hero-in>[data-sc-cue]{animation:cap-greet 720ms var(--ease-out) backwards}
  .hero-in>h1[data-sc-cue]{animation:none}
  .hero-in>.chip{animation-delay:40ms}
  .hero-in>.hero-lead{animation-delay:380ms}
  .hero-in>.hero-cta{animation-delay:480ms}
  /* The index arrives as one object: the rows are the ground, and the words inside them are
     already owned by their own cues. Animating each row would double the first word's fade. */
  .cap-index ol{animation:cap-greet 720ms var(--ease-out) backwards;animation-delay:540ms}
}

/* If the script never runs, or a capture tool asks for the static page, nothing may stay
   invisible and nothing may sit mid-animation. folio.css covers the cues, reveals and staggers;
   these are this page's own moves. */
html.no-js .cap-bed-lift,html.hv-static .cap-bed-lift,
html.no-js .closer-lift,html.hv-static .closer-lift{transform:none}
html.no-js .frame-still .media,html.hv-static .frame-still .media{transform:none}
html.no-js .hero-in>[data-sc-cue],html.hv-static .hero-in>[data-sc-cue],
html.no-js .cap-index ol,html.hv-static .cap-index ol,
html.no-js .hero h1 .sc-split__i,html.hv-static .hero h1 .sc-split__i{animation:none}

/* ---------------- reduced motion ----------------
   Fewer and gentler, not zero: the engine keeps the opacity that carries comprehension and drops
   every position change. These are this page's own position changes. */
@media(prefers-reduced-motion:reduce){
  .cap-bed-lift,.closer-lift{transform:none}
  .frame-still .media{transform:none}
  .cap-i-w,.btn{transition:none}
  .hero h1 .sc-split__i{animation:none}
}

/* ---------------- responsive ---------------- */
@media(max-width:1120px){
  .cap-hero-grid{gap:40px}
  .rules.cap-rules-3{column-gap:24px}
}
@media(max-width:900px){
  /* The hero and the close are flow here, so their progress is not a pin's progress and the
     lift would arrive half resolved. The bed still pans. */
  .cap-bed-lift,.closer-lift{transform:none}
  /* One column, so the bed cannot sit behind the copy: the index runs the full width and the
     archive would print itself through the last three family names. Below 900px the hero is
     always demoted, so the flow rule above already has it standing under the copy. */
  .cap-hero-grid{grid-template-columns:1fr;gap:40px}
  .hero-in{align-items:flex-start}
  .hero h1{max-width:none}
  .rules.cap-rules-2{grid-template-columns:1fr;column-gap:0}
  .rules.cap-rules-2 li:nth-child(n+2){border-top:1px solid var(--line)}
  .rules.cap-rules-2 li:nth-last-child(-n+2){padding-bottom:20px}
  .rules.cap-rules-2 li:last-child{padding-bottom:0}
  .rules.cap-rules-3{grid-template-columns:1fr;column-gap:0;margin-top:38px}
  .rules.cap-rules-3 li{padding-bottom:20px}
  .rules.cap-rules-3 li+li{border-top:1px solid var(--line)}
  .rules.cap-rules-3 li:last-child{padding-bottom:0}
  .cap-board-cols{grid-template-columns:1fr}
}
@media(max-width:760px){
  .hero-stage{padding-top:calc(var(--nav-h) + var(--nav-inset) + 30px);padding-bottom:0}
  .hero h1{margin-top:16px}
  .hero-lead{margin-top:16px}
  .hero-cta{margin-top:24px;width:100%}
  .hero-cta .btn{width:100%;justify-content:center;min-height:48px}
  .cap-index li{gap:14px;padding:10px 0 11px}
  .cap-bed-frame{opacity:.42}
  .cap-panel{margin-top:34px;padding:22px 20px 24px;border-radius:16px}
  .cap-shot-search{--zoom:180%;--sx:-27%;--sy:-19%;--w-to:-62px}
  .cap-shot-review{--zoom:300%;--sx:-92%;--sy:-30%;--w-to:-22px}
  .cap-ledger-head,.cap-board-head{padding:16px 18px 14px}
  .cap-row{padding:16px 18px 18px}
  .cap-col{padding:16px 18px 20px}
  .fit-stage{padding:calc(var(--nav-h) + var(--nav-inset) + 16px) 0 30px}
  .fit-lines{margin-top:26px}
  .line{padding:14px 0;font-size:clamp(20px,5.2vw,26px)}
  .stage-closer{margin-top:36px}
  /* The closer's console on this page is the projects board, not the search results the shared
     phone crop in folio.css is tuned for. A 2.2x crop of a card grid frames a third of one card;
     1.2x frames two whole cards and both of their caption rows, which is what the claim is about. */
  .closer-stage .frame-still .media{--w-s:1.2;transform-origin:0 0}
  .closer-stage .frame-still img{object-position:29% 0}
  /* On a phone a whole 1600px console is unreadable at 335px: the closer frame crops to the
     column that carries the claim instead of shrinking the entire application to a smudge. */
  .closer-stage .stage-closer{padding-top:26px}
}


/* --- the phone crops for the three full consoles ---
   Each of these frames carries a phone source and, until now, showed the entire 1600px
   application at 350px, where every label renders at four or five pixels. Each one crops to the
   one region its claim is about: the bed to two shoot cards, the archive frame to the asset
   panel's own file and metadata block, relay to the team-computers table. See .frame-crop in
   folio.css for the mechanism. */
@media(max-width:760px){
  .cap-bed-frame{aspect-ratio:16/10;--zoom:290%;--sx:-46%;--sy:-29%;--w-from:0px;--w-to:-24px}
  .cap-crop-detail{aspect-ratio:4/3;--zoom:300%;--sx:-206%;--sy:-105%;--w-from:0px;--w-to:-46px}
  #relay .frame-window{aspect-ratio:4/3}
  .cap-crop-relay{--zoom:300%;--sx:-48%;--sy:-100%;--w-from:0px;--w-to:-26px}
  #relay .frame-window img{--w-from:0px;--w-to:-26px}
}

/* --- the seam when nothing is pinned ---
   A pinned section takes padding:0 and its stage carries a top pad whose only job is to clear the
   fixed nav pill while the stage is stuck under it. With nothing stuck that is not a seam, it is
   a leftover, and it put 154px of ground between the section above and the act's first line.
   In the static state the stage takes the page's own section rhythm instead. */
html.hv-static .fit-stage{padding:var(--sec-pad) 0}
/* The act half of the rule above: an unpinned hero is as tall as the hero, not as tall as a
   screen it no longer fills. .sc-act--pinned is the class the engine adds to a pinned act. */
.hero:not(.sc-act--pinned){min-height:0}

/* ---------------- type floors on a phone ----------------
   Body copy to 15.5px, mono captions to 11px, the fine print that carries the terms to 12px.
   folio.css sets the shared floors; these are the sizes this page authors itself. */
@media(max-width:760px){
  .cap-i-n,.cap-panel-k,.cap-ledger-k,.cap-ledger-d,.cap-row dt,.cap-col-h{font-size:11px}
  .cap-tile span{font-size:11px}
  .cap-row-n{font-size:15.5px}
  /* The index is the way into six sections, so each name is a real target on a phone. */
  .cap-i-w{min-height:44px;display:flex;align-items:center}
}
