/* ═══════════════════════════════════════════════════════════════════════
   THE CLIENT FLOW — Spec J, screen 1.

   INHERITED, NOT RE-AUTHORED. Every rule below comes from
   `AE_UpShot_FlowSpecimen_v6_2026-08-14.html`, the design of record ruled canon
   by Ten on 2026-08-15. Spec J §8's principle applied to the stylesheet: the
   specimen's frame wins, and nothing here is a fresh opinion about how the read
   should look. What IS different is that the specimen animates one hard-coded
   company with `setTimeout`, and this file dresses states a server resolved —
   so the transitions survive and the timeline does not.

   THIS FILE DOES NOT TOUCH `upside.css`. The console keeps its stylesheet
   exactly as certified; nothing about the retired surface is edited today.

   THE ONE RULE THAT OUTRANKS THE LOOK — J-3.3: legibility is never sacrificed
   to an effect. An earlier cut of the specimen lightened the ground across the
   whole read; it looked right in stills and failed in motion, because text on a
   ground travelling navy → white passes through a moment where it matches the
   ground. Timing cannot fix that — it only moves the dead spot. So the read
   stays in the darkroom for its whole length. There is no ground transition on
   this screen at all.
   ═══════════════════════════════════════════════════════════════════════ */

/* THE TWO TOKENS THIS SHEET SETS FROM THE SERVER, declared here with their
   defaults so they RESOLVE.

   `--p` (the progress bar's fill) and `--cols` (how many columns an agent card
   opens onto) are written per-element as inline styles, because both are facts
   the route computed. Declaring them anyway is not ceremony: the S23 token port
   asserts that every token a stylesheet names resolves to a definition,
   precisely because a mistyped one fails SILENTLY — it is not an error, it is
   an empty string, which is the whole problem with it. Undeclared, these two
   read as typos to that guard and as nothing at all to a browser that never
   received the inline style.

   (The guard reads comments as well as rules, so this note deliberately
   describes tokens rather than spelling any — naming an example would have
   invented two more undefined ones.) */
/* ── THE SPEC J PALETTE — declared HERE, and why here rather than in upside.css.
   
   THIS BLOCK IS THE ONLY PLACE IN THIS FILE THAT HOLDS A RAW VALUE. Everything
   below it references these tokens, which is the same discipline upside.css
   keeps for the console.

   The first attempt put these in a `CAL ADDITIONS (g)` block inside upside.css,
   because AE_M3_Conventions 1.2 makes that file the single source of design
   truth. Source-verify check 4 caught it: both addition groups are asserted
   TOKEN-ONLY, zero new raw values, and Hub verified that promise at S2. A new
   PALETTE cannot be expressed as a reuse of existing tokens -- the specimen's
   darkroom navy is #0A1A2C and the console's is #1B2A4A, and flattening one
   into the other would re-author the design of record, which Spec J §8
   forbids in both directions.

   PROVISIONAL -- HUB TO RULE. Spec J §1 makes the client surface a second
   product for a second audience, so it has a second palette; this file is its
   canon the way upside.css is the console's. `design_lint` is told about it in
   ONE constant, so reversing this ruling is a one-line change. The alternative
   Hub may prefer -- extending the conventions doc to name two canons -- is a
   documentation change this session had no authority to make.
   ──────────────────────────────────────────────────────────────────────── */
:root{
  /* the darkroom, and the paper it develops onto */
  --j-navy:#0A1A2C;        /* the read's ground, start to finish */
  --j-brand:#0E2A47;       /* the report's structural navy */
  --j-accent:#5B8FA8;      /* the one continuous motion, and every link */
  --j-ink:#131722;
  --j-ink-2:#2A3242;
  --j-slate:#5B6577;
  --j-slate-2:#7A8494;
  --j-surface:#FFFFFF;
  --j-white:#fff;
  --j-muted:#F7F8FA;
  --j-hair:#DFE3E9;
  --j-sunk:#EFF1F4;
  --j-logo:#1F2A37;
  /* the uplift ramp, as the specimen draws it */
  --j-band-a:#14532D;
  --j-band-b:#3F6212;
  /* A read that stopped says so in the failure colour, and NOTHING else on
     this surface uses it. S30 found that every success on the console rendered
     in the error palette, which is why this is a single-purpose token rather
     than a general "notice" colour. */
  --j-stop-ink:#F3C9C4;
  /* S44 Item 2 · THE HEARTBEAT'S THREE STATES, from the liveness prototype.
     A THIRD single-purpose set, declared for the same reason `--j-stop-ink`
     is: these three say "the reader is alive / late / gone" and NOTHING else
     on this surface may borrow them. The whole argument of the band is that
     its appearance changes when the truth does, so a colour shared with a
     decorative element is a colour that can be changed for a decorative
     reason. */
  --j-beat-ok:#6FBF9B;
  --j-beat-late:#E8B36A;
  --j-beat-gone:#E58A80;
  /* radii the specimen uses that the console ramp has no step for */
  --jr-xs:4px; --jr-sm:8px; --jr-reg:9px; --jr-xl:11px; --jr-md:10px; --jr-lg:12px; --jr-pill:20px;
  /* S41 §3 · the door modal's own two values, declared here because
     `design_lint` is right that a raw hex or radius below this block is a
     second canon starting. The card corner is larger than any step the
     ramp has, and the button's ink is the near-black the specimen sets on
     the accent so the call to action reads at AA against it. */
  --jr-modal:18px;
  --j-cta-ink:#062033;
  /* the live way-on lifting off the bar */
  --j-lift:0 6px 24px rgba(0,0,0,.3);
  /* S41 §3 · the modal sits ABOVE the page rather than on it, so its
     shadow is deeper than the way-on's lift; and the button's hover glow
     is the accent's own. Declared here because a shadow below this block
     is a second canon starting, exactly as a hex would be. */
  --j-modal-lift:0 34px 100px rgba(0,0,0,.55);
  --j-cta-glow:0 10px 26px rgba(91,143,168,.32);
  /* S44 Item 1 · THE SHEET ON A DESK. The report is a document lying on a
     surface, not a website filling a window, and the shadow is what says so.
     Shallower than every other shadow on this sheet on purpose: the way-on
     LIFTS off the bar and the modal sits ABOVE the page, but a sheet of paper
     rests ON the desk. Declared here rather than written at `.paper` for the
     reason the two blocks above give -- a shadow below this block is a second
     canon starting, and `design_lint` rejects a literal `box-shadow` outside
     a canon. Hub's directive specifies this VALUE; only its name is mine. */
  --j-sheet:0 1px 3px rgba(15,32,53,.08);
  /* ⚠ THE TYPEFACE, DECLARED HERE, AND IT MUST BE.
     This sheet briefly named the CONSOLE's sans token — one that lives in
     `upside.css`, a file THIS SURFACE NEVER LOADS. An undefined token is not an
     error; it is an empty string. So `font-family:` resolved to nothing and
     every screen of the client flow rendered in the browser's default SERIF.

     The S23 token port did not catch it because it pools token DEFINITIONS
     across every stylesheet in the repo and then asks whether a name is defined
     SOMEWHERE — which it was. A canon is only a canon for the surface that
     loads it. That is Hub's doctrine #5 (a gate's scope is a claim like any
     other) landing for the third time in two days, and it is now guarded by a
     test that resolves this file's tokens against THIS FILE ALONE.

     That is the S29 defect exactly, one week later: every client artifact for
     nineteen sessions was set in Times because a generated CSS block reached
     the browser invalid, the markup was perfect throughout, and no string
     assertion could see it. This one survived a green 71-test suite and a
     contact sheet whose colour counts all PASSED — a serif page has plenty of
     colours. It was caught by LOOKING at the picture.

     A canon declares every value the surface it dresses needs. This one needs
     a typeface. */
  --j-sans:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,
    'Helvetica Neue',Arial,sans-serif;
  /* set per-element by the route -- see the note below */
  --p:0%; --cols:3;
}

*{margin:0;padding:0;box-sizing:border-box}
body.flow{font-family:var(--j-sans);color:var(--j-ink);font-size:16px;
  line-height:1.55;background:var(--j-navy)}

/* ── THE MARK ──────────────────────────────────────────────────────────
   ONE asset, not two: every stroke is drawn in `currentColor`, so the mark
   takes the colour of whatever it sits in. A second file would be a second
   thing to keep in step, and this lane has paid for two-authored truths four
   times over. */
.upmark{display:inline-flex;align-items:center;gap:8px;line-height:1}
.upmark svg{display:block;flex:none}
.upword{font-size:14.5px;font-weight:700;letter-spacing:.005em}
.upword em{font-style:normal;opacity:.62}
.on-dark{color:rgba(255,255,255,.9)}
.brandrow{padding:14px 32px 0;flex:none}

