/* Completion Run item 5: bottom padding was 0 because the old graph
   (.flow-stage) supplied its own full-viewport spacing internally; the
   new .surfaces replacement is a normal-height block and needs the
   section's own closing padding back, matching this file's own
   existing var(--sec) convention used elsewhere on this page. */
#flow{padding:clamp(96px,10vw,152px) 0 var(--sec);overflow:hidden}
/* the personal 4-step loop: same shared .surfaces/.surf-card component
   os.html's own #loop uses for its four platform-scale cards (site.css,
   page-agnostic) -- overridden to 4 columns here for the identical
   reason os.css overrides it there (the shared default is 3 columns),
   same responsive 2-col/1-col steps reused verbatim, not reinvented. */
#flow .surfaces{margin-top:8px;grid-template-columns:repeat(4,minmax(0,1fr))}
@media(max-width:900px){ #flow .surfaces{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media(max-width:560px){ #flow .surfaces{grid-template-columns:1fr} }
/* REFINE-V4.md 1.6: the gap below .flow-head closes from clamp(44,5vw,72)
   (72px at 1512) to a flat 48px -- a specific number, not a new clamp
   range, per the brief's own wording. */
#flow .flow-head{width:min(100% - 48px,1400px);margin:0 auto 48px}
#flow .flow-kicker{margin:0 0 22px;color:var(--accent);font:400 12px/1.4 var(--mono);letter-spacing:.04em}
#flow h2{max-width:760px;margin:0;color:var(--ink);font:500 clamp(30px,2.45vw,36px)/1.13 var(--sans);letter-spacing:-.5px}
/* the new mid-scroll explainer line, verbatim per COPY-CANON */
#flow .flow-explain{max-width:640px;margin:16px 0 0;color:var(--ink-2);font-size:18px;line-height:1.5;letter-spacing:-.01em}
/* N10 item 1 (the verifier's JOB 31 stranger notes): 28px top / 36px
   bottom padding shifted the flex-centered board 4px off true centre --
   small on its own, but combined with the pin's own long scroll
   distance (flow.js, 1.6 viewport heights) the board's own resting
   position read as sitting high with the room below it doing nothing
   for most of the pin. Padding is symmetric now (32px both), and the
   pin itself is shorter (flow.js, 1.6 to 1.1) so the connector draw
   finishes closer to where the pin actually releases. */
#flow .flow-stage{width:100%;height:100vh;min-height:720px;padding:32px 0;display:flex;align-items:center}
#flow .flow-board{position:relative;width:min(100% - 48px,1400px);height:min(760px,calc(100vh - 64px));min-height:650px;margin:auto}
/* REFINE-V4.md 1.6: labels rise from 11px to 14px mono and sit 24px above
   their OWN column's own topmost node (not a shared top:0 -- the three
   columns start at different heights: outputs highest at 2.05%, lens at
   32.9%, references at 7.55%), so each gets its own top value, computed
   from the board's own real 760px height at 1512 (7.55%=57.4px etc, not
   assumed) rather than left on the same value as before. The outputs
   label's own 24px lands a few px above .flow-board's own top edge --
   verified against .flow-stage's own 28px top padding, which has nothing
   else in it, so this isn't a clip. */
#flow .flow-group-label{position:absolute;z-index:4;margin:0;color:var(--ink-3);font:400 14px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase}
#flow .flow-label-references{left:2.15%;top:19px}
#flow .flow-label-lens{left:40.7%;top:212px}
#flow .flow-label-outputs{left:78.6%;top:-22px}
#flow .flow-node{position:absolute;z-index:2;border:1px solid var(--glass-line);background:var(--bg-3);box-shadow:var(--sh-obj)}
#flow .flow-node .node-bar{isolation:isolate;display:block}
#flow .flow-node .node-bar::before{content:"";position:absolute;z-index:-1;top:-12px;left:-14px;right:-14px;height:56px;background:linear-gradient(to bottom,rgba(5,5,5,.85),transparent);pointer-events:none}
#flow .flow-node .node-title{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Impeccable, found on os.html specifically (this graph never lived on
   a page it audited before): two of the five output titles are real
   long compound strings ("Midjourney . Style prompt . LIVE", "Any
   agent . Lens endpoint . LIVE", both 32 characters) inheriting
   text-transform:uppercase from the shared .node-title rule above --
   the same all-caps-body class of finding os.css already fixed for
   #lit-list/.fo-agent.solo/etc, same fix applied here: sentence case
   (as already written in the HTML), sized and tracked as the small
   caption text it now reads as instead of mono-label size with the
   caps sanded off. Scoped to #flow .flow-output specifically (the only
   context these particular long strings occur in), so the shared base
   rule's short-label uses elsewhere are untouched. */
#flow .flow-output .node-title{text-transform:none;font-size:12px;letter-spacing:.01em;line-height:1.4}
#flow .flow-node .node-source{display:block;margin-top:6px;text-align:left}
#flow .flow-node img{display:block;width:100%;height:100%;object-fit:cover}
#flow .flow-reference{left:.45%;width:17.4%;height:27%}
#flow .flow-ref-1{top:7.55%}#flow .flow-ref-2{top:36.55%}#flow .flow-ref-3{top:65.45%}
#flow .flow-lens{position:absolute;z-index:3;left:40.7%;top:32.9%;width:18.6%;height:34.2%;min-width:0;display:flex;align-items:flex-end;justify-content:flex-end;padding:24px;background:var(--glass-bg)}
#flow .flow-lens .node-bar{display:block}
/* D8 item 1: "Warm light, unsentimental" clipped mid-word ("...
   UNSENTIMENT") -- .node-source's own base rule (v3.css) is
   white-space:nowrap, and nothing here let it wrap; the box has the
   height to spare (34.2% of the reference column), the source just
   never had permission to use it. Same fix as the home Carry card's own
   node (cards.css, D-earlier job): overflow-wrap:anywhere so a long
   single "word" (one CSS token after text-transform:uppercase) can
   break onto a second line instead of overflowing past .node's own
   overflow:hidden. */
