
/* ============================================================
   /websites page layer. Shared shell in /site/site.css; every
   block below is section-scoped per the 6c section-as-unit
   convention. The three proof animations: the schema x-ray and
   the speed race are integrations of animations/schema-xray.html
   and animations/speed-race.html; the content section is aeo v2,
   the round-13 Main Line build (its Bovender v1 predecessor is
   archived at animations/integrated-v1/). Retypeset to the site
   tokens, palette mapped to tokens or muted derivatives declared
   per section block, assets under
   /assets/animations/{xray,race,aeo-mainline}.
   Each animation is IntersectionObserver-gated (runs on screen,
   pauses off screen) and collapses to its most legible single
   frame under reduced motion. No-JS hides the stages; the copy
   and captions carry the sections.
   ============================================================ */

/* ============ SHARED PAGE BITS ============ */
.anim-cap{margin-top:2rem;font-size:var(--t-small);color:var(--lt-3);max-width:44em}
.sec-link{margin-top:1.6rem}
/* watching cue: one plain small-type sentence under each animated chapter's
   lede, so the visitor knows what the motion is before it starts. Not an
   eyebrow (no caps, no letterspacing). */
.watch-cue{margin-top:0.9rem;font-size:var(--t-small);color:var(--lt-3);max-width:44em}
/* no-JS: hide the stages, the copy carries the sections. The aml head
   sits above its stage (the round-4 composition, carried into aeo v2), so
   the selectors hide only the stage's media, frame and layers. */
body:not(.js) .xr-fit,body:not(.js) .race-fit,body:not(.js) .aml-left,body:not(.js) .aml-frame,body:not(.js) .aml-overlay,body:not(.js) .aml-bubbles{display:none}

/* ============ HERO (the glow hero: navy lit from within) ============
   ROUND 4: the silver water is retired (persistence rule, two rounds).
   The band is a deep navy field (var(--navy), the nav bar's own navy, so
   the fixed bar sits seamless on it) carrying the footer's lava-glow
   grammar adapted to hero scale: three periwinkle blobs in the ending
   triad, larger and slower than the footer's (blur 110px, 44-60s
   descents against the footer's 23-35s), low opacity, on a masked layer
   whose linear gradient keeps the upper type zone quiet and the lower
   half densest (the ending's sanctioned masking grammar). CSS-only
   motion; no-JS stills the blobs (body:not(.js)), reduced motion stills
   them too. ROUND 7: the hero is FLOW-SIZED. Viewport-height sizing is
   BANNED for this hero (three rounds of caps and short-screen overrides,
   retired under the persistence rule's spirit): no height, no min-height,
   no svh anywhere in the band. The section is padding-driven: the type
   wrap keeps its nav clearance (padding-top calc(87px + 3.2rem)), the CTA
   floor is static flow under the sub2 line at margin-top 2.4rem, and the
   section closes with padding-bottom 4.5rem. ONE layout at every size;
   the round-6 short-screen and mobile overrides are deleted. The glow
   field sizes to the section (inset:0 on the absolute bg). Acceptance:
   rendered hero height is IDENTICAL at 1536x730 and 1920x1080 (nothing in
   the band may depend on the viewport; the h1's vw clamp leg is capped at
   its 1536 rendering, 4.416rem, see the h1 rule). The seam against
   #seventy below is a hard edge by design (navy onto cream). */