/* ═══ THE ASK ══════════════════════════════════════════════════════════ */
.ask{min-height:100vh;display:flex;flex-direction:column;justify-content:center;
  align-items:center;text-align:center;padding:30px 40px}
.ask .brandrow{position:absolute;top:0;left:0}
.ask h1{font-size:clamp(32px,4.9vw,54px);line-height:1.06;font-weight:700;
  letter-spacing:-.028em;color:var(--j-white);max-width:16ch;margin-bottom:16px}
.ask .lede{font-size:17px;line-height:1.6;color:rgba(255,255,255,.62);
  max-width:50ch;margin-bottom:30px}

/* THE PROOF STRIP. The number motivates; the line beneath it keeps the number
   honest, and it is deliberately close enough that you cannot read one without
   the other. It renders ONLY over a real prior read — see `flow_ask.html`. */
.proof{border:1px solid rgba(91,143,168,.34);background:rgba(91,143,168,.08);
  border-radius:var(--jr-lg);padding:16px 26px;margin-bottom:32px;max-width:60ch}
.proof .fig{font-size:clamp(23px,3.1vw,32px);font-weight:800;color:var(--j-white);
  letter-spacing:-.022em;font-variant-numeric:tabular-nums;line-height:1.15}
.proof .fig .per{font-size:15px;color:rgba(255,255,255,.55);font-weight:600}
.proof .src{font-size:12.5px;color:rgba(255,255,255,.52);margin-top:6px;
  line-height:1.5}
.proof .src b{color:rgba(255,255,255,.78);font-weight:600}

/* S46 ITEM 1 . THE ROW THAT COULD NOT BECOME TWO ROWS.
   Measured at 390: website 234 + invite 150 + button 209 + two gaps = 653
   in a 310px container, and `display:flex` with no `flex-wrap` has no
   width at which that stops being one row. 653 does not fit the 520 here
   either, so on a wide public bind the items already spilled out of their
   own container -- which is why the wrap is not inside a media query. */
.field{display:flex;flex-wrap:wrap;gap:10px;width:100%;max-width:520px}
/* ⚠ `min-width:0` IS THE HALF THAT MAKES `flex:1` MEAN ANYTHING HERE. A
   flex item's min-width defaults to `auto` -- its CONTENT minimum -- and
   for a text input that is its default `size`, about twenty characters.
   `flex:1` was asking it to grow; nothing was letting it shrink. */
.field input{flex:1 1 200px;min-width:0;background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.22);border-radius:var(--jr-reg);padding:15px 19px;
  font-size:16.5px;color:var(--j-white);font-family:inherit;
  transition:border-color .2s,background .2s}
/* F2's invite field. These three values came off the tag's `style`
   attribute UNCHANGED: an inline style cannot be overridden by a media
   query, and this one has to widen on a phone. Moved, not re-decided. */
.field .invite{flex:0 1 150px;max-width:150px;text-align:center;
  letter-spacing:.06em}
.field input:focus{outline:none;border-color:var(--j-accent);
  background:rgba(255,255,255,.1)}
.field button{background:var(--j-white);color:var(--j-navy);border:none;border-radius:var(--jr-reg);
  padding:15px 27px;font-size:16px;font-weight:700;font-family:inherit;
  cursor:pointer;white-space:nowrap;transition:transform .12s ease}
.field button{flex:0 0 auto}
.field button:hover{transform:translateY(-1px)}
/* BELOW 760 IT IS A COLUMN, NOT A WRAPPED ROW. Wrapping alone would put a
   234px input beside a 150px invite on a 310px line; a form on a phone is
   one field per line. 760 and not 720 because the row needs 733px of
   VIEWPORT to fit on a public bind -- the column must start above the
   width at which the row breaks, not at it. */
@media (max-width:760px){
  .field{flex-direction:column;align-items:stretch}
  /* ⚠ `flex-basis` IS THE MAIN AXIS, AND THE MAIN AXIS JUST BECAME HEIGHT.
     `flex:1 1 200px` in a column asks for a 200px-TALL input and then grows
     it -- the first cut of this rule shipped a text box the size of a
     textarea, and the picture is the only thing that said so. In a column
     each control is its own height and nothing flexes. */
  .field input,.field .invite,.field button{flex:0 0 auto}
  .field .invite{max-width:none}
  .field button{width:100%}
}
.reassure{margin-top:20px;font-size:13px;color:rgba(255,255,255,.38)}

/* F2 — the invite gate. The specimen left a dashed slot here reading "reserved
   for whatever you rule gates a press". Hub ruled it: an invite code, because a
   public field spends real money on every press and we have no abuse control.
   It is a real field now, not a slot. */
.gate{margin-top:22px;display:flex;gap:10px;align-items:center;
  width:100%;max-width:520px}
.gate input{flex:1;background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.18);border-radius:var(--jr-sm);padding:11px 15px;
  font-size:14px;color:var(--j-white);font-family:inherit;text-align:center;
  letter-spacing:.06em}
.gate input:focus{outline:none;border-color:var(--j-accent)}
.gate .lab{font-size:11.5px;color:rgba(255,255,255,.34);white-space:nowrap}
.refused{margin-top:18px;border:1px solid rgba(192,57,43,.5);
  background:rgba(192,57,43,.12);border-radius:var(--jr-sm);padding:10px 16px;
  font-size:13.5px;color:var(--j-stop-ink);max-width:54ch}

/* E2E-1 — THE PROPOSAL. A state of the ask, not a fourth screen (Spec J §2),
   so it sits inside the same section and inherits its type and its ground.

   Each choice is its own form and its own button, deliberately: a radio group
   plus a submit is two presses to agree to one sentence, and the thing being
   agreed to IS the sentence. The NAICS code rides hidden — a stranger is shown
   words and never a census code (R-ADVANCED-1).

   Quieter than `.field button`, which is the one press this screen is FOR: a
   proposal that shouted louder than the Snapshot press would make the detour
   look like the destination. */
.proposal{margin-top:22px;width:100%;max-width:520px;display:flex;
  flex-direction:column;gap:9px}
.proposal .pq{font-size:14px;color:rgba(255,255,255,.62);margin-bottom:2px}
.proposal .pchoice{display:block}
.proposal .pchoice button{width:100%;text-align:left;cursor:pointer;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.18);
  border-radius:var(--jr-sm);padding:12px 16px;font-size:14.5px;
  line-height:1.45;color:var(--j-white);font-family:inherit}
.proposal .pchoice button:hover{border-color:var(--j-accent);
  background:rgba(255,255,255,.09)}
.proposal .pnone{font-size:12.5px;color:rgba(255,255,255,.38);margin-top:2px}
/* ── R-LIVE-3 · A PRESS IN FLIGHT SAYS SO, AND CANNOT BE MADE TWICE ───────
   Ten pressed this door TEN TIMES IN FIFTY SECONDS on 2026-08-17 because each
   press thought for five to eight seconds in silence. `door_entries` rows 1-9
   are the measurement. The guard that disables the controls is on the page
   that owns them; this is the half of it the client can see.

   `flowbeat` is REUSED, not re-authored. It is already this surface's one
   motion primitive — the source being read now — and a second pulse with its
   own timing would be a second vocabulary for "something is happening". The
   read screen's "exactly one continuous motion" rule is untouched: that rule
   governs the READ, and this beat only ever runs on the ask.

   The pressed control keeps full strength and beats; the others recede. So
   the screen says WHICH press is in flight rather than only that it has gone
   inert — which matters most on the proposal, where the choices are separate
   forms and the client needs to see the sentence they actually agreed to. */
.ask button[type="submit"]:disabled{opacity:.45;cursor:default;transition:opacity .15s}
.ask .field button:disabled:hover{transform:none}
.ask .proposal .pchoice button:disabled:hover{border-color:rgba(255,255,255,.18);
  background:rgba(255,255,255,.06)}
.ask button[type="submit"].working{opacity:1;animation:flowbeat 1.6s ease-in-out infinite}


/* ═══ THE READ — ONE FIXED FRAME, never scrolls ════════════════════════ */
.read{display:flex;flex-direction:column;height:100vh;padding:18px 32px 0;
  max-width:1280px;margin:0 auto}
/* R-MARK-1 · the one provisional mark this surface carries. Quiet, above the
   fold, and NOT repeated: a marker that repeats down a column stops being read,
   which is what twelve of them proved. */
.surface-mark{font-size:11px;color:rgba(255,255,255,.42);letter-spacing:.02em;
  padding-bottom:10px}
.dev-head{display:flex;align-items:center;gap:14px;flex:none;padding-bottom:12px}
.logo{width:42px;height:42px;border-radius:var(--jr-md);background:var(--j-logo);color:var(--j-white);
  display:flex;align-items:center;justify-content:center;font-weight:800;
  font-size:17px;flex:none}