#flow .flow-lens .node-source{display:block;margin-top:7px;text-align:left;white-space:normal;overflow-wrap:anywhere}
#flow .flow-swatches{display:flex;width:100%;height:54px;overflow:hidden;border:1px solid var(--glass-line);border-radius:8px}
#flow .flow-swatches i{flex:1;background:var(--swatch)}
/* Impeccable, os.html: the v7/v8 version chip was 10px, under the
   11px functional-text floor -- bumped, badge stays 34x24px (fits a
   2-character string comfortably at the new size, checked). */
#flow .flow-version{position:absolute;right:16px;bottom:92px;width:34px;height:24px;overflow:hidden;border:1px solid var(--accent);border-radius:100px;color:var(--accent-hi);font:500 11px/22px var(--mono);text-align:center;text-transform:uppercase}
#flow .flow-version span{position:absolute;inset:0}.flow-v8{opacity:0}
/* D8 item 2: the label sat directly on the photograph (.node-bar's own
   position:absolute overlay, the same 56px top-scrim every flow-node
   shares) -- fine for the darker reference photos, unreadable on the
   library's own brighter frames (a bright sky or sand under semi-
   transparent dark-on-dark text has nowhere near enough contrast,
   whatever the gradient's own opacity). #lit-list's own .lit-output node
   (lit-list.css) already solved exactly this for the same "library photo
   behind a label" shape: the bar leaves the photo and becomes its own
   real, solid-background block above it in normal flow (flex-direction:
   column, .node-bar{position:static}, the image flex:1 filling
   whatever's left) -- legible regardless of the photo under it, since
   there no longer is one. Same pattern here, .node-scrim kept in the
   markup (still darkens the photo itself, just no longer load-bearing
   for the label's own contrast). Scoped to .flow-output only --
   .flow-reference and .flow-lens keep their own existing overlay
   treatment, untouched. */
#flow .flow-output{right:2.5%;width:18.9%;height:18.3%;display:flex;flex-direction:column}
#flow .flow-output img{flex:1;min-height:0;height:0;width:100%}
#flow .flow-output .node-bar{position:static;isolation:auto;flex:none;padding:9px 11px;background:var(--bg-2)}
#flow .flow-output .node-bar::before{display:none}
#flow .flow-out-1{top:2.05%}#flow .flow-out-2{top:21.15%}#flow .flow-out-3{top:40.15%}#flow .flow-out-4{top:59.25%}#flow .flow-out-5{top:78.35%}
#flow .flow-output.is-next{opacity:.7}
#flow .flow-connectors{z-index:1}
#flow .flow-path{stroke-dasharray:var(--path-length);stroke-dashoffset:var(--path-length)}
@media(max-width:700px){#flow{padding:80px 0}#flow .flow-head{width:min(100% - 32px,480px);margin-bottom:48px}#flow .flow-stage{height:auto;min-height:0;padding:0}#flow .flow-board{width:min(100% - 32px,480px);height:auto;min-height:0;display:flex;flex-direction:column;gap:36px}#flow .flow-group-label{position:static;margin-bottom:-22px}#flow .flow-label-lens,#flow .flow-label-outputs{margin-top:14px}#flow .flow-label-references{order:0}#flow .flow-references{order:1}#flow .flow-label-lens{order:2}#flow .flow-lens{order:3}#flow .flow-label-outputs{order:4}#flow .flow-outputs{order:5}#flow .flow-column{position:relative;display:flex;flex-direction:column;gap:16px}#flow .flow-column::after,#flow .flow-lens::after{content:"";position:absolute;left:50%;bottom:-37px;width:1px;height:37px;background:var(--connector-line)}#flow .flow-node,#flow .flow-lens{position:relative;inset:auto;width:100%;height:auto;min-width:0}#flow .flow-reference{aspect-ratio:16/9}#flow .flow-lens{aspect-ratio:4/3;padding:24px}#flow .flow-output{aspect-ratio:16/9}#flow .flow-output.is-next{opacity:.7}#flow .flow-connectors{display:none}#flow .flow-version{bottom:92px}.flow-v7{opacity:0}.flow-v8{opacity:1}}
/* N1, the motion policy: this rule used to force the connectors to
   their final drawn state under prefers-reduced-motion, skipping the
   scroll-scrubbed draw entirely -- directly contradicting the new
   policy (site.js), which names connector draws explicitly as scroll-
   driven motion that stays ON under reduced motion, because it only
   ever moves as the reader scrolls. Removed alongside the matching fix
   in flow.js (no longer gates its own GSAP setup on the media query
   either) -- the two changes have to travel together, since this rule
   alone would keep overriding a correctly-running scrub with
   !important. Verified after: connectors draw progressively on scroll
   under reduced motion, same as with it off, not forced to the end
   state on load. */