.wh{position:relative;overflow:hidden;background:var(--navy);padding-bottom:4.5rem}
.wh-bg{position:absolute;inset:0;pointer-events:none;z-index:0;
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,rgba(0,0,0,0.22) 36%,rgba(0,0,0,0.7) 66%,#000 100%);
  mask-image:linear-gradient(180deg,transparent 0%,rgba(0,0,0,0.22) 36%,rgba(0,0,0,0.7) 66%,#000 100%)}
.wh-blob{position:absolute;border-radius:50%;filter:blur(110px);opacity:0.5;will-change:transform}
/* round-6 glow dials: a light source, not a tint. Blob 3 is WHITE-CORED
   (near-white center stop through periwinkle to transparent) so the field
   has an actual light source; opacities rose ~1.5x from round 4 (blobs 1
   and 2: 0.34 to 0.5; blob 3: 0.26 to 0.4); travel roughly 1.7x so the
   drift is perceptible at a glance, periods unchanged (44/52/60s, nothing
   under 20s). Reduced motion and no-JS still the blobs where they stand,
   white core included. */
/* round 14: navy ground, so the blob tones ride the on-dark periwinkle rule
   (base 92,144,255 = --peri-dark's triplet; deep #416CD7 = 65,108,215 takes
   the same red-pull-down shift; blob 3's white core is unchanged). Keep in
   sync with the ending triads in site/site.css and concept-6c. */
.wh-blob-1{width:64vw;height:64vw;left:-18vw;bottom:-22%;background:radial-gradient(circle at 40% 40%,rgba(92,144,255,0.85),rgba(92,144,255,0.35) 50%,transparent 72%);z-index:1;animation:wh-drift1 44s ease-in-out infinite alternate}
.wh-blob-2{width:56vw;height:56vw;right:-16vw;bottom:-14%;background:radial-gradient(circle at 40% 40%,rgba(65,108,215,0.8),rgba(65,108,215,0.3) 50%,transparent 72%);z-index:0;animation:wh-drift2 52s ease-in-out infinite alternate}
.wh-blob-3{width:42vw;height:42vw;left:30vw;bottom:-26%;opacity:0.4;background:radial-gradient(circle at 40% 40%,rgba(250,251,255,0.98),rgba(92,144,255,0.6) 34%,rgba(92,144,255,0.3) 58%,transparent 74%);z-index:2;animation:wh-drift3 60s ease-in-out infinite alternate}
@keyframes wh-drift1{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(17vw,-14vh,0) scale(1.16)}}
@keyframes wh-drift2{from{transform:translate3d(0,0,0) scale(1.08)}to{transform:translate3d(-20vw,11vh,0) scale(0.9)}}
@keyframes wh-drift3{from{transform:translate3d(0,0,0) scale(0.94)}to{transform:translate3d(14vw,-17vh,0) scale(1.18)}}
body:not(.js) .wh-blob{animation:none}
@media (prefers-reduced-motion: reduce){.wh-blob{animation:none}}
.wh>.wrap{position:relative;z-index:1;padding-top:calc(87px + 3.2rem)}   /* the type wrap only: the floor's wrap carries no nav clearance */
/* h1 in the homepage hero's display casting (Switzer 600, --track-serif,
   --lh-disp) at the --t-hero clamp with ONE round-7 departure: the cap
   moves from 4.5rem to 4.416rem, which is exactly 4.6vw at 1536 (the
   token's vw leg at the widest directive test width). Both 1536 and 1920
   then render the identical 70.656px h1, satisfying the flow-hero height
   equality gate; below 1536 the vw leg governs exactly as the token does,
   and the 1.34px cap reduction is the only difference anywhere. */
.wh h1{font-family:var(--serif);font-weight:600;font-size:clamp(2.7rem,4.6vw,4.416rem);letter-spacing:var(--track-serif);line-height:var(--lh-disp);max-width:14em}
/* ROUND 41: the brand term never severs. "AI Visibility" sits in a no-wrap
   span (markup), so the only wrap opportunities are before AI and before
   Website at ANY width; the old nbsp join on the last two words is retired
   here (it made "Visibility Website" the unbreakable unit and forced
   "The AI" / "Visibility Website" on phones). The phone size step is what
   lets "The AI Visibility" hold one line inside the 90vw wrap: the phrase
   measures ~9.5em in this casting, 9.2vw keeps ~2.7 percent of slack at
   every width under the 2.7rem floor (which 9.2vw reaches at 470px, where
   the phrase already fits at the floor). Desktop widths are untouched. */
.wh h1 .nw{white-space:nowrap}
@media (max-width:767px){.wh h1{font-size:min(9.2vw,2.7rem)}}
/* the homepage title entrance, lifted as a sealed pattern (concept-6c
   202-217 CSS, 1703-1735 IIFE): JS splits the h1 into per-character spans
   (an .sr copy carries the text for AT); each character rises and fades in
   when body.loaded lands (window load + 900ms fallback, once per load).
   ROUND-6 RULE, cause on record: letters NEVER animate letter-spacing.
   The old 0.16em-to-display-token collapse shrank the title's width as
   letters landed and moved the wrap point (two lines mid-entrance, one
   settled, on a 1536 laptop); letter-spacing is the display token from
   the first frame in every state, so the line count never changes.
   Reduced motion and no-JS: the plain heading, nothing split. */
.wh h1 .split-w{display:inline-block;white-space:nowrap}
body.js .wh h1.is-split .split-c{display:inline-block;opacity:0;transform:translateY(0.45em);transition:opacity 0.7s var(--ease-soft),transform 0.7s var(--ease-soft)}
body.js.loaded .wh h1.is-split .split-c{opacity:1;transform:none}
/* tag line 1: display register, roughly the h3 scale; the two periwinkle
   phrases are run-directed (light-on-navy via the section's dark theme) */
.wh-tag1{margin-top:1.6rem;font-family:var(--serif);font-weight:var(--w-6);font-size:1.5rem;letter-spacing:var(--track-h3);line-height:var(--lh-sub);max-width:40em}
.wh-tag1 .c{color:var(--peri-dark)}   /* navy hero: on-dark periwinkle per the round-14 rule */
/* tag line 2: full light ink (the dark-theme body color, not the muted
   step) at weight 500 */
.wh-sub2{margin-top:1rem;font-size:var(--t-lede);font-weight:var(--w-5);color:var(--lt);max-width:48em}
/* the CTA floor (round 7): static flow under the sub2 line; its own .wrap
   keeps the buttons on the same left gutter as the type */
.wh-floor{position:relative;margin-top:2.4rem;z-index:1}
.wh-cta{display:flex;gap:1.2rem;flex-wrap:wrap;align-items:center}
/* entrance: the title letters first (0.35s + 0.028s per character after
   load, settled ~1.64s), then tag 1, tag 2 and the CTAs fade up in place
   sequentially (round 2's timing feel: 500ms apart, 600ms rises, settled
   ~3.05s), all keyed to the same body.loaded latch so nothing outruns the
   letters, once per load. Reduced motion: everything static. */
body.js .wh-in{opacity:0;transform:translateY(18px);transition:opacity 0.6s var(--ease),transform 0.6s var(--ease)}
body.js.loaded .wh-in{opacity:1;transform:none}
.wh-tag1.wh-in{transition-delay:1.45s}
.wh-sub2.wh-in{transition-delay:1.95s}
.wh-cta.wh-in{transition-delay:2.45s}
@media (prefers-reduced-motion: reduce){body.js .wh-in{opacity:1;transform:none;transition:none}}
/* round 7: the short-screen and mobile height overrides are DELETED with
   the viewport sizing; the flow band is the one layout at every size */

/* ============ SEVENTY (the house pillar model: the website is 70 percent) ============ */
.seventy{padding:var(--sec-pad) 0;background:var(--field)}
.seventy-grid{display:grid;grid-template-columns:minmax(0,0.75fr) minmax(0,1.25fr);gap:4rem;align-items:center}
.seventy-stat{font-family:var(--serif);font-weight:600;font-size:clamp(5.5rem,10vw,9rem);line-height:var(--lh-solid);letter-spacing:var(--track-serif);color:var(--peri);font-variant-numeric:tabular-nums;white-space:nowrap}
.seventy-num{display:inline-block;min-width:2ch;text-align:right}   /* the % never moves while the number counts */
/* the proportion bar: 70 periwinkle / 30 hairline-gray under the numeral.
   The DOM ships it FILLED (the no-JS and reduced-motion state); the IIFE
   arms the scaleX fill (is-armed) only when motion is allowed, and is-in
   lands on the same IO trigger as the count-up. */
.seventy-bar{margin-top:1.8rem;max-width:420px}
.seventy-track{display:grid;grid-template-columns:70fr 30fr;gap:3px;height:4px}
.seventy-seg{border-radius:2px}
.seventy-seg--site{background:var(--peri);transform-origin:0 50%}
.seventy-seg--rest{background:var(--hair-strong)}
.seventy.is-armed .seventy-seg--site{transform:scaleX(0)}
.seventy.is-armed.is-in .seventy-seg--site{transform:scaleX(1);transition:transform 0.9s var(--ease)}
.seventy-legend{display:grid;grid-template-columns:70fr 30fr;gap:3px;margin-top:0.55rem}
.seventy-legend span{font-size:var(--t-label);letter-spacing:0.08em;text-transform:uppercase;color:var(--lt-3);white-space:nowrap}
/* the statement stack: four beats, one display line and one supporting
   sentence each, staggered into view 120ms apart on the .rv pattern */
.seventy-beats{list-style:none;margin-top:2.2rem}
.seventy-beats li{margin-top:1.7rem}
.seventy-beats li:nth-child(2){transition-delay:0.12s}
.seventy-beats li:nth-child(3){transition-delay:0.24s}
.seventy-beats li:nth-child(4){transition-delay:0.36s}
.beat-d{font-family:var(--serif);font-weight:var(--w-6);font-size:1.35rem;letter-spacing:var(--track-h3);line-height:var(--lh-sub)}
.beat-s{margin-top:0.35rem;color:var(--lt-2);max-width:36em}
@media (max-width:991px){.seventy-grid{grid-template-columns:1fr;gap:2rem}}

/* ============ SITE (The AI Visibility Website: isometric stack) ============
   LIFTED AS A SEALED UNIT from concept-6c.html 701-754 (CSS), 1409-1434
   (markup), 1858-2016 (IIFE). Only the head copy, the asset path style
   (root-absolute) and the adapted head block's h-to-sub gap (.site-head
   .lede margin-top:2rem, the homepage hero's h1-to-sub token; this page
   only, the 6c twin's head is untouched) differ; the referenced captures are the same
   /assets/site/ruth/ files, not duplicates. Dependencies (all in
   site/site.css): --sec-pad, --navy, --lt, --ink-rgb, --peri, --ease,
   --serif, --t-small, .wrap, .sec-h2, .lede, body.js. White literals on
   --navy: the same sanctioned exception as on the homepage. */
.site{padding:var(--sec-pad) 0;background:var(--navy);color:var(--lt);overflow:hidden}
.site-head{max-width:36em;margin-bottom:3rem}
.site-head .lede{margin-top:2rem;color:rgba(var(--ink-rgb),0.7)}   /* adapted head block: the homepage hero's h-to-sub gap */
.site-body{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,0.65fr);gap:4rem;align-items:center}
.site-stage{position:relative;aspect-ratio:4/3;perspective:1600px;margin-top:3.5rem}
.site-stack{position:absolute;left:8%;top:48%;width:58%;aspect-ratio:16/10;transform-style:preserve-3d;transform:rotateX(44deg) rotateZ(-20deg);transition:transform 0.9s var(--ease)}
.site-layer{position:absolute;inset:0;margin:0;border-radius:10px;overflow:hidden;box-shadow:0 10px 26px rgba(0,0,0,0.6),0 2px 5px rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.26);background:#111;transform:translate3d(var(--tx),var(--ty),var(--z));transition:transform 0.8s var(--ease),opacity 0.5s var(--ease),filter 0.5s var(--ease);will-change:transform,opacity}
.site-layer img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
.site-layer::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 1px 0 rgba(255,255,255,0.32);pointer-events:none}
.site-layer[data-i="0"]{--tx:0%;--ty:0%;--z:270px}
.site-layer[data-i="1"]{--tx:16%;--ty:12%;--z:180px}
.site-layer[data-i="2"]{--tx:32%;--ty:24%;--z:90px}
.site-layer[data-i="3"]{--tx:48%;--ty:36%;--z:0px}
.site-stack.has-active .site-layer{opacity:0.62;filter:saturate(0.7)}
.site-stack.is-picked .site-layer{opacity:0.22;filter:saturate(0.5) blur(0.6px)}
.site-stack.has-active .site-layer.is-active{opacity:1;filter:none}
.site-layer.is-active{transform:translate3d(calc(var(--tx) - 4%),calc(var(--ty) - 5%),330px);transition-delay:0.15s,0s,0s;pointer-events:none}
.site-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;position:relative;z-index:2}
.site-item button{display:block;width:100%;text-align:left;padding:1.3rem 0;border:0;border-top:1px solid rgba(255,255,255,0.14);background:transparent;color:inherit;cursor:pointer;border-radius:0}
.site-item:last-child button{border-bottom:1px solid rgba(255,255,255,0.14)}
.site-num{display:block;font-size:0.68rem;letter-spacing:0.14em;text-transform:uppercase;color:rgba(255,255,255,0.5)}
.site-name{display:block;margin-top:0.4rem;font-family:var(--serif);font-weight:600;font-size:1.15rem;color:rgba(255,255,255,0.7);transition:color 0.3s var(--ease)}
.site-desc{display:block;margin-top:0.45rem;font-size:var(--t-body);line-height:1.5;color:rgba(255,255,255,0.5);transition:color 0.3s var(--ease)}
.site-item.is-active .site-name{color:#fff}
.site-item.is-active .site-desc{color:rgba(255,255,255,0.78)}
.site-item.is-active .site-num{color:var(--peri-dark)}   /* navy section: on-dark periwinkle per the round-14 rule */
.site-visit{margin-top:1.6rem;justify-self:start;grid-column:2;position:relative;z-index:2}
body:not(.js) .site-stage{aspect-ratio:auto;perspective:none}
body:not(.js) .site-stack{position:static;width:auto;aspect-ratio:auto;transform:none;display:grid;grid-template-columns:1fr 1fr;gap:1rem}
body:not(.js) .site-layer{position:relative;transform:none;aspect-ratio:16/10;box-shadow:none}
@media (max-width:1099px){.site-body{grid-template-columns:1fr}.site-stage{aspect-ratio:5/4}.site-visit{grid-column:1}}
@media (max-width:767px){.site-stage{display:none}.site-list{gap:0}}
@media (prefers-reduced-motion: reduce){.site-stack,.site-layer{transition:none}}
/* ROUND 40 / 42: THE TRAVELING ACCORDION, the standard phone behavior of
   the four-pillar cycle (round 40 built it dormant behind ?exploded=c; round
   42 enabled it on Max's phone verdict and stripped the param). At phone
   widths the stage is hidden and the list runs its light-up cycle, so the
   site IIFE gives each list item a .site-exp row under its button holding a
   compact frame with that page's phone-weight top
   (assets/site/ruth/m/<page>.webp, 800x500), and the row is OPEN exactly
   when the item is active (.is-active, the shipped lit state, so the
   accordion is purely additive to it). The height rides grid-template-rows
   0fr to 1fr (the FAQ's technique; a fractional fr track resolves to that
   fraction of its content, so the collapsing row and the expanding row,
   identical in content height and run from the same setActive call on the
   same 0.4s curve, always sum to one frame: the list holds one constant
   footprint and the section never pumps), the frame fades on the same
   curve. Frame chrome: the round-38 card radius token, the site-layer's
   hairline and #111 ground (the block's sanctioned literals). The closing
   hairline moves from the last button to the list so it sits under the last
   panel. Desktop: no element exists, no rule here matches, no image is
   requested. The four page tops are lazy images (loading="lazy"), so they
   load as the section approaches view, not at page load. Reduced motion: no
   transitions (the first item stands expanded, static; the cycle is already
   off). Twin in concept-6c.html, keep in sync. */
@media (max-width:767px){
  .site--xc .site-exp{display:grid;grid-template-rows:0fr;transition:grid-template-rows 0.4s var(--ease)}
  .site--xc .site-item.is-active .site-exp{grid-template-rows:1fr}
  .site--xc .site-exp-in{min-height:0;overflow:hidden}
  .site--xc .site-exp-frame{position:relative;aspect-ratio:16/10;margin:0 0 1.3rem;border-radius:var(--r-card);overflow:hidden;border:1px solid rgba(255,255,255,0.26);background:#111;opacity:0;transition:opacity 0.4s var(--ease)}
  .site--xc .site-exp-frame::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 1px 0 rgba(255,255,255,0.32);pointer-events:none}
  .site--xc .site-item.is-active .site-exp-frame{opacity:1}
  .site--xc .site-exp-frame img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
  .site--xc .site-item:last-child button{border-bottom:0}
  .site--xc .site-list{border-bottom:1px solid rgba(255,255,255,0.14)}
}
@media (prefers-reduced-motion: reduce){.site--xc .site-exp,.site--xc .site-exp-frame{transition:none}}

/* ============ STRUCTURE (schema x-ray at half speed) ============
   Integrated from animations/schema-xray.html. Light section; the device
   frame and its code panel are a dark artifact rendering the real build,
   so their interior keeps a declared dark-derivative palette (below).
   ROUND 12: the section reads fosterrealty.com LIVE. Code view and
   extraction chips render the site's ACTUAL served source
   (assets/animations/xray/foster-live.html, a formatting derivative only:
   newlines between adjacent tags; nothing sampled, invented or authored).
   The Carrie v1 section is archived at animations/integrated-v1/
   xray-carrie.html and restores by splice when her site goes live.
   The code panel is depicted source code: it renders in the system
   monospace stack (no font fetch; Switzer everywhere else). */
.xr{padding:var(--sec-pad) 0;background:var(--field-2);overflow:hidden;
  /* dark chrome of the frame artifact: derivatives declared per the run
     directive; periwinkle is the invariant accent */
  --xr-navy:#0A1628;--xr-panel:#070D1A;--xr-frame:#0D1626;
  --xr-code:#C9CFDB;--xr-dim:#8A93A6;--xr-faint:#4B5468}
.xr-fit{position:relative;margin-top:3rem;overflow:hidden}
.xr-stage{width:1478px;transform-origin:0 0}
.xr-row{position:relative;display:grid;grid-template-columns:1200px 250px;column-gap:28px;align-items:start}
.xr-frame{position:relative;width:1200px;height:680px;border-radius:16px;border:1px solid rgba(255,255,255,0.08);overflow:hidden;background:var(--xr-frame)}
.xr-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--xr-dim);font-size:13px}
.xr-pan{position:absolute;left:0;top:0;width:1200px;will-change:transform}
.xr-layer-a{display:block;width:1200px;height:auto}
.xr-layer-b{position:absolute;inset:0;background:var(--xr-panel);color:var(--xr-code);font-family:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;font-size:12px;line-height:18px;padding:0 0 0 28px;overflow:hidden;will-change:clip-path}
.xr-layer-b pre{font:inherit;margin:0}
.xr-ln{height:18px;white-space:pre;overflow:hidden;padding-left:10px;margin-left:-10px;border-radius:3px}
.xr-ln.filler{opacity:0.35}
.xr-ln .k{color:var(--peri-dark)}   /* dark code panel: on-dark periwinkle per the round-14 rule (the panel artifacts below follow) */
.xr-ln .s{color:#fff;opacity:0.85}
.xr-ln .n{color:#fff;opacity:0.85}
.xr-ln .p{color:var(--xr-faint)}
.xr-ln .t{color:var(--xr-dim)}
.xr-reset{position:absolute;left:0;top:0;width:1200px;height:auto;opacity:0;pointer-events:none}
.xr-scan{position:absolute;left:0;right:0;top:0;height:2px;background:var(--peri-dark);opacity:0;pointer-events:none}
.xr-scan::after{content:"";position:absolute;left:0;right:0;top:2px;height:40px;background:linear-gradient(to bottom,rgba(92,144,255,0.35),rgba(92,144,255,0))}
.xr-scan::before{content:"";position:absolute;left:0;right:0;top:-6px;height:6px;background:linear-gradient(to top,rgba(92,144,255,0.35),rgba(92,144,255,0))}
.xr-bot{position:absolute;left:0;top:0;width:28px;height:28px;opacity:0;will-change:transform;filter:drop-shadow(0 0 6px rgba(92,144,255,0.55))}
.xr-col{position:relative;padding-top:6px;min-height:680px}
.xr-col h3{font-size:11px;letter-spacing:0.18em;text-transform:uppercase;color:var(--lt-3);font-weight:var(--w-6);padding-bottom:12px;border-bottom:1px solid var(--hair);margin-bottom:14px;transition:color 0.2s}
.xr-chip{position:absolute;left:0;top:0;display:inline-flex;align-items:center;height:26px;padding:0 10px;border-radius:999px;border:1px solid var(--peri-dark);background:var(--xr-navy);color:#fff;font-size:12px;font-weight:var(--w-5);white-space:nowrap;opacity:0;pointer-events:none;will-change:transform,opacity;max-width:250px;overflow:hidden;text-overflow:ellipsis}
.xr-chip .ck{color:var(--xr-code);margin-right:5px;font-weight:var(--w-4)}
/* under the hood: the band after the animation naming the other
   machine-read elements. Round 2: the seven-row table is replaced by the
   SPOTLIGHT GRID (round 6: TWELVE tokens, the five site-level signals
   appended after og:); the elements as dim code-styled tokens (system
   monospace, the depicted-source-code exception), one lit periwinkle at a
   time on a slow auto-cycle, the lit token's one-clause explainer typed
   into the terminal panel beside the grid (round 4; the round-2 caption
   slot is retired). Hover or focus pins a token and pauses the cycle
   (resume on leave); tap pins with the site-stack's 6s quiet window.
   Reduced motion and no-JS: no cycle (is-cycling never lands), every
   token at full, the panel carries the lit line statically. The band's
   felt job is "a lot is tended down here", not reading. */
.xr-under{margin-top:5rem}
.xr-under h3{font-family:var(--serif);font-weight:600;font-size:1.5rem;letter-spacing:var(--track-h3);max-width:22em}
.xr-under>p{margin-top:0.8rem;color:var(--lt-2);max-width:38em}
/* round 4: the band's blank right becomes the caption's stage. Two
   columns: the token grid LEFT (behavior unchanged) and a small
   code-styled terminal panel RIGHT, in the xr code view's aesthetic (the
   dark panel field, system monospace, periwinkle prompt), where the lit
   token's one-liner TYPES in as the cycle advances: cut on token change,
   then type at ~24ms per character, so the longest line finishes well
   inside the 2.8s dwell. Pinning a token pins its line. Reduced motion:
   no typing, the panel shows the lit token's line statically. No-JS: the
   DOM ships the first line. The panel is aria-hidden; the visually
   hidden live region (the old caption id) carries each full line for AT.
   Stacked below 1100: grid, then panel. */
/* round 6: twelve tokens; the grid column widens (1.35fr) and the token
   type steps to 0.9rem so the set wraps to TWO rows at 1440, DOM-metric
   checked; the terminal's typed line wraps to two lines at the narrower
   column, inside the panel's 5.2em min-height */
.xr-spot{margin-top:2.2rem;display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,0.65fr);gap:2rem 2.5rem;align-items:start}
.xr-spot-grid{display:flex;flex-wrap:wrap;gap:0.7rem 0.9rem}
.xr-tok{font-family:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;font-size:0.9rem;color:var(--lt-2);background:transparent;border:1px solid var(--hair);border-radius:8px;padding:0.6rem 0.9rem;cursor:pointer;transition:color 0.3s var(--ease),border-color 0.3s var(--ease),opacity 0.3s var(--ease)}
.xr-tok.is-lit{color:var(--peri);border-color:var(--peri)}
body.js .xr-spot.is-cycling .xr-tok{color:var(--lt-3);opacity:0.5}
body.js .xr-spot.is-cycling .xr-tok.is-lit{color:var(--peri);border-color:var(--peri);opacity:1}
.xr-term{border:1px solid rgba(255,255,255,0.08);border-radius:10px;background:var(--xr-panel);overflow:hidden}
.xr-term-bar{display:flex;align-items:center;gap:6px;height:26px;padding:0 10px;background:var(--xr-frame);border-bottom:1px solid rgba(255,255,255,0.08)}
.xr-term-bar span{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.14)}
.xr-term-body{margin:0;padding:0.85rem 1rem;font-family:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;font-size:0.85rem;line-height:1.55;color:var(--xr-code);min-height:5.2em}   /* two wrapped lines plus padding: the panel never changes height mid-cycle */
.xr-term-body .pr{color:var(--peri-dark);margin-right:0.6ch}   /* dark terminal panel: on-dark periwinkle (the lit tokens beside it sit on the light section ground and keep --peri) */
.xr-term-caret{display:inline-block;width:0.55ch;height:1em;background:var(--peri-dark);vertical-align:-0.12em;margin-left:2px;animation:xr-caret 1.1s steps(1) infinite}
@keyframes xr-caret{50%{opacity:0}}
@media (max-width:1100px){.xr-spot{grid-template-columns:1fr}}
@media (prefers-reduced-motion: reduce){.xr-tok{transition:none}.xr-term-caret{animation:none}}

/* ============ SPEED (the race, real captures vs the fictional RJ site) ====
   Integrated from animations/speed-race.html at 1x. Dark section. ROUND 12:
   the left phone shows real storyresidential.com captures
   (tools/capture-story-race.mjs; the Foster v1 section is archived at
   animations/integrated-v1/race-foster.html, its captures parked in
   assets-race-foster/); the right phone renders RJ
   Properties, a FICTIONAL template site (captioned as such, aria-hidden,
   data-nosnippet so no engine extracts its invented NAP). Muted chromatic
   derivatives for the RJ template palette are declared below per the run
   directive (its former gold star tint is gone). The score rings and their
   numerals draw in --lh-pass, Lighthouse's own green. RJ's deliberately
   cheap type runs on system stacks (Times before the font-swap stage,
   Georgia/Arial after): the FOUT gag survives with zero font fetches. */
.race{padding:var(--sec-pad) 0;background:var(--navy);overflow:hidden;
  --race-bezel:#14161C;
  --lh-pass: #0CCE6B; /* Lighthouse's own pass green; palette exception: these circles depict Google's tool and its real state colors, mapping them to brand tokens would falsify the depiction */
  --rj-navy:#31445E;--rj-slate:#2F4152;--rj-deep:#26303C;
  --rj-red:#A94438;--rj-chat:#4A63D9;--rj-star:#9A9A9A}
/* round 2 layout: side by side at desktop, the race stage LEFT and the
   head + copy RIGHT, vertically centered against the stage; stacked with
   the head first below 1100 (the copy precedes the stage in source order,
   the grid places it in column 2 at desktop) */
.race-cols{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,0.88fr);gap:4rem;align-items:center}
.race-copy{grid-column:2;grid-row:1}
.race-fit{grid-column:1;grid-row:1;position:relative;display:flex;justify-content:center;overflow:hidden}
@media (max-width:1100px){.race-cols{display:block}.race-fit{margin-top:3rem}}
.race-rig{position:relative;width:776px;height:960px;transform-origin:top center;flex:none;display:flex;gap:96px}
.race-col{position:relative;width:340px;display:flex;flex-direction:column;align-items:center}
.race-url{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 14px;border-radius:999px;background:rgba(var(--ink-rgb),0.06);font-size:13px;color:var(--lt-2);margin-bottom:16px}
.race-url svg{width:11px;height:11px;fill:none;stroke:var(--lt-3);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.race-timer{position:absolute;left:50%;top:-6px;transform:translateX(-50%);font-family:ui-monospace,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;font-size:44px;font-weight:var(--w-5);line-height:1;color:var(--lt);font-variant-numeric:tabular-nums;letter-spacing:-0.02em;white-space:nowrap}
.race-timer.done{color:var(--peri-dark)}   /* navy section: on-dark periwinkle (the tap ripple plays over the light captures and keeps --peri) */
.race-phone{position:relative;width:340px;height:736px;border-radius:44px;background:var(--race-bezel);padding:10px;box-shadow:inset 0 0 0 1px rgba(255,255,255,0.10),0 30px 60px rgba(0,0,0,0.45);flex:0 0 auto}
.race-phone::before{content:"";position:absolute;top:10px;left:50%;transform:translateX(-50%);width:110px;height:28px;background:var(--race-bezel);border-radius:0 0 16px 16px;z-index:5}
.race-phone::after{content:"";position:absolute;top:18px;left:50%;transform:translateX(-50%);width:46px;height:6px;background:#000;border-radius:3px;z-index:6}
.race-screen{position:relative;width:320px;height:716px;border-radius:34px;overflow:hidden;background:#fff}
.race-fs img{position:absolute;top:0;left:0;width:320px;height:auto;display:none;will-change:transform;user-select:none;-webkit-user-drag:none}
.race-fs img.on{display:block}
.race-ripple{position:absolute;width:56px;height:56px;margin:-28px 0 0 -28px;border-radius:50%;background:rgba(92,144,255,0.45);border:2px solid rgba(92,144,255,0.8);opacity:0;pointer-events:none;z-index:3}
.race-result{margin-top:22px;width:340px;opacity:0;text-align:center}
.race-rings{display:flex;justify-content:space-between;padding:0 6px}
.race-ring{width:76px;display:flex;flex-direction:column;align-items:center;gap:6px}
.race-ring svg{width:60px;height:60px;transform:rotate(-90deg)}
.race-ring .track{fill:none;stroke:rgba(255,255,255,0.10);stroke-width:5}
.race-ring .arc{fill:none;stroke:var(--lh-pass);stroke-width:5;stroke-linecap:round}
.race-ring .num{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:var(--w-6);color:var(--lh-pass)}
.race-ring .wrap-ring{position:relative;width:60px;height:60px}
.race-ring .name{font-size:10px;color:var(--lt-3);line-height:1.2;text-align:center}
.race-cap{margin:14px 0 0;font-size:12px;color:var(--lt-3)}
.race-plain{font-size:13px;color:var(--lt-3);margin:24px 0 0;max-width:300px}
.race-screen .rj-top{padding-top:30px}
.race-screen .rj-loadbar{top:30px}
.race-fade{position:absolute;inset:-40px;background:var(--navy);opacity:0;pointer-events:none;z-index:20}
.race.is-reduced .rj *,.race.is-reduced .rj *::before,.race.is-reduced .rj *::after{transition:none!important;animation-duration:0s!important}
/* RJ Properties: the fictional template site, staged via data-stage on .rj.
   0 white, 1 system-font text only, 2 font swap, 3 hero image height, 4 card
   image heights, 5 cookie banner, 6 chat widget, 7 settled. Neutral greys in
   this block are achromatic mixes inside the depicted screen artifact. */
.rj{position:relative;width:320px;height:716px;overflow:hidden;background:#fff;color:#333;
  --rj-serif:"Times New Roman",Times,serif;--rj-sans:"Times New Roman",Times,serif;
  font-family:var(--rj-sans);font-size:13px;line-height:1.45}
.rj *,.rj *::before,.rj *::after{box-sizing:border-box}
.rj:is([data-stage="2"],[data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"],[data-stage="7"]){
  --rj-serif:Georgia,"Times New Roman",serif;--rj-sans:Arial,Helvetica,sans-serif}
.rj-page{position:absolute;inset:0;overflow:hidden}
.rj[data-stage="0"] .rj-page{visibility:hidden}
.rj-loadbar{position:absolute;top:0;left:0;height:3px;width:var(--rj-load,0%);background:#8a9099;display:none}
.rj[data-stage="0"] .rj-loadbar{display:block}
.rj-top{display:flex;flex-direction:column;gap:4px;padding:7px 8px 6px;border-bottom:1px solid #e2e2e2}
.rj-logo{font-family:var(--rj-serif);font-weight:900;font-size:15px;color:var(--rj-navy);white-space:nowrap;letter-spacing:-0.01em}
.rj-logo span{color:var(--rj-red)}
.rj-nav{display:flex;justify-content:space-between;flex-wrap:nowrap}
.rj-nav a{font-size:9.5px;color:var(--rj-navy);text-decoration:none;text-transform:uppercase;letter-spacing:0.02em;white-space:nowrap}
.rj-hero-media{position:relative;height:0;overflow:hidden;transition:height 180ms ease-out;background:#e6e6e6;box-shadow:inset 0 0 0 1px #d0d0d0}
.rj:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"],[data-stage="7"]) .rj-hero-media{height:210px}
.rj-hero-title{position:absolute;left:0;right:0;bottom:14px;padding:0 14px;color:var(--rj-navy);z-index:1;font-family:var(--rj-serif);font-weight:900;font-size:22px;line-height:1.15;margin:0}
.rj-hero-copy{background:var(--rj-slate);color:#fff;padding:12px 14px 14px;text-align:center}
.rj-hero-copy h2{font-family:var(--rj-serif);font-weight:900;font-size:20px;margin:0 0 6px;line-height:1.2}
.rj-hero-copy p{margin:0 0 10px;font-size:12px;color:#dbe1e8}
.rj-search{display:flex;gap:4px;margin:0}
.rj-search input{flex:1;min-width:0;font:inherit;font-size:11px;padding:6px 8px;border:1px solid #b9c2cc;background:#fff;color:#333}
.rj-search button,.rj-btn{font:inherit;font-size:11px;font-weight:700;padding:6px 10px;background:var(--rj-red);color:#fff;border:0;text-transform:uppercase;letter-spacing:0.04em;text-decoration:none}
.rj-section{padding:14px 14px 6px}
.rj-section h3{font-family:var(--rj-serif);font-weight:900;font-size:17px;margin:0 0 8px;color:var(--rj-navy);text-align:center}
.rj-section h3::after{content:"";display:block;width:46px;height:3px;background:var(--rj-red);margin:6px auto 0}
.rj-card{border:1px solid #e2e2e2;margin-bottom:10px;background:#fff}
.rj-card-media{position:relative;height:0;overflow:hidden;transition:height 180ms ease-out;background:#e6e6e6;box-shadow:inset 0 0 0 1px #d0d0d0}
.rj-card:nth-child(2) .rj-card-media{transition-delay:0ms}
.rj-card:nth-child(3) .rj-card-media{transition-delay:200ms}
.rj-card:nth-child(4) .rj-card-media{transition-delay:400ms}
.rj:is([data-stage="4"],[data-stage="5"],[data-stage="6"],[data-stage="7"]) .rj-card-media{height:140px}
.rj-ph{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;visibility:hidden;transition:visibility 0s linear 300ms}
.rj-ph svg{width:28px;height:28px;fill:none;stroke:#9a9a9a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.rj-ph span{font-family:var(--rj-sans);font-size:11px;line-height:1;color:#9a9a9a}
.rj-card:nth-child(3) .rj-ph{transition-delay:500ms}
.rj-card:nth-child(4) .rj-ph{transition-delay:700ms}
.rj:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"],[data-stage="7"]) .rj-hero-media .rj-ph{visibility:visible}
.rj:is([data-stage="4"],[data-stage="5"],[data-stage="6"],[data-stage="7"]) .rj-card-media .rj-ph{visibility:visible}
.rj-badge{position:absolute;top:8px;left:8px;z-index:1;background:var(--rj-red);color:#fff;font-size:9px;font-weight:700;text-transform:uppercase;padding:3px 6px;letter-spacing:0.06em}
.rj-card-body{padding:8px 10px 10px}
.rj-price{font-weight:700;color:var(--rj-red);font-size:14px}
.rj-addr{font-family:var(--rj-serif);font-weight:700;font-size:13px;color:var(--rj-navy);margin:2px 0}
.rj-meta{font-size:11px;color:#777}
.rj-card-body .rj-btn{display:inline-block;margin-top:6px;padding:4px 8px;font-size:10px}
.rj-testi{background:#f3f4f6;padding:14px;text-align:center}
.rj-testi h3{font-family:var(--rj-serif);font-weight:900;font-size:16px;margin:0 0 8px;color:var(--rj-navy)}
.rj-quote{font-size:12px;color:#555;margin:0 0 4px}
.rj-who{font-size:11px;color:#888;margin:0 0 10px}
.rj-stars{color:var(--rj-star);font-size:12px;letter-spacing:2px}
.rj-footer{background:var(--rj-deep);color:#b9c2cc;padding:18px 14px 26px;font-size:11px}
.rj-footer h4{color:#fff;font-family:var(--rj-serif);font-weight:900;font-size:12px;margin:0 0 6px;text-transform:uppercase;letter-spacing:0.06em}
.rj-footer ul{list-style:none;padding:0;margin:0 0 14px}
.rj-footer li{padding:2px 0}
.rj-footer p{margin:0 0 6px}
.rj-footer .rj-copy{border-top:1px solid #2e3b49;padding-top:10px;margin-top:8px;font-size:10px;color:#7f8a96}
.rj-cookie{position:absolute;left:0;right:0;bottom:0;z-index:3;background:#222;color:#ddd;padding:12px 14px;font-size:11px;transform:translateY(105%);transition:transform 260ms ease-out;display:flex;gap:10px;align-items:center;box-shadow:0 -4px 14px rgba(0,0,0,0.3)}
.rj:is([data-stage="5"],[data-stage="6"],[data-stage="7"]) .rj-cookie{transform:translateY(0)}
.rj-cookie p{margin:0;flex:1}
.rj-cookie button{font:inherit;font-size:10px;font-weight:700;padding:6px 10px;background:#fff;color:#222;border:0;white-space:nowrap}
.rj-chat{position:absolute;right:14px;bottom:72px;z-index:4;width:54px;height:54px;border-radius:50%;background:var(--rj-chat);box-shadow:0 6px 16px rgba(0,0,0,0.35);transform:scale(0);display:flex;align-items:center;justify-content:center}
.rj-chat::after{content:"";position:absolute;top:-2px;right:-2px;width:14px;height:14px;border-radius:50%;background:var(--rj-red);border:2px solid #fff}
.rj-chat svg{width:26px;height:26px;fill:#fff}
.rj:is([data-stage="6"],[data-stage="7"]) .rj-chat{animation:rj-pop 480ms cubic-bezier(0.34,1.56,0.64,1) forwards}
@keyframes rj-pop{0%{transform:scale(0)}60%{transform:scale(1.18)}80%{transform:scale(0.94)}100%{transform:scale(1)}}

/* ============ CONTENT (aeo v2: the Main Line, feed-and-highlight) ============
   ROUND 13: the Bovender assembly section is replaced by the Main Line
   two-scene animation on The Meghan Chorin Team's live build; the v1
   section is archived at animations/integrated-v1/aeo-bovender.html and
   restores by splice. Grammar carried from the archive: the map's navy
   field, wave hatching, stroke weights and letterspaced caps labels; the
   bubble treatment; the flow-line draw with the traveling dot; the
   browser-frame chrome. GRAMMAR CHANGE (recorded): the pages here are
   LIVE and COMPLETE, so flow lines FEED a highlighted section instead of
   assembling the page; the assembly translation (placeholder slices
   fading to captures, the builder bot) is retired for live builds. Light
   section; the map and frame are dark artifacts with their palettes
   declared below (the archive's aeo values, renamed --aml-*). */
.aeo-mainline{padding:var(--sec-pad) 0;background:var(--field-2);overflow:hidden;
  --aml-gutter:32px;
  --aml-water:#10203A;--aml-land:#1A2C4E;--aml-isle:#162743;--aml-navy:#0A1628;
  --aml-chrome:#0D1A30;--aml-bar:#101F38;--aml-label:#C9CFDB;--aml-dim:#4B5468}
/* the round-4 head/stage layout carries over: compressed two-column head
   above the stage, the stage one full-width native unit (38fr/58fr, 4%
   gap); head stacks below 1100, the map column drops below 991. */
.aml-head{display:grid;grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr);gap:2rem 4rem;align-items:start}
.aml-head-copy .sec-sub{max-width:36em}
.aml-head-copy .sec-sub:first-child{margin-top:0}
.aml-stage{position:relative;margin-top:2rem}
.aml-cols{display:grid;grid-template-columns:38fr 58fr;column-gap:4%;align-items:stretch}
.aml-left{display:flex;flex-direction:column;min-height:0}
.aml-fade-up{opacity:0;transform:translateY(10px);will-change:opacity,transform}
/* the map: the Main Line as a drawn region; fills the column (the region
   wants vertical room for Newtown Square south of the rail), viewBox
   400x440 matching the column's ~0.91 aspect at 1440 */
.aml-map{position:relative;width:100%;flex:1 1 auto;min-height:340px;border-radius:12px;overflow:hidden;background:var(--aml-water);border:1px solid rgba(20,20,19,0.10)}
.aml-map svg{display:block;width:100%;height:100%}
.aml-map .map-label{font-family:var(--font);font-size:8px;letter-spacing:0.16em;text-transform:uppercase;fill:var(--aml-label);font-weight:500}
.aml-map .map-label--st{fill:rgba(201,207,219,0.55)}
.aml-map .map-river{font-family:var(--font);font-size:8px;letter-spacing:0.22em;text-transform:uppercase;fill:rgba(201,207,219,0.35);font-weight:500}
.aml-map .streets{stroke:rgba(201,207,219,0.16);stroke-width:0.8;fill:none;stroke-linecap:round}
.aml-map .road{stroke:rgba(201,207,219,0.22);stroke-width:1;fill:none;stroke-linecap:round}
.aml-map .rail{stroke:rgba(201,207,219,0.42);stroke-width:1.6;fill:none;stroke-linecap:round}
.aml-map .rail-on{stroke:rgba(201,207,219,0.3);stroke-width:1;fill:none;stroke-dasharray:3 3}
.aml-map .creek{stroke:rgba(92,144,255,0.20);stroke-width:1.4;fill:none;stroke-linecap:round}   /* dark map artifact: on-dark periwinkle triplet per the round-14 rule */
.aml-map .st-dot{fill:var(--aml-dim);stroke:var(--aml-land);stroke-width:1}
/* the two ACTIVE towns: focus is state, not camera. The label brightens
   and the focus ring DRAWS around the bead (dashoffset transition over
   the ring's 44px circumference); inactive towns rest dim. */
.aml-town .t-dot{fill:var(--aml-dim);stroke:var(--aml-land);stroke-width:1.5;transition:fill 0.3s}
.aml-town.is-focus .t-dot{fill:var(--peri-dark)}
.aml-town .t-ring{fill:none;stroke:var(--peri-dark);stroke-width:1;opacity:0;stroke-dasharray:44 44;stroke-dashoffset:44;transform-box:fill-box;transform-origin:center;transition:stroke-dashoffset 0.6s var(--ease),opacity 0.3s}
.aml-town.is-focus .t-ring{opacity:0.55;stroke-dashoffset:0}
.aml-town .map-label{transition:fill 0.3s}
.aml-town.is-focus .map-label{fill:#fff}
/* the browser frame: the archive chrome verbatim, renamed */
.aml-frame{position:relative;min-height:clamp(420px,58vh,620px);border-radius:12px;background:var(--aml-chrome);border:1px solid rgba(20,20,19,0.12);box-shadow:0 30px 80px rgba(0,0,0,0.25);display:flex;flex-direction:column;overflow:hidden}
.aml-bar{height:36px;flex:0 0 auto;display:flex;align-items:center;gap:8px;padding:0 12px;background:var(--aml-bar);border-bottom:1px solid rgba(255,255,255,0.08)}
.aml-dots{display:flex;gap:6px;margin-right:8px}
.aml-dots span{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,0.14);display:block}
.aml-url{flex:1 1 auto;height:22px;line-height:22px;background:rgba(255,255,255,0.06);border-radius:6px;padding:0 10px;font-size:11px;color:var(--aml-label);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.aml-url b{color:#fff;font-weight:500}
.aml-vp{position:relative;flex:1 1 auto;min-height:0;background-color:#fff;background-image:linear-gradient(rgba(10,22,40,0.05) 1px,transparent 1px),linear-gradient(90deg,rgba(10,22,40,0.05) 1px,transparent 1px);background-size:24px 24px;overflow:hidden}
.aml-vp .aml-gutter-col{position:absolute;left:0;top:0;bottom:0;width:var(--aml-gutter);background:#f4f5f8;border-right:1px solid rgba(10,22,40,0.08)}
/* two capture layers crossfading; each is a live page REGION: the layer
   holds its scene's fixed scroll, highlights ride the same transform in
   capture coordinates */
.aml-page{position:absolute;left:var(--aml-gutter);top:0;width:1440px;transform-origin:0 0;will-change:transform,opacity;opacity:0}
.aml-page img{display:block;width:1440px;height:auto}
.aml-hl{position:absolute;border:2px solid var(--peri);background:rgba(92,144,255,0.06);border-radius:6px;opacity:0;will-change:opacity}
.aml-overlay{position:absolute;inset:0;pointer-events:none;overflow:visible}
html svg.aml-overlay{overflow:visible}   /* Webflow-proof (round 30): the published base sheet's svg:not(:root){overflow:hidden} is 0,1,1 and beats the class rule above; this is 0,1,2 and wins by specificity. Local no-op. */
/* the flow lines originate and spend their drama on the dark map, so they
   take the on-dark variant for their whole traversal (judgment recorded:
   #5C90FF still reads as the accent over the white captures they land on);
   the .aml-hl highlights RIDE the light captures and keep --peri */
.aml-overlay path{fill:none;stroke:var(--peri-dark);stroke-width:1.5;stroke-linecap:round;opacity:0}
.aml-overlay circle.dot{fill:var(--peri-dark);opacity:0;filter:drop-shadow(0 0 5px rgba(92,144,255,0.9))}
.aml-bubbles{position:absolute;inset:0;pointer-events:none}
.aml-bubble{position:absolute;max-width:220px;padding:8px 11px;background:#fff;color:var(--aml-navy);font-size:13px;line-height:1.3;border-radius:12px;box-shadow:0 6px 18px rgba(0,0,0,0.28),0 1px 3px rgba(0,0,0,0.2);opacity:0;transform:scale(0.6);will-change:transform,opacity}
.aml-bubble .tail{position:absolute;width:10px;height:10px;background:#fff;transform:rotate(45deg)}
.aml-stage.is-nomap .aml-bubbles,.aml-stage.is-nomap .aml-overlay{display:none}
@media (max-width:1100px){.aml-head{grid-template-columns:1fr;gap:1rem}.aml-cols{grid-template-columns:1fr;row-gap:2rem}}
@media (max-width:991px){.aml-left{display:none}}
/* ROUND 41 / 42: AML MOBILE, THE STACKED TRANSLATION, the standard phone
   rendering (round 41 built it dormant behind ?aml=m / ?exploded=c; round 42
   enabled it on Max's phone verdict and stripped the params). Before it the
   phone view showed the browser panel alone (the map column hides under
   991, is-nomap hides bubbles and lines): the story was amputated. The aml
   IIFE arms .is-m on the stage at a phone width (max-width 767, matched
   once); on desktop no rule here matches. Restaged vertically: the SAME map
   svg becomes a WIDE STRIP (the IIFE re-crops its viewBox to 0 100 400 216,
   the rail spine west to east with Newtown Square south of it; slice on an
   exact 400/216 box, so nothing is distorted) above a compact browser panel
   (300px, the same capture regions at the narrower scale, the page gutter
   column 18px). Labels step up so they stay legible at the strip's ~0.88
   scale (towns 12px -> ~10.5px rendered, stations 11.5px -> ~10px); the
   bubbles are the shipped treatment scaled down (12px, 156px max); the
   flow lines drop DOWN from each bubble's bottom edge into the panel (the
   IIFE's vertical path variant) where the shipped highlight pulse lands.
   Reduced motion: the same single settled frame, stacked. */
@media (max-width:767px){
  .aml-stage.is-m{--aml-gutter:18px}
  .aml-stage.is-m .aml-cols{row-gap:14px}
  .aml-stage.is-m .aml-left{display:flex}
  .aml-stage.is-m .aml-map{flex:none;min-height:0;height:auto;aspect-ratio:400/216}
  .aml-stage.is-m .aml-map .map-label{font-size:12px}
  .aml-stage.is-m .aml-map .map-label--st{font-size:11.5px}
  .aml-stage.is-m .aml-map .map-label--st[transform]{display:none}   /* the rotated Center City label straddles the strip's top edge; its grid patch still orients the region */
  .aml-stage.is-m .aml-frame{min-height:0;height:300px;box-shadow:0 18px 44px rgba(0,0,0,0.22)}
  .aml-stage.is-m .aml-bubble{max-width:156px;padding:6px 9px;font-size:12px;border-radius:10px}   /* 156: two bubbles sit side by side inside the 324px strip at 360 with a 12px gap */
}
@media (prefers-reduced-motion: reduce){.aml-town .t-dot,.aml-town .t-ring,.aml-town .map-label{transition:none}}
/* ============ EXAMPLES (ambient gallery) ============
   ROUND 14: FIVE live builds as browser-framed cards whose full-page
   captures (assets/site/examples/, from tools/capture-examples.mjs) pan
   top to bottom and back at a very slow constant drift: a CSS keyframe on
   the image (translateY to --pan, ease-in-out for the turnarounds,
   alternate), distance measured by JS per frame (capture height at
   rendered width minus the frame's viewport), attached paused and running
   only while the frame is on screen (IntersectionObserver toggles .is-run;
   will-change rides .is-run only). Durations stagger 45/52/60/47/56s per
   descent (inline --dur), five distinct values so no pair syncs. Reduced
   motion: no animation, each capture rests at the top of its page. No-JS:
   --pan stays 0, static.
   GRID (round-14 choice, DOM-metric at 1440 and 1536): 3+2, a flex row
   at the three-up card width with the two overflow cards CENTERED on the
   second row at the same size (legibility over density: a 5-up would put
   each capture at ~225px, under the ~320px card-image floor). Stacked
   below 1100 as before. The launching-soon pair (Carrie McCormick, Andy
   Bovender) is REMOVED per Mark's review; they return as FULL cards when
   their sites are live (the archive rule already covers their animations). */
.exg-row{list-style:none;margin-top:3rem;display:flex;flex-wrap:wrap;justify-content:center;gap:2rem}
.exg-row>li{width:calc((100% - 4rem)/3)}
.exg-frame{margin:0;border:1px solid var(--hair-strong);border-radius:12px;overflow:hidden;background:var(--field-3);box-shadow:0 18px 44px rgba(0,0,0,0.10)}
.exg-bar{display:flex;align-items:center;gap:6px;height:30px;padding:0 12px;background:var(--field);border-bottom:1px solid var(--hair)}
.exg-bar span{width:8px;height:8px;border-radius:50%;background:var(--hair-strong)}
.exg-view{position:relative;aspect-ratio:3/4;overflow:hidden}
.exg-view img{display:block;width:100%;height:auto}
@keyframes exg-pan{from{transform:translateY(0)}to{transform:translateY(var(--pan,0px))}}
body.js .exg-view img{animation:exg-pan var(--dur,52s) ease-in-out infinite alternate;animation-play-state:paused}
body.js .exg-view.is-run img{animation-play-state:running;will-change:transform}
@media (prefers-reduced-motion: reduce){body.js .exg-view img{animation:none;will-change:auto}}
.exg-name{margin-top:1.4rem}
.exg-name a{display:inline-flex;align-items:center;gap:0.7rem;font-family:var(--serif);font-weight:600;font-size:1.35rem;letter-spacing:var(--track-h3);color:var(--lt);transition:color 0.3s var(--ease)}
.exg-name a:hover,.exg-name a:focus-visible{color:var(--peri)}
.exg-name .arr{display:inline-block;transition:transform 0.4s var(--ease)}
.exg-name a:hover .arr,.exg-name a:focus-visible .arr{transform:translateX(6px)}
.exg-metric{margin-top:0.4rem;font-size:var(--t-body);color:var(--lt-2)}
/* the market-line register (cards whose lines state a market, not a
   citation claim); the round-14 soon-card rules are deleted with the pair */
.exg-market{margin-top:0.4rem;font-size:var(--t-small);color:var(--lt-3)}
@media (max-width:1100px){.exg-row>li{width:100%}}
@media (prefers-reduced-motion: reduce){.exg-name a,.exg-name .arr{transition:none}}

/* ============ PROCESS (drawn timeline) AND OWNERSHIP CODA ============
   Four phases on one connector line that draws across as the section
   enters (scaleX on .proc-draw, keyed off the .rv observer's .is-in on
   the wrapper; .rv-none suppresses the wrapper's own fade so only the
   line and the staggered phases move). Each phase lights in sequence
   (opacity/translate with an inline --d delay). Below 991 the columns
   win: the draw line hides and per-step top rules return; the phase
   stagger carries the sequence. Reduced motion and no-JS: line drawn,
   phases visible, nothing moves. NO week ranges anywhere (round-3 rule).
   The section carries page-sec + page-sec--alt so the standard --sec-pad
   token applies: round 2 shipped the modifier alone, which set only the
   background and left the section unpadded (the head sat on the top seam
   and the ownership trio sat on the cream/white boundary below). */
body.js .rv-none{opacity:1;transform:none;transition:none}
.proc-tl{position:relative;margin-top:3rem}
.proc-draw{position:absolute;left:0;top:0;height:2px;width:100%;background:var(--hair-strong);transform-origin:0 50%}
body.js .proc-tl .proc-draw{transform:scaleX(0);transition:transform 1.6s var(--ease)}
body.js .proc-tl.is-in .proc-draw{transform:scaleX(1)}
.proc-steps{list-style:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.6rem}
.proc-step{position:relative;padding-top:1.6rem}
.proc-step::before{content:"";position:absolute;left:0;top:-4px;width:10px;height:10px;border-radius:50%;background:var(--peri)}
body.js .proc-tl .proc-step{opacity:0;transform:translateY(14px);transition:opacity 0.7s var(--ease) var(--d,0s),transform 0.7s var(--ease) var(--d,0s)}
body.js .proc-tl.is-in .proc-step{opacity:1;transform:none}
.proc-num{font-size:var(--t-label);letter-spacing:var(--track);text-transform:uppercase;color:var(--peri);font-weight:var(--w-6)}
.proc-step h3{margin-top:0.6rem;font-family:var(--serif);font-weight:600;font-size:1.2rem;letter-spacing:var(--track-h3)}
.proc-step p{margin-top:0.5rem;color:var(--lt-2);font-size:var(--t-body)}
/* CMS band (round 5): the capture never lives inside a timeline column.
   It broke the row's text-equal balance, so it gets its own compact
   two-column band between the timeline and the ownership trio (same
   cream ground, this section). Image left at half the content width in
   the portal-device frame; head, one paragraph, caption and demo link
   right. Stacked below 1100, image first (DOM order). */
.proc-cms{margin-top:5rem;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:4rem;align-items:center}
.proc-cms-media{margin:0}
.proc-cms-media img{display:block;width:100%;height:auto;border-radius:8px;border:1px solid var(--hair-strong);box-shadow:0 12px 30px rgba(0,0,0,0.12)}
.proc-cms-copy h3{font-family:var(--serif);font-weight:600;font-size:1.2rem;letter-spacing:var(--track-h3)}
.proc-cms-lede{margin-top:0.6rem;color:var(--lt-2);font-size:var(--t-body)}
.proc-cms-cap{margin-top:1.6rem;font-size:var(--t-small);color:var(--lt-3)}
.proc-demo{margin-top:0.9rem}
@media (max-width:1100px){.proc-cms{grid-template-columns:1fr;gap:1.8rem}}
.own{margin-top:5rem;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2.4rem;border-top:1px solid var(--hair-strong);padding-top:2.4rem}
.own h3{font-family:var(--serif);font-weight:600;font-size:1.2rem;letter-spacing:var(--track-h3)}
.own p{margin-top:0.6rem;color:var(--lt-2);font-size:var(--t-body)}
@media (max-width:991px){
  .proc-draw{display:none}
  .proc-steps{grid-template-columns:1fr 1fr}
  .proc-step{border-top:2px solid var(--hair-strong);padding-top:1.2rem}
  .proc-step::before{display:none}
  .own{grid-template-columns:1fr;gap:1.8rem}
}
@media (max-width:600px){.proc-steps{grid-template-columns:1fr}}
@media (prefers-reduced-motion: reduce){
  body.js .proc-tl .proc-draw{transform:scaleX(1);transition:none}
  body.js .proc-tl .proc-step{opacity:1;transform:none;transition:none}
}

/* ============ DECISION BAND (price card + website questions) ============
   The from-$9,997 block and the four-question accordion merged into one
   closing band: price card left, FAQ right under a compact head INSIDE
   the right column. Round 2 shipped the FAQ on the shared .faq-body grid
   with the h2 at --t-disp2 in a minmax(0,0.55fr) column: the heading's
   non-breaking join made it one unbreakable token wider than the column,
   and minmax(0,...) let the column shrink under it, so the h2 painted
   across the gap into the accordion (stickily). The compact in-column
   head removes the collision class entirely. */
.dec-grid{display:grid;grid-template-columns:minmax(0,0.9fr) minmax(0,1.1fr);gap:4rem;align-items:start}
/* round 5: six questions run ~200px taller than the price card at 1440, so
   the card rides sticky within the band (87px = the rendered .nav-bar
   height, the fixed bar's clearance; arithmetic in concept-6c's proof
   tight-pin comment). Below 1100 the band stacks and sticky is inert
   against the 1fr column, but the top offset is scoped to desktop anyway. */
.dec-price{border:1px solid var(--hair-strong);border-radius:12px;background:var(--field);padding:2.6rem;position:sticky;top:calc(87px + 2rem)}
@media (max-width:1100px){.dec-price{position:static}}
.wprice-lock{font-family:var(--serif);font-weight:600;font-size:var(--t-disp2);letter-spacing:var(--track-serif);line-height:var(--lh-disp);white-space:nowrap}
.wprice-unit{margin-top:0.7rem;font-size:var(--t-small);letter-spacing:0.08em;text-transform:uppercase;color:var(--lt-3)}
.dec-price .prose{margin-top:1.6rem}
.dec-faqh{font-family:var(--serif);font-weight:600;font-size:1.5rem;letter-spacing:var(--track-h3);margin-bottom:1.4rem}
@media (max-width:1100px){.dec-grid{grid-template-columns:1fr;gap:2.6rem}}