.dev-name{font-size:clamp(22px,2.8vw,31px);font-weight:700;
  letter-spacing:-.024em;line-height:1.12;color:var(--j-white)}
.dev-sub{font-size:12.5px;color:rgba(255,255,255,.45);margin-top:2px}
/* R-NAME-1 · the derived-name mark on the read screen. Same restraint as
   `.cover .nmark`; sized against this screen's much larger name. */
.dev-mark{font-size:12px;color:rgba(255,255,255,.5);margin-top:4px;max-width:52ch;
  line-height:1.45}

.stage{flex:1;display:grid;grid-template-columns:1fr 300px;gap:24px;min-height:0}
.col-main{min-width:0;display:flex;flex-direction:column;overflow:hidden}

.naics{display:flex;align-items:center;gap:12px;flex-wrap:wrap;flex:none;
  border:1px solid rgba(91,143,168,.38);background:rgba(91,143,168,.09);
  border-radius:var(--jr-reg);padding:10px 15px;margin-bottom:12px}
.naics .txt{font-size:14px;color:var(--j-white);flex:1;min-width:230px}

/* ── J-3.2 · AN EMPTY FRAME IS A HAIRLINE AND NOTHING ELSE ────────────
   Never a filled grey slab. That is the loading-skeleton cliché and it reads
   as software waiting rather than as a picture arriving. `.cell` with no
   `.filled` IS the empty frame: a 1px border at 9% white on the dark ground,
   holding the exact place and size the fact will occupy. */
.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;
  margin-bottom:14px;flex:none}
.cell{border:1px solid rgba(255,255,255,.09);border-radius:var(--jr-md);padding:11px 13px;
  background:transparent;min-height:82px;
  transition:border-color .8s ease,background-color .8s ease}
.cell.filled{border-color:transparent;background:var(--j-surface)}
.cell .k{font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;
  font-weight:700;color:var(--j-slate)}
.cell .v{font-size:15.5px;font-weight:700;color:var(--j-brand);margin-top:3px;
  line-height:1.26;letter-spacing:-.01em}
.cell .s{font-size:10.5px;color:var(--j-slate);margin-top:2px;line-height:1.38}

.sec-label{font-size:10px;letter-spacing:.13em;text-transform:uppercase;
  font-weight:700;color:rgba(255,255,255,.42);margin-bottom:8px;flex:none;
  display:flex;justify-content:space-between;align-items:baseline}

/* The GROUP takes the leftover height and centres inside it; the LIST stays
   tight. Space goes around the block, never between its rows — spreading rows
   apart fills the frame but breaks a list into unrelated objects. */
.rivalgroup{flex:1;display:flex;flex-direction:column;justify-content:center;
  min-height:0;overflow:hidden}
.rivals{display:flex;flex-direction:column;gap:6px}
.rival{border:1px solid rgba(255,255,255,.08);
  border-left:3px solid rgba(91,143,168,.2);border-radius:var(--jr-sm);padding:8px 12px;
  background:transparent;min-height:38px;
  transition:border-color .8s ease,background-color .8s ease}
.rival.filled{border-color:transparent;border-left-color:var(--j-accent);
  background:var(--j-surface)}
.rrow{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.rival .n{font-size:13.5px;font-weight:700;color:var(--j-ink);flex:none}
.rival .w{font-size:11.5px;color:var(--j-slate);line-height:1.4}

/* ── THE SOURCE TICKER — numbered, ascending, and it STAYS ────────────
   J-3.4: what we read is the argument, not a loading animation. Read sources
   grey out rather than disappearing, and the result count rises ABOVE the list
   rather than replacing it. */
.col-rail{border-left:1px solid rgba(255,255,255,.11);padding-left:20px;
  display:flex;flex-direction:column;min-height:0}
.rail-h{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  font-weight:700;color:rgba(255,255,255,.4);margin-bottom:9px;flex:none;
  display:flex;justify-content:space-between;align-items:baseline}
.rail-h .ct{color:rgba(255,255,255,.3);letter-spacing:.04em}

/* R-EMPTY-2 — the footprint reading, on the rail rather than over the facts.
   Quiet by construction: it is context for the source list it sits above, not
   a verdict on the business. It was a banner in `empty`'s palette until S35,
   which is how it came to be printed over $3.7B in reported net sales. */
.railnote{flex:none;margin-bottom:14px;padding-bottom:12px;
  border-bottom:1px solid rgba(255,255,255,.12)}
.railnote .rn-h{font-size:11.5px;font-weight:700;color:rgba(255,255,255,.62);
  margin-bottom:5px}
.railnote .rn-b{font-size:11.5px;line-height:1.5;color:rgba(255,255,255,.44)}

.found{flex:none;margin-bottom:14px}
.found .num{font-size:clamp(40px,5.4vw,60px);font-weight:800;
  letter-spacing:-.035em;color:var(--j-white);line-height:1;
  font-variant-numeric:tabular-nums}
.found .cap{font-size:13px;color:rgba(255,255,255,.62);margin-top:6px;
  line-height:1.45}
.found .prov{font-size:11px;color:rgba(255,255,255,.36);margin-top:10px;
  padding-top:9px;border-top:1px solid rgba(255,255,255,.12)}

.ticker{flex:1;overflow:hidden;min-height:0}
.tick{display:flex;align-items:baseline;gap:9px;min-height:29px}
.tick .no{font-size:10.5px;font-weight:700;color:rgba(255,255,255,.28);
  font-variant-numeric:tabular-nums;flex:none;width:17px;letter-spacing:.02em}
.tick .tn{font-size:12.5px;color:rgba(255,255,255,.42);line-height:1.3}
/* a source that was reached and refused is still part of the argument, and it
   says which it was rather than sitting silently in the same grey. */
.tick.skipped .tn{color:rgba(255,255,255,.3)}
.tick.skipped .tn i{font-style:normal;color:rgba(255,255,255,.22)}
/* exactly one continuous motion on this screen: the source being read now */
.tick.live .no{color:var(--j-accent)}
.tick.live .tn{color:var(--j-white);font-weight:600}
.tick.live .no::after{content:"";display:inline-block;width:5px;height:5px;
  border-radius:50%;background:var(--j-accent);margin-left:4px;
  vertical-align:middle;animation:flowbeat 1.6s ease-in-out infinite}
@keyframes flowbeat{0%,100%{opacity:1}50%{opacity:.25}}
/* R-RAIL-1 · the row that says what the frame did not show. Quieter than a
   source, because it is an account of the list and not a member of it. */
.tick.more .no{color:var(--j-accent);opacity:.75}
.tick.more .tn{color:rgba(255,255,255,.34);font-style:italic}


/* ── THE PERSISTENT BAR — status, honest progress, the way forward ────
   J-3.5: the forward affordance is on screen from the first second, present
   but not live. The answer to "where am I going" precedes there being anywhere
   to go. `--p` is only ever set from a real fraction (J-3.1). */
.bar{flex:none;border-top:1px solid rgba(255,255,255,.12);margin-top:12px;
  padding:12px 0 15px;display:flex;align-items:center;gap:20px;position:relative}
.bar::before{content:"";position:absolute;top:-1px;left:0;height:2px;
  width:var(--p,0%);background:var(--j-accent);
  transition:width .6s cubic-bezier(.2,.7,.3,1)}
/* R-LIVE-7 · THE FILL COMES OFF THE RUNNING SCREEN.
   `display:none`, NOT `width:0`. A zero-width fill is still a rendered
   element with a transition attached, and the ruling is that during a read
   there is no bar at all - not a bar reading zero, which is its own false
   statement about a read that is doing plenty.
   The fraction was never wrong. Its DENOMINATOR is source families, and
   families are exhausted long before the read is, so a true statement about
   families sat on a screen where the reader was asking about the read. It
   returns on the settled screen, where the ratio summarises what was
   actually reached. */
.bar.nofill::before{display:none}
.bar .st{font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:700;color:var(--j-accent);flex:1;min-width:0}
.bar .counts{font-size:12px;color:rgba(255,255,255,.45);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.bar .counts b{color:rgba(255,255,255,.8);font-weight:700}
/* ── S36 ITEM 3 · THE PHASE THAT HAD NO ACCOUNT — R-LIVE-4 ────────────────
   A name and an elapsed time, sitting between the status and the counts.

   NO FILL, NO RATE, NO BAR (R-LIVE-5). Sources have a denominator and
   generation does not, so the only honest thing this can show is what is
   happening and how long it has been happening. The elapsed figure takes the
   accent — the one colour this surface uses for the thing moving now — and
   tabular numerals so a digit changing does not shift the line. */
.bar .phase{font-size:12px;color:rgba(255,255,255,.5);white-space:nowrap;
  flex:none}
.bar .phase .el{color:var(--j-accent);font-weight:700;margin-left:7px;
  font-variant-numeric:tabular-nums}

.bar .go{background:rgba(255,255,255,.09);color:rgba(255,255,255,.4);
  border:1px solid rgba(255,255,255,.16);border-radius:var(--jr-reg);padding:12px 24px;
  font-size:14.5px;font-weight:700;font-family:inherit;white-space:nowrap;
  cursor:not-allowed;text-decoration:none;display:inline-block;
  transition:background .5s ease,color .5s ease,border-color .5s ease,
    transform .12s ease,box-shadow .5s ease}
.bar .go.live{background:var(--j-white);color:var(--j-navy);border-color:var(--j-white);
  cursor:pointer;box-shadow:var(--j-lift)}
.bar .go.live:hover{transform:translateY(-2px)}

/* ── THE STOPPED AND EMPTY STATES ─────────────────────────────────────
   J-3.6: every state has an exit. A press that ends says so. These two are
   the states a product is tempted to leave as a dead end, so they get the
   same persistent bar and the same way forward as the other two — the only
   difference is what the way forward honestly promises. */
.saidso{flex:none;border-radius:var(--jr-reg);padding:11px 16px;margin-bottom:12px;
  font-size:13.5px;line-height:1.5}
.saidso.stopped{border:1px solid rgba(192,57,43,.45);
  background:rgba(192,57,43,.12);color:var(--j-stop-ink)}
.saidso.empty{border:1px solid rgba(91,143,168,.38);
  background:rgba(91,143,168,.09);color:rgba(255,255,255,.78)}
.saidso b{color:var(--j-white);font-weight:700}

@media (max-width:900px){
  .stage{grid-template-columns:1fr;gap:16px}
  .read{height:auto;min-height:100vh}
  .grid{grid-template-columns:repeat(2,1fr)}
}

/* ═══════════════════════════════════════════════════════════════════════
   SCREEN 2 — YOUR UPSHOT.

   The page turns to paper HERE, and only here. J-3.3: the read stays in the
   darkroom for its whole length, because text on a ground travelling navy to
   white passes through a moment where it matches the ground, and timing cannot
   fix that — it only moves the dead spot. So this is a different DOCUMENT
   rather than a transition, and there is nothing to get caught inside.

   Spec J §8, the convergence ruling, IS these rules: the type scale, the
   arithmetic disclosure, the source and depth discipline and the competitor
   treatment come from the review-certified S29 artifact; the AGENT FRAME, the
   Why/What/How anatomy, the TYPICAL chip, the per-agent questions and the close
   on The UpShot come from the v6 specimen. Neither is re-authored. Where they
   disagree, the artifact's honesty behaviour wins and the specimen's frame
   wins.
   ═══════════════════════════════════════════════════════════════════════ */

body.flow-upshot{background:var(--j-muted);color:var(--j-ink)}
/* S44 Item 1 · THE GUTTER, TAKEN BACK FROM THE SPECIMEN.
   This sheet had drifted to 1440px with ZERO horizontal padding, so at any
   viewport at or under 1440 the navy masthead bled to both edges of the
   browser. The v13 specimen -- which R-PIXEL-1 makes the spec -- is 1060px
   with a 40px gutter, and those are its numbers, not new ones.

   ⚠ THIS RULE REACHES THE FLOW PAGE AND NOTHING ELSE. The operator's
   in-place report, Present and Export are `srcdoc` iframes fed by
   `client_artifact.client_artifact_html`, which renders `artifact.html` --
   a self-contained document carrying its own `<style>`. Present CANNOT gain
   a margin from this change because it never loads this file. Shot at three
   widths anyway: the claim is cheap and a picture is what settles it. */
/* S46 ITEM 0 (Hub, R-PIXEL-1) . ONE GUTTER, AND IT MOVES INSIDE.
   The measure stays here; the padding does not. `.paper` now fills the
   1060 and every block inside it carries `var(--gut)` -- which is what
   the specimen does with `.wrap` inside a full-bleed masthead. Deleting
   `.pbody`'s 34 on its own would have left the navy bands inset and the
   body text flush: one gutter in name, two content columns in fact.

   v14 ADDENDUM (Ten, 2026-08-22): on large screens the sheet grows to
   1280 but KEEPS real margins. Below 1600px this is byte-identical
   geometry to v13, which is why the 1440 picture does not move. */
.upwrap{--gut:40px;max-width:1060px;margin:0 auto;padding:24px 0 40px}
@media (min-width:1600px){.upwrap{max-width:1280px}}
.paper{background:var(--j-surface);overflow:hidden;
  border-radius:var(--jr-md);box-shadow:var(--j-sheet)}
/* Below the sheet's width plus its two gutters the padding stops being a
   margin and starts being a bite out of the page. A rounded sheet on a phone
   is a sheet with wasted edges, so the corner goes square at the same breath. */
@media (max-width:720px){
  .upwrap{--gut:20px;padding:0}
  .paper{border-radius:0}
}
.cover{background:var(--j-brand);color:var(--j-white);padding:16px var(--gut,40px) 15px;display:flex;
  align-items:center;gap:16px;flex-wrap:wrap}
.cover .lg{width:34px;height:34px;border-radius:var(--jr-sm);background:var(--j-logo);flex:none;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px}
.cover h2{font-size:20px;font-weight:800;letter-spacing:-.015em;line-height:1.2}
.cover .nm{font-size:10px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  color:rgba(255,255,255,.5)}
/* R-NAME-1 · the derived-name mark. QUIETER THAN THE NAME ON PURPOSE: it is a
   note about the document, not a warning, and Hub's R-NOTICE-1 reasoning
   applies -- a shouted caveat on a prospect's own report reads as fear. It sits
   under the name rather than beside it so the masthead does not gain a column
   at narrow widths (the metadata-does-not-stack rule works the other way too:
   this is one line, and it stays one line). */
.cover .nmark{font-size:10.5px;font-weight:400;letter-spacing:0;text-transform:none;
  color:rgba(255,255,255,.52);margin-top:3px;max-width:52ch;line-height:1.45}
.cover p{font-size:12.5px;color:rgba(255,255,255,.66);flex:1;min-width:240px;
  line-height:1.5}
.accentbar{height:3px;background:var(--j-logo)}
/* R-NOTICE-1 · the persistent chrome band. One row, both notices, and QUIET --
   it is small print about the document, and it may not compete with the
   client's own content. `flex-wrap` so it stays one ROW on a desk and folds
   rather than truncating on a phone. */
.chrome-notice{display:flex;flex-wrap:wrap;gap:6px 18px;justify-content:space-between;
  padding:14px 34px 18px;font-size:11px;line-height:1.5;color:var(--j-slate-2);
  border-top:1px solid rgba(128,140,155,.22)}
/* ⚠ NOT `--gut`. `flow_base.html` renders this block OUTSIDE `.upwrap` on
   every client screen, where `--gut` is undefined -- and an undefined
   custom property does not fall back, it INVALIDATES THE DECLARATION and
   the padding becomes zero. It is page chrome below the sheet and has
   never aligned with it. */
@media (max-width:760px){.chrome-notice{padding:12px 22px 16px}}
/* S46 ITEM 0 . THE BODY IS NO LONGER A RAIL. It was `1fr 350px` down the
   entire page, which put the agent cards -- the thing the reader came
   for -- in 536px and left a column of white beside them. */
.pbody{padding:20px var(--gut,40px) 30px}
/* The specimen's `.top2`, at the specimen's numbers. The rests-on card
   sits BESIDE THE LEDE ONLY; everything below runs the full content
   width. `min-width:0` on the children because a grid track's default
   `auto` minimum is its content, and one long unbroken figure in the
   rail would otherwise push the column wider than its fraction. */
.top2{display:grid;grid-template-columns:1.45fr 1fr;gap:34px;
  align-items:start;margin-bottom:16px}
.top2>*{min-width:0}
/* NOT STICKY ANY MORE. Sticky was for a rail that ran the page; a column
   inside one section has nothing to travel past, and a sticky element
   taller than its container cannot pin in any case. */
.rside{display:flex;flex-direction:column;gap:12px}
.sec{padding-bottom:16px;margin-bottom:16px;border-bottom:1px solid var(--j-hair)}
.sec:last-child{border:none;margin:0;padding:0}
.sec h3{font-size:17px;font-weight:800;color:var(--j-brand);letter-spacing:-.01em;
  margin-bottom:9px}
.sidecard{border:1px solid var(--j-hair);border-radius:var(--jr-xl);padding:14px 16px;
  background:var(--j-muted)}
.sidecard h5{font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  font-weight:700;color:var(--j-slate);margin-bottom:9px}
.sidecard .kv{display:flex;justify-content:space-between;gap:10px;font-size:12.5px;
  padding:5px 0;border-bottom:1px dashed var(--j-hair);color:var(--j-slate)}
.sidecard .kv:last-child{border:none}
.sidecard .kv b{color:var(--j-ink-2);font-weight:700;font-variant-numeric:tabular-nums}

/* The standalone basis lede is GONE — it lives inside the money block it
   describes. One statement, one place, and it cannot go stale on its own. */
.money{display:flex;align-items:center;gap:24px;background:var(--j-muted);
  border:1px solid var(--j-hair);border-radius:var(--jr-xl);padding:16px 22px;flex-wrap:wrap}
.money .fig{font-size:clamp(24px,3.2vw,31px);font-weight:800;color:var(--j-brand);
  letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
.money .fig .per{font-size:13.5px;color:var(--j-slate);font-weight:600}
.money .lab{font-size:12px;font-weight:700;color:var(--j-ink-2);margin-top:4px}
.money .side{flex:1;min-width:250px;font-size:12.5px;color:var(--j-slate);line-height:1.5}
.money .side b{color:var(--j-ink-2)}
.sl{font-size:12.5px;color:var(--j-slate);margin-bottom:10px;max-width:88ch}
/* S46 ITEM 0 . INSIDE THE TOP SECTION THE TRACK IS THE MEASURE.
   88ch is right for a paragraph running the full content width and wrong
   in a 1.45fr column: at 2560 the column was 690 and the text stopped at
   593. The specimen's lede has a cap too and it is generous enough never
   to bite; ours bit. It comes off here and nowhere else. */
.top2>.sl{max-width:none}

/* ── AN AGENT, NOT A FINDING ──────────────────────────────────────────
   The frame change that makes the product click: each row is an AGENT YOU
   COULD HIRE and the card is its job description. WHY is the business case,
   WHAT is the job, HOW is the onboarding, and the range is the salary it would
   justify. A reader already knows how to evaluate a hire; nobody knows how to
   evaluate a "finding". */
.find{border:1px solid var(--j-hair);border-radius:var(--jr-md);margin-bottom:9px;
  background:var(--j-surface);overflow:hidden}
details.find>summary{list-style:none;cursor:pointer;padding:12px 16px;display:block}
details.find>summary::-webkit-details-marker{display:none}
details.find>summary:focus-visible{outline:2px solid var(--j-accent);outline-offset:-2px}
.find .t{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.find .sd{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--j-slate)}
.find .nm{font-weight:700;font-size:14.5px;flex:1;min-width:220px;color:var(--j-ink)}
.find .bd{font-size:10.5px;font-weight:700;color:var(--j-white);border-radius:var(--jr-xs);padding:2px 8px}
.bA{background:var(--j-band-a)}.bB{background:var(--j-band-b)}
.bC{background:var(--j-slate)}.bD{background:var(--j-slate-2)}
.find .vl{font-weight:700;color:var(--j-brand);font-size:13.5px;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.find .dx{color:var(--j-slate);font-size:12.5px;margin-top:6px;line-height:1.5;
  max-width:84ch}
/* The disclosure's LABEL is rendered from the columns that actually open, not
   hard-coded. The specimen's `content:"Why · What · How"` would promise two
   sections that J-7.1 keeps dark — a label is a claim like any other. */
.expbtn{font-size:11px;color:var(--j-accent);border:1px solid var(--j-accent);
  border-radius:var(--jr-pill);padding:2px 11px;font-weight:600;white-space:nowrap;order:99}
details.find[open] .expbtn .caret::after{content:"\25B4"}
details.find:not([open]) .expbtn .caret::after{content:"\25BE"}
.abody{border-top:1px solid var(--j-hair);background:var(--j-muted);padding:14px 16px 16px}
.wgrid{display:grid;grid-template-columns:repeat(var(--cols,3),1fr);gap:16px}
.wcol h6{font-size:10px;letter-spacing:.13em;text-transform:uppercase;font-weight:800;
  color:var(--j-brand);margin-bottom:7px;padding-bottom:5px;
  border-bottom:2px solid var(--j-accent)}
.wcol p{font-size:12.5px;color:var(--j-ink-2);line-height:1.55;margin-bottom:7px}
.wcol ul{list-style:none;font-size:12.5px;color:var(--j-ink-2);line-height:1.5}
.wcol li{padding-left:14px;position:relative;margin-bottom:5px}
.wcol li::before{content:"";position:absolute;left:0;top:7px;width:5px;height:5px;
  border-radius:50%;background:var(--j-accent)}
.wcol b{color:var(--j-brand);font-variant-numeric:tabular-nums}
/* S33 · Ten's house rule (cert §2.2) is the HOW column's third line, and it is
   not read off this agent — it is the same sentence on every card. The bullet
   is squared off and the rule is set above it so a reader can see at a glance
   that it belongs to a different class of statement than the reads and writes
   it follows. Tokens only; no new value enters this canon. */
.wcol li.house{margin-top:8px;padding-top:8px;border-top:1px solid var(--j-hair);
  color:var(--j-slate)}
.wcol li.house::before{border-radius:0;background:var(--j-slate);top:15px}

/* AN EXEMPLAR MUST SAY IT IS ONE — in the interface, never in a footnote.
   Muted and matter-of-fact, not a warning: the reader is being told the shape
   is typical, which is useful, not being apologised to. (J-5.1)

   ⚠ S32 · RETIRED FROM THE AGENT CARD, AND KEPT ANYWAY. The chip was reserved
   for the moment WHAT and HOW arrived as exemplars. The Spec J §7 amendment
   landed instead, so they arrive as ENGINE OUTPUT and Ten's §5 exemplar
   permission expires for those two fields — a chip reading TYPICAL over a
   computed field is a lie in the other direction. Nothing is deleted in this
   lane: if a later surface earns an exemplar, the chip returns by ruling and
   not by rebuild, and it will want these exact styles when it does. */
.typical{display:inline-block;font-size:9.5px;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--j-slate);background:var(--j-sunk);
  border:1px solid var(--j-hair);border-radius:var(--jr-xs);padding:1px 6px;margin-left:7px;
  vertical-align:middle}
.exnote{margin-top:9px;font-size:11px;color:var(--j-slate);line-height:1.45;
  border-top:1px dashed var(--j-hair);padding-top:7px}
/* THE UNKNOWN AS AN INVITATION, never a disclaimer (J-5.2). Not "we do not know
   your CMS" but "a CMS — which one?", with somewhere to say. */
.ask-inline{color:var(--j-accent);font-weight:600;
  border-bottom:1px dashed var(--j-accent);background:none;border-top:none;
  border-left:none;border-right:none;font-family:inherit;font-size:inherit;
  padding:0;text-decoration:none}

.arith{margin-top:13px;background:var(--j-surface);border:1px solid var(--j-hair);
  border-radius:var(--jr-sm);padding:9px 12px;font-size:12px;color:var(--j-ink-2)}
.arith .alab{display:block;font-size:9.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--j-slate);font-weight:700;margin-bottom:4px}
.arith .aval{font-variant-numeric:tabular-nums;color:var(--j-brand);font-weight:700;
  line-height:1.5}
.checkline{font-size:11.5px;color:var(--j-slate);margin-top:8px}
.checkline b{color:var(--j-ink-2)}

/* ══ S37 · THE WHY COLUMN ═══════════════════════════════════════════════
   Ten: *"the what and the how are strong - this why is very weak."* The
   column was answering the wrong question, and this is the composition he
   settled over eight rounds, matched rather than reinterpreted.

   ⚠ EVERY RULE HERE IS A NEW SELECTOR. Nothing certified is edited. Where
   the composition disagrees with an existing declaration it wins on
   specificity, and the existing declaration stays exactly as it was and
   still governs every other surface it dresses.

   The tokens are THIS canon's. The specimen carries six local aliases
   (`--muted` -> `--j-slate`, `--deep` -> `--j-brand`, `--hair` ->
   `--j-hair`, `--accent` -> `--j-accent`, `--paper` -> `--j-muted`,
   `--ink` -> `--j-ink`) over an otherwise byte-identical `:root`, so there
   is no second palette - checked value by value before a line was written. */

/* WHY IS THE WIDEST COLUMN BECAUSE IT CARRIES THE CASE. The count still has
   ONE author - the length of `agent.columns` - and it is stated as an
   attribute so this can be a new rule instead of an edit to `.wgrid`. A
   card the engine could only fill one column of (J-7.1, per card) keeps its
   single full-width column and gains no invented ratio. */
.wgrid[data-cols="1"]{grid-template-columns:1fr}
.wgrid[data-cols="2"]{grid-template-columns:1.3fr 1fr}
.wgrid[data-cols="3"]{grid-template-columns:1.3fr 1fr 1fr;gap:18px}

/* THE STAKE. The share, the people band and the labour pool take the brand
   colour and tabular figures because they are the three numbers a founder
   reads off this card in one pass. */
.wcol .stake{font-size:13px;line-height:1.5;color:var(--j-ink-2);margin:0 0 8px}
.wcol .stake b{color:var(--j-brand);font-weight:700;
  font-variant-numeric:tabular-nums}

/* THE ENGINE'S OWN EVIDENCE, clamped to four lines with the rest behind one
   word. `--ln` is declared here rather than inline because there is exactly
   one clamped block in this product and its depth is a design decision, not
   a per-instance one.

   ⚠ THE DISCLOSURE IS HIDDEN UNTIL SOMETHING IS ACTUALLY CLIPPED. `.more`
   is `display:none` by default and the script adds `.clipped` only after
   measuring. The specimen does the reverse - ships it visible, hides it on
   measurement - which leaves a button that opens nothing wherever the
   script has not run. Hub: *a More that opens nothing is worse than none.* */
.wcol .cl{--ln:4;font-size:12.5px;line-height:1.52;color:var(--j-ink-2)}
.wcol .cltx{display:-webkit-box;-webkit-line-clamp:var(--ln);
  -webkit-box-orient:vertical;overflow:hidden}
.wcol .cl.open .cltx{-webkit-line-clamp:unset;overflow:visible}
.wcol .more{display:none;font:inherit;font-size:11px;font-weight:700;
  color:var(--j-accent);background:none;border:0;padding:4px 0 0;cursor:pointer}
.wcol .cl.clipped .more{display:inline-block}
.wcol .more:hover{text-decoration:underline}

/* THE LINE THAT STOPS A FOUNDER HEARING "LAYOFFS". Quiet, and directly
   above the inputs box so it is read as a condition on the arithmetic. */
.wcol .capnote{font-size:12px;line-height:1.5;color:var(--j-slate);margin:8px 0 0}

/* J-7.1's GAP. A function the engine could not decompose says so, in the
   column, in the same quiet register - never as an empty space that reads
   as a short answer. */
.wcol .wgap{font-size:12px;line-height:1.5;color:var(--j-slate);margin:0 0 8px;
  padding-left:9px;border-left:2px solid var(--j-hair)}

/* THE INPUTS BOX, in the specimen's proportions: white on the muted column,
   tighter than the operator artifact's, and the VALUE no longer set in bold
   brand - it is the inputs, not the answer, and it stopped competing with
   the stake line for the eye. */
.wcol .arith{margin:9px 0 8px;padding:8px 10px;border-radius:var(--jr-xs)}
.wcol .arith .alab{font-size:8.5px;letter-spacing:.14em;margin-bottom:4px}
.wcol .arith .aval{display:block;font-size:11px;line-height:1.45;
  color:var(--j-ink-2);font-weight:400}

.wcol .payb{font-size:12px;color:var(--j-ink-2);margin:0}

/* PROVENANCE, DEMOTED. This is the demotion: the smallest type on the card,
   the quietest colour in the canon, under a hairline. If it reads as a peer
   of the stake line it has not landed. */
.wcol .prov{margin-top:9px;padding-top:7px;border-top:1px solid var(--j-hair);
  font-size:10.5px;line-height:1.45;color:var(--j-slate)}
.wcol .prov b{color:var(--j-slate);font-weight:700}

/* A SAVED OR FORWARDED COPY HIDES NOTHING. The clamp is a reading
   convenience on screen and has no business in a document somebody printed
   to send on - the evidence paragraph is the part that proves we read them. */
@media print{
  .wcol .cltx{-webkit-line-clamp:unset;overflow:visible}
  .wcol .more{display:none}
}

/* ── WHAT WE'D NEED TO KNOW ───────────────────────────────────────────
   The engine's existing `missing_fields` / `unlock_label`, surfaced client-side
   and attached to the agent each one sharpens. R-INTAKE-1: a question is a
   DISCLOSURE, never a GATE. Nothing here withholds, greys out or blocks. */
.qsec{background:var(--j-muted);border:1px solid var(--j-hair);border-radius:var(--jr-lg);
  padding:18px 20px;margin-top:4px}
.qhead{display:flex;justify-content:space-between;align-items:baseline;gap:14px;
  flex-wrap:wrap;margin-bottom:4px}
.qhead h4{font-size:16.5px;font-weight:800;color:var(--j-brand);letter-spacing:-.01em}
.qcount{font-size:12px;color:var(--j-slate);font-variant-numeric:tabular-nums}
.qlede{font-size:12.5px;color:var(--j-slate);margin-bottom:14px;max-width:90ch}
.qgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.qcard{background:var(--j-surface);border:1px solid var(--j-hair);border-radius:var(--jr-md);
  padding:12px 14px}
.qcard .qfor{font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  font-weight:700;color:var(--j-accent);margin-bottom:6px}
.qcard .qq{font-size:13.5px;font-weight:700;color:var(--j-ink);margin-bottom:4px}
.qcard .qw{font-size:11.5px;color:var(--j-slate);line-height:1.45}
.qcard .qw b{color:var(--j-ink-2)}
.qmore{margin-top:12px;font-size:12px;color:var(--j-slate)}
.qmore b{color:var(--j-ink-2)}

/* ── THE PUNCHLINE ────────────────────────────────────────────────────
   The page ends on the dark band it began on. Everything above argues; this
   states. UpShot is the noun (Spec J §4). */
/* S46 ITEM 0 . the closing band is a direct child of `.paper` and takes
   the sheet's one gutter like every other one. */
.punch{background:var(--j-brand);color:var(--j-white);
  padding:30px var(--gut,40px) 34px;margin-top:24px}
.punch .ph{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  font-weight:800;color:rgba(255,255,255,.5);margin-bottom:10px}
.punch .pfig{font-size:clamp(34px,4.6vw,52px);font-weight:800;letter-spacing:-.03em;
  line-height:1.05;font-variant-numeric:tabular-nums;margin-bottom:6px}
.punch .psub{font-size:14px;color:rgba(255,255,255,.66);max-width:76ch;
  margin-bottom:22px}
.pgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.ptile{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.15);
  border-radius:var(--jr-md);padding:14px 16px}
.ptile .pk{font-size:10px;letter-spacing:.11em;text-transform:uppercase;
  font-weight:700;color:rgba(255,255,255,.55);margin-bottom:6px}
.ptile .pv{font-size:19px;font-weight:800;letter-spacing:-.015em;
  font-variant-numeric:tabular-nums;line-height:1.15}
.ptile .pn{font-size:11px;color:rgba(255,255,255,.45);margin-top:5px;line-height:1.4}
.disclose{padding:18px var(--gut,40px) 4px;font-size:11px;color:var(--j-slate);line-height:1.5;
  max-width:110ch}
/* S32 · the disclaimer became two paragraphs when the placeholder bracket was
   replaced by Ten's copy. The wrapper keeps the padding it always had and the
   paragraphs inside carry the break, so the block still starts exactly where it
   did. PROVISIONAL — typographic, reversible in these three lines. */
.disclose p{margin:0 0 8px}
.disclose p:first-child{margin-top:0}
.disclose p:last-child{margin-bottom:0}

@media(max-width:1180px){
  .wgrid{grid-template-columns:1fr}
  .pgrid{grid-template-columns:repeat(2,1fr)}
  .qgrid{grid-template-columns:1fr}
}
/* 880px is the specimen's own collapse breakpoint -- the width at which
   it folds `.wgrid`, `.qgrid` and `.two` to one column. The specimen
   does not fold `.top2` at all; a 386px rail beside a 1.45fr lede at
   390 would be an overflow, so this takes the NEAREST SPECIMEN PATTERN
   rather than inventing a width. Said out loud in the S46 report. */
@media(max-width:880px){
  .top2{grid-template-columns:1fr;gap:22px}
  /* one track below the fold-width, so a phone never renders a 300px
     track beside a 90px one. */
  .rivalgrid{grid-template-columns:1fr}
}

/* ── S41 §3 · THE DOOR MODAL, PORTED FROM THE APPROVED SPECIMEN ──────────────
   R-PIXEL-1, and the picture is `s40_design\TARGET_door_modal.png`. The mark
   is 52px and the wordmark 44px, which is the specimen's `.upmark.xl` — the
   `Shot` at .62 opacity is the canon treatment and is not re-decided here. */
.scrim[hidden]{display:none}
.scrim{position:fixed;inset:0;background:rgba(4,12,22,.74);display:grid;
  place-items:center;padding:24px;z-index:50;opacity:0;
  animation:doorfade .5s ease forwards;overflow:auto}
@keyframes doorfade{to{opacity:1}}
body.doorlocked{overflow:hidden}
/* The page recedes behind the introduction rather than merely dimming —
   the specimen's `.door.behind`. It is applied by the same class the
   script already sets, so there is one switch and not two. */
body.doorlocked .ask{filter:blur(3px) saturate(.75);opacity:.4;
  pointer-events:none;transition:filter .45s ease,opacity .45s ease}
.scrim .dcard{max-width:680px;width:100%;background:var(--j-brand);
  border-radius:var(--jr-modal);border:1px solid rgba(255,255,255,.13);padding:0;
  position:relative;overflow:hidden;box-shadow:var(--j-modal-lift);
  transform:translateY(14px);
  animation:doorrise .55s cubic-bezier(.2,.7,.3,1) .06s forwards;
  color:var(--j-white)}
@keyframes doorrise{to{transform:translateY(0)}}
/* the brand band: the name gets its own field, not a corner */
.scrim .brandband{padding:40px 44px 30px;text-align:center;
  background:linear-gradient(180deg,rgba(91,143,168,.14),rgba(91,143,168,0));
  border-bottom:1px solid rgba(255,255,255,.10)}
.scrim .doormark .upmark{gap:16px}
.scrim .brandband .tag{margin:16px 0 0;font-size:11.5px;letter-spacing:.20em;
  text-transform:uppercase;color:rgba(255,255,255,.46)}
.scrim .dbody{padding:30px 44px 34px}
.scrim .dbody p{font-size:17px;line-height:1.62;margin:0;
  color:rgba(255,255,255,.90)}
.scrim .x{position:absolute;top:14px;right:16px;background:none;border:0;
  color:rgba(255,255,255,.38);font-size:22px;line-height:1;cursor:pointer;
  padding:6px 9px;border-radius:var(--jr-sm)}
.scrim .x:hover{color:var(--j-white);background:rgba(255,255,255,.08)}
/* ⚠ `--j-accent`, NOT `--j-logo`. My first pass mapped the specimen's
   `--j-accent` onto this file's `--j-logo` on the assumption that the two
   palettes needed reconciling. They did not: `flow.css` already declares
   `--j-accent` at the same value the specimen uses, while `--j-logo` is a
   near-black — so the
   button rendered dark navy text on a near-black field and the only call to
   action on the page was illegible. THE PHOTOGRAPH SHOWED IT AND THE
   MARKUP ASSERT COULD NOT: every element was present and correctly named. */
.scrim .cta{display:block;width:100%;margin-top:28px;padding:17px 22px;border:0;
  border-radius:var(--jr-xl);background:var(--j-accent);
  color:var(--j-cta-ink);font:inherit;
  font-size:17px;font-weight:650;cursor:pointer;text-align:center;
  letter-spacing:-.01em;transition:transform .15s ease,box-shadow .15s ease}
.scrim .cta:hover{transform:translateY(-1px);
  box-shadow:var(--j-cta-glow)}
.scrim .cta:focus-visible{outline:3px solid var(--j-white);outline-offset:3px}
.scrim .skip{display:block;width:100%;margin-top:12px;background:none;border:0;
  color:rgba(255,255,255,.48);font:inherit;font-size:13.5px;cursor:pointer;
  text-align:center}
.scrim .skip:hover{color:rgba(255,255,255,.82)}
@media (max-width:560px){
  .scrim{padding:12px}
  .scrim .brandband{padding:32px 26px 24px}
  .scrim .dbody{padding:26px 26px 30px}
  .scrim .doormark .upword{font-size:34px}
}

/* ── S41 §2 · THE MASTHEAD, PORTED FROM THE APPROVED SPECIMEN ────────────────
   R-PIXEL-1 governs and the pictures are `s40_design\TARGET_report_masthead.png`
   and `TARGET_rivals.png`. Nothing below is new design: every value is the
   running specimen's, and where a colour literal existed in the specimen the
   flow token stands in its place, because a second palette on one surface is
   how two designs for one document start.

   THE COVER IS NO LONGER A FLEX ROW. It was a logo, a name and a standfirst
   side by side; it is now a stacked masthead whose second element is a
   two-column grid. `display:block` is the change that makes the rest legible.
   ───────────────────────────────────────────────────────────────────────── */
/* ⚠ THIS IS THE SECOND `.cover` DECLARATION AND IT IS THE ONE THAT WINS.
   S46 ITEM 0: the first pass gave `--gut` to the rule at the top of the
   sheet and the masthead did not move, because this line is 350 lines
   later at equal specificity. The gutter is one number now and it is
   spelled the same in both places. */
.cover{display:block;padding:20px var(--gut,40px) 18px}
.cover .brandrow{margin-bottom:18px}
.cover .lg{width:34px;height:34px}

/* R-NOTICE-1 · the confidentiality line, at the HEAD, above the company's own
   name. QUIET, NOT SHOUTED — it is a statement of terms, not a warning label,
   and a red banner on a prospect's own report reads as fear. */
.cover .conf{font-size:10px;letter-spacing:.055em;text-transform:uppercase;
  color:rgba(255,255,255,.42);margin:0 0 16px;line-height:1.5}

/* R-FRAME-1 (Ten, 2026-08-19) · TWO COLUMNS. The company and its number left,
   the framing paragraph right. The right column is SMALLER than the standfirst
   and quieter on purpose: it is context for the number, and if it competes
   with the number it has failed. */
.cover .mastgrid{display:grid;grid-template-columns:1fr 330px;gap:44px;
  align-items:start}
.cover .mastmain{min-width:0}
.cover h2{font-size:clamp(26px,3.6vw,40px);font-weight:800;letter-spacing:-.028em;
  line-height:1.08;margin:0}
.cover .sub{font-size:clamp(14px,1.6vw,17px);line-height:1.4;margin:10px 0 18px;
  color:rgba(255,255,255,.66);font-weight:400}
.cover .hero{font-size:clamp(32px,5.6vw,60px);line-height:1;letter-spacing:-.036em;
  font-weight:700;margin:0}
.cover .herocap{font-size:13px;color:rgba(255,255,255,.6);margin-top:12px}
/* The derived-name mark sits under the name, one line, and does not gain the
   masthead a column at narrow widths. */
.cover .nmark{margin-top:7px}

.cover .frame{font-size:13.5px;line-height:1.62;color:rgba(255,255,255,.72);
  border-left:2px solid rgba(255,255,255,.22);padding:2px 0 2px 16px;margin:6px 0 0}
.cover .frame b{color:rgba(255,255,255,.95);font-weight:600}
.cover .frame .close{display:block;margin-top:11px;color:var(--j-white);
  font-weight:600}

/* ⚠ ONE STRIP, NOT TWO STACKED BLOCKS. Read date, basis and the estimates line
   are all small print ABOUT THE DOCUMENT. Stacked, they cost the generator's
   masthead three lines and pushed the first section below the fold. */
.cover .metastrip{display:flex;gap:34px;align-items:flex-start;margin-top:20px;
  padding-top:13px;border-top:1px solid rgba(255,255,255,.16)}
.cover .metastrip .k{font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.45);margin-bottom:4px}
.cover .metastrip .v{font-size:13px;color:rgba(255,255,255,.86)}
.cover .metastrip .v.small{font-size:11.5px;line-height:1.5;
  color:rgba(255,255,255,.58);font-weight:400}
.cover .metastrip .grow{flex:1;max-width:62ch}

/* Below 860px the framing paragraph stacks UNDER the figure, never above it:
   on a phone the first thing on the page must still be whose report this is. */
@media (max-width:860px){
  .cover .mastgrid{grid-template-columns:1fr;gap:22px}
  .cover .frame{border-left:0;border-top:1px solid rgba(255,255,255,.18);
    padding:14px 0 0;margin-top:4px}
}
/* The horizontal half is `--gut` (20px from 720 down); only the vertical
   is this breakpoint's business. Two pixels narrower than the 22 it read
   before, and the same as every other block on the page, which is worth
   more than the two pixels. */
@media (max-width:700px){
  .cover{padding-top:16px;padding-bottom:16px}
  .cover .metastrip{flex-wrap:wrap;gap:16px 28px}
}

/* R-RIVAL-1 (Ten, 2026-08-19) · THE FIGURES GO IN THE SUMMARY ROW.
   `est. people` is set in the muted italic the rest of this surface uses for
   "we did not read this", so it cannot be mistaken for a figure. */
/* R-TOP-1 (Hub, 2026-08-23) · the competitors card runs the full content
   width beneath `.top2`, and its CONTENTS are the column, not the card.
   Four competitors stacked across 980px would be four sparse lines and a
   taller page -- the void moved rather than closed.

   ⚠ 350px IS THE FLOOR BECAUSE 350px IS WHAT THE ROW WAS FIXED AT. S44
   measured `.rn`/`.loc` against the 350px rail after a 249px location string
   left a competitor's name 53px to set itself in, one word per line, four
   lines deep, on a client's report. A minimum below that re-opens it. I first
   wrote 300 and MEASURED the result: it does not even produce the narrower
   layout it was picked for -- three 300px tracks plus two gaps is 952 against
   948 of card, so 1440 fell back to two tracks anyway. The number that was
   doing nothing but risking S44's defect is gone.

   What this actually renders, measured, not intended:
       1440  content 980  ->  2 tracks of 461
       2560  content 1200 ->  3 tracks of 372   (v14's own COMPETITION column
                                                 is (980-60)*1.25/3.05 = 377)
        390               ->  1 track (the media query below) */
.rivalcard{margin-bottom:16px}
.rivalgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(350px,1fr));
  gap:0 26px}
.sidecard .rival{padding:9px 0;border-bottom:1px solid var(--j-hair)}
/* ⚠ `:last-child` IS THE WRONG SELECTOR ONCE THE LIST IS A GRID. In a
   single column the last child is the bottom row; in three columns it is
   the bottom of ONE column and the other two keep a rule under them. The
   rail is still one column, so both rules stand and the grid's own last
   ROW is what loses its border -- which CSS cannot express, so the grid
   keeps every rule and the card's padding closes the bottom instead. */
.sidecard .rival:last-child{border-bottom:0;padding-bottom:0}
.rivalgrid .rival:last-child{border-bottom:1px solid var(--j-hair)}
.sidecard .rtop{display:flex;gap:10px;align-items:baseline;
  justify-content:space-between}
/* ⚠ S44 · THE NAME GETS THE ROOM, AND IT DID NOT BEFORE.
   Found by Item 1's camera and then MEASURED at both wrap widths, because the
   honest question was whether narrowing the sheet caused it: the sidecard is a
   fixed 350px column, so it renders identically at 1440 and at 1060 and this
   defect is INHERITED, not introduced. `.loc` was `flex:none` -- it never
   yielded -- so a 249px location string on a 350px card left `New Jersey
   Bariatric Center` 53px in which to set itself, and it came out one word per
   line, four lines deep, on a client's report.

   The name is the row's subject and the location is its qualifier, so the
   qualifier is what shrinks. `.rn` takes the free space; `.loc` may give up to
   half the row and wraps rather than pushing. Nothing about the design moves:
   name still left, location still right, same type, same figures. */
.sidecard .rn{font-size:12.5px;font-weight:700;color:var(--j-ink);
  min-width:0;flex:1 1 auto}
.sidecard .loc{font-size:11px;color:var(--j-slate);text-align:right;
  flex:0 1 auto;min-width:0;max-width:50%}
.sidecard .rmeta{display:flex;flex-direction:column;gap:3px;align-items:flex-end;
  margin-top:4px}
.sidecard .rf{display:flex;gap:6px;align-items:baseline;white-space:nowrap}
.sidecard .rf i{font-style:normal;font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--j-slate);font-weight:700}
.sidecard .rf b{font-size:12.5px;font-weight:700;letter-spacing:-.005em;
  color:var(--j-ink)}
.sidecard .rf b.nr{font-weight:400;color:var(--j-slate);font-style:italic}
/* The qualifier WRAPS. `.rf` is nowrap because a money range must not
   break across lines; the sentence that explains it must. */
.sidecard .rnote{font-size:11px;line-height:1.45;color:var(--j-slate);
  margin-top:4px;text-align:right;white-space:normal}
.sidecard .rmeta{max-width:100%}
.sidecard .rf b{overflow-wrap:anywhere}

/* The double-count sentence, now beside the two sides it describes. */
.punch .once{font-size:12px;line-height:1.55;color:rgba(255,255,255,.6);
  max-width:78ch;margin:16px auto 0}
.punch .once b{color:rgba(255,255,255,.9)}


/* ═══ S44 ITEM 2 · THE READER BAND ══════════════════════════════════════════
   The heartbeat, and where you are against every read we have on record.
   Ported from `s40_design/AE_UpShot_Liveness_Prototype_2026-08-19.html`, which
   R-PIXEL-1 makes the spec; the tokens are this sheet's, never the
   prototype's raw hexes. */
.live{border:1px solid rgba(255,255,255,.10);border-radius:var(--jr-lg);
  background:rgba(255,255,255,.03);margin:0 0 20px;overflow:hidden;
  display:flex;align-items:stretch}
.live .cell{padding:15px 18px;flex:1;min-width:0}
.live .cell.hb{flex:0 0 300px}
.live .cell + .cell{border-left:1px solid rgba(255,255,255,.07)}
.live .lab{font-size:10.5px;letter-spacing:.10em;text-transform:uppercase;
  color:var(--j-slate);margin:0 0 7px}
/* ⚠ THE COLOUR IS DECLARED, AND IT HAS TO BE. This rule carried no `color`,
   so it inherited the page's ink -- and the read screen is DARK, so both of
   the band's headlines rendered near-black on near-black and were effectively
   invisible. Every markup assertion passed the entire time: the text was
   present, correct, and unreadable. Only the photograph could see it, which
   is S41's lesson arriving for the third time. The DEAD state was legible
   purely by accident, because `.dead .big` happens to set a colour of its
   own -- so the one state a test would think to check was the one state that
   worked. */
.live .big{font-size:19px;font-weight:650;letter-spacing:-.2px;margin:0;
  color:var(--j-white)}
.live .sub{font-size:12.5px;color:var(--j-slate);margin:5px 0 0}

/* 1 · the pulse. It BEATS while the reader is answering and STOPS when it is
   not -- the animation is itself a claim, so it is removed rather than
   recoloured when the claim stops being true. */
.live .pulse{display:inline-block;width:9px;height:9px;border-radius:50%;
  background:var(--j-beat-ok);margin-right:9px;vertical-align:middle;
  animation:beat 5s ease-out infinite}
@keyframes beat{
  0%{box-shadow:0 0 0 0 rgba(111,191,155,.6)}
  55%{box-shadow:0 0 0 13px rgba(111,191,155,0)}
  100%{box-shadow:0 0 0 0 rgba(111,191,155,0)}}
.live .cell.hb.stale .pulse{background:var(--j-beat-late);animation:none}
.live .cell.hb.dead .pulse{background:var(--j-beat-gone);animation:none}
.live .cell.hb.stale .big{color:var(--j-beat-late)}
.live .cell.hb.dead .big{color:var(--j-beat-gone)}

/* 2 · the strip. A MEASURED range and never a prediction. */
.live .co{margin-top:11px}
.live .track{position:relative;height:26px}
.live .track.bare{height:14px}
/* The prototype writes `border-radius:2px` here. It comes from the ramp
   instead: on a 3px-high bar the smallest step is already a full round, so
   the render is identical and the sheet keeps one place where a radius is
   decided. `test_session31` caught the raw value -- design_lint did not,
   because that check reads the canon differently, and two guards disagreeing
   about the same line is worth knowing. */
.live .rail{position:absolute;left:0;right:0;top:11px;height:3px;
  border-radius:var(--jr-xs);
  background:linear-gradient(90deg,rgba(91,143,168,.16) 0%,
    rgba(91,143,168,.42) 26%,rgba(91,143,168,.42) 74%,
    rgba(91,143,168,.16) 100%)}
.live .track.bare .rail{top:5px}
.live .tick{position:absolute;top:4px;width:1px;height:17px;
  background:rgba(255,255,255,.22)}
.live .tick b{position:absolute;top:20px;left:50%;transform:translateX(-50%);
  font-size:10px;font-weight:500;color:var(--j-slate);white-space:nowrap}
.live .you{position:absolute;top:1px;width:2px;height:23px;
  background:var(--j-white);transition:left .9s linear}
.live .you b{position:absolute;top:-17px;left:50%;transform:translateX(-50%);
  font-size:11px;font-weight:700;color:var(--j-white);white-space:nowrap}
.live .co.beyond .you{background:var(--j-beat-late)}
.live .co.beyond .you b{color:var(--j-beat-late)}
.live .nobench{font-size:11.5px;color:var(--j-slate);margin:8px 0 0}

/* The band stacks before the tick labels start colliding: three labels on one
   26px track need roughly 420px before `5m20s -- middle` overlaps its
   neighbours, and a benchmark you cannot read is worse than none. */
@media (max-width:760px){
  .live{flex-direction:column}
  .live .cell.hb{flex:1 1 auto}
  .live .cell + .cell{border-left:0;border-top:1px solid rgba(255,255,255,.07)}
}
