/* Vanity Ink: Home (v2 flow, pass 3: black stages).
   The marble canvas shows in the interludes (statement + reel, expect, process, final CTA). Sections that carry photos
   (hero, artists, cover-ups, studio, visit) sit on a true-black stage with feathered edges, so photos never blend into
   the swirl and nothing cuts off. Photos have clean edges (no fades into the marble). Each block notes its Elementor route. */
:root{--bleed:calc((100vw - min(100vw, calc(var(--container) + var(--gutter) * 2))) / 2 + var(--gutter))}

/* ===== 1 · Hero: centered over the real room, on its own black base =====
   Elementor: container min-height 100vh, background image (the room) + background overlay gradient, black background
   color, content centered. Unlike the inner pages (left-aligned H1 over a still life), Home is centered and full-bleed. */
.hero{position:relative;isolation:isolate;min-height:100svh;display:flex;align-items:center;justify-content:center;text-align:center;
  padding:150px 0 170px;background:var(--black);overflow:hidden}
.hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 58%;z-index:-2;filter:saturate(.85) brightness(.78) contrast(1.05)}
/* a dark pool behind the centered text + a low-opacity veil over the room; the bottom ends in solid black */
.hero::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:
  radial-gradient(ellipse 62% 56% at 50% 50%,rgba(6,6,7,.86),rgba(6,6,7,.56) 70%,rgba(6,6,7,.34)),  /* deeper behind the words (10-02) */
  linear-gradient(180deg,rgba(6,6,7,.55) 0%,rgba(6,6,7,.12) 26%,rgba(6,6,7,.2) 62%,var(--black) 90%)}
.hero-copy{max-width:1040px;margin:0 auto}  /* wide enough for the tagline with its gems (10-02); the subhead keeps its own 600 */
/* 10-02 (Carlos: the old split made "WHEAT RIDGE, CO" the headline, "like it's announcing the city and state"): the copy's
   H1 stays word for word as the small line, in the brand violet, and the big line is the logo's own tagline, "Art.
   Precision. Passion." (About explains it), its words parted by the separator's purple gem (Carlos 10-02: the diamond "in
   place of the dots"; `assets/brand/gem-2x.png`, cut from separator-2x.png). Screen readers get the plain sentence. SEO
   keeps the H1 and the meta title as they were. Elementor: a Heading widget (H1) styled as the small line, then a row
   (flex container, centred, gap) of three Heading widgets and two Image widgets (the gem); on phones the row stacks. */
.hero h1{background:none;-webkit-text-fill-color:currentColor;filter:none;margin:0 0 18px;color:var(--purple-light);
  font-size:clamp(14px,1.35vw,19px);line-height:1.5;letter-spacing:.3em;text-indent:.3em;text-wrap:balance}
.hero-tag{display:flex;justify-content:center;align-items:center;gap:.4em;margin:0 0 30px;font:500 clamp(30px,3.9vw,60px)/1.08 var(--display);text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;
  background-image:var(--chrome),var(--brushed);background-size:100% 1lh,auto;background-repeat:repeat-y,repeat;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:#DADAE0;
  filter:drop-shadow(0 1px 0 rgba(0,0,0,.6)) drop-shadow(0 12px 28px rgba(0,0,0,.6))}
.hero-tag .gem{flex:none;width:auto;height:.6em;transform:translateY(-.04em)}  /* centred on the caps */
.hero .sub{max-width:600px;margin:0 auto 40px;font-size:var(--body);color:#C4C4CB;text-wrap:pretty}
.hero-actions{display:flex;justify-content:center;align-items:center;gap:32px;flex-wrap:wrap}

/* Stages (.stage) and marble sections (.marble) are shared: see vanity.css.
   Home's river, round 2 (09-29): cuts of the original canvas (Carlos preferred its look), placed so they flow:
   - .flow-idea wraps Your Idea + Meet Your Artist: the river enters on the left right under the hero (a short fade,
     no big black gap), runs behind the reel and on down the right side of the artists, dimmed under the portraits
     so it still shows faintly beneath them;
   - Cover-ups carries a dim strip of marble at its top (.m-under), so the stage isn't flat black;
   - .flow-steps wraps What You Can Expect + the Process: one S-curve of the river through both, behind the list too.
   The mask stops are tuned at 1440 wide (the fades follow the section edges closely enough at 1280 to 1920).
   Elementor: outer containers with the background image and a gradient overlay (same stops). */
/* Less dark (10-02; Carlos after the 09-30 meeting: "just bump up the brightness or reduce the dark overlay").
   The same river, the same places and the same canvas grade, lifted with three knobs and one image step:
   --m-dim    the level of the river beneath the portraits (Meet: was .42 to .46; now its own layer, below, at .72:
              Carlos 10-02, a notch down so it matches the river above and below instead of standing out)
   --m-under  the opacity of an underlay beneath a photo section on its own (Cover-ups; was .5)
   --m-rise   how far above its section the pre-footer's finale starts rising, up behind Visit's map (was 0; the
              finale sits half of it higher against the call to action, 120px here)
   the -b files: the same grade with gamma 1.35 and vgain 1 (was 1.55, .85; same saturation and veil), each ending
   in black (no line where a cut runs out before its section, at 1280 and below) and nothing darker than the page.
   Rollout (10-02): --m-dim and --m-under live in vanity.css :root, and every page's dimmed stops and underlays read them.
   Elementor: --m-under = the Background Overlay opacity; the stops = the overlay gradient or baked (5.3); --m-rise = the
   CTA container's margin-top -240px and padding-top +240px, with Visit's container one z-index above it (so the map and
   text paint over the rising marble; the footer already overlaps the CTA this way). */
:root{--m-rise:240px}
.c-home-idea{--mimg:url(../assets/marble/c-home-idea-b.webp)}
.c-home-flow{--mimg:url(../assets/marble/c-home-flow-b.webp)}
.c-home-cover{--mimg:url(../assets/marble/c-home-cover-b.webp)}
.cta-final.m-finale{--mimg:url(../assets/marble/finale-home-b.webp)}
/* Your Idea's river: unchanged down to the reel (the join under the hero as approved), then it fades out under Meet's
   own river, which rises over it (below) */
.flow-idea{--mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.55) 45px,#000 110px,#000 1010px,rgba(0,0,0,.5) 1500px,transparent 1800px)}
/* Meet's own river (10-02; Carlos: "especially where you start to see Jeremy and Kain's profiles"). The original cut
   runs out before Kain, and its lower half is the S-curve the Process shows, so Meet gets its own layer: strip
   2720-5120, mirrored, with the same grade and step. Honest note (review, 10-02): mirrored, it is still the Process's
   lower S-curve (behind Jeremy) and Expect's opening stretch (behind Kain); no unused stretch is long enough, the
   approved page already showed that S-curve under Meet (dimmed), and Cover-ups is the Process's D stretch mirrored.
   Scrolling it doesn't read as a repeat; side by side it does. A fresh generated stretch is the alternative (Carlos's
   call, API spend). The layer is opaque (the
   marble over the page black) and rises over 380px at Meet's top: it dissolves over Your Idea's river and then covers
   it, so the two read as one river at every width. At the bottom it runs 240px on under Cover-ups' top (160px on
   phones) and fades out over 440px across the join, while Cover-ups' own river rises over it: the two overlap instead
   of meeting in a band of black (Carlos 10-02: continuous, not stitched).
   --m-dim sets its level: a black overlay of 1 - --m-dim over the marble (none at 1). Pools keep the artist text dark.
   Elementor: Meet's container: background image (the cut), NO background colour (the image is opaque), with the 380px
   rise baked into the image's alpha (Your Idea's river is still about 96% strong there, so a colour under the alpha
   would end it in a line); from 1280 up the image runs past Meet's end, so the bottom fade is route B's mask line or
   the native fallback: an absolute container at Meet's bottom with a 2-stop gradient to #060607. The 240px tail: Meet's
   container padding-bottom +240px and Cover-ups' container margin-top -240px, one z-index above Meet. */
.c-home-meet{--mimg:url(../assets/marble/c-home-meet-b.webp)}
.artists-flow{--mop:1;--mtail:240px;
  --mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.12) 99px,rgba(0,0,0,.5) 198px,rgba(0,0,0,.88) 296px,#000 380px,#000 calc(100% - 440px),rgba(0,0,0,.88) calc(100% - 343px),rgba(0,0,0,.5) calc(100% - 211px),rgba(0,0,0,.12) calc(100% - 114px),transparent 100%);
  --mmask-m:linear-gradient(180deg,transparent 0,rgba(0,0,0,.12) 94px,rgba(0,0,0,.5) 187px,rgba(0,0,0,.88) 281px,#000 360px,#000 calc(100% - 320px),rgba(0,0,0,.88) calc(100% - 250px),rgba(0,0,0,.5) calc(100% - 154px),rgba(0,0,0,.12) calc(100% - 83px),transparent 100%)}
.artists-flow::after{bottom:calc(0px - var(--mtail));background:linear-gradient(rgb(6 6 7/calc(1 - var(--m-dim))),rgb(6 6 7/calc(1 - var(--m-dim)))),var(--mimg) no-repeat var(--mpos,center top)/var(--msize,100% auto) var(--black)}
.coverups{--mop:var(--m-under)}
/* the lower Process: full 100px longer, a softer end (was full to 100% - 300px, .4 at 100% - 140px).
   10-02 late (Carlos: it "blends weirdly... towards the bottom of the From Consultation to Finished" section): the
   river no longer stops at the wrapper's end while the studio's own river rises 240px into it (two swirls crossfading
   over each other). It runs on --steps-tail past the wrapper, over the studio's top (under its words and photo), and
   eases out there over the same 200px + the tail, with the same eased stops as every other fade; from about 1480 up
   the studio's river starts at its own top, on the dark part of its cut (the Process's tail trails over it, and the
   studio's lobe takes over on the right), so the two hand off instead of crossfading (narrower, see .home-studio).
   Desktop and tablet; phones keep the default fades. Elementor: the wrapper's padding-bottom +240px (its image runs on)
   and the studio container's margin-top -240px / padding-top +240px, the studio one z-index above the wrapper (as
   Cover-ups over Meet), its own river's top fade baked into its image (route A) so the tail shows through it; the
   Process's last step ends 160px above the seam, so only that faded top ever reaches it. */
.flow-steps{--steps-tail:240px;--mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.5) 80px,#000 210px,#000 calc(100% - var(--steps-tail) - 200px),rgba(0,0,0,.88) calc(100% - (var(--steps-tail) + 200px) * .78),rgba(0,0,0,.5) calc(100% - (var(--steps-tail) + 200px) * .52),rgba(0,0,0,.12) calc(100% - (var(--steps-tail) + 200px) * .26),transparent 100%)}
@media (min-width:768px){.flow-steps::before{bottom:calc(0px - var(--steps-tail))}}
/* the finale starts rising --m-rise earlier, behind Visit's map and text (its layer joins the page's stacking order,
   so it paints under Visit's content instead of over it); the fade is that much longer, so it still reaches full
   where it did (230px into its section) */
.cta-final{isolation:auto;--mlift:var(--m-rise);--mt:calc(var(--m-rise) + 230px)}

/* ===== 2 · Statement + work reel (marble interlude) =====
   The reel is a carousel: same-size cards (no staggered sizes), arrows at the sides on hover, swipe on phones, and a
   gentle autoplay that moves one card every few seconds and pauses on hover or touch (js/site.js).
   Elementor: Loop Carousel (or Image Carousel): 4 slides + offset on the right, arrows, autoplay ~4s, pause on hover,
   infinite loop. All native. */
.statement{position:relative;padding:150px 0 0}
.stmt{max-width:720px}   /* on the container's left edge like every other section head (10-13 audit) */
.stmt h2{margin-bottom:24px}
.stmt p{max-width:640px;text-wrap:pretty}

.reel-wrap{position:relative;margin-top:88px}
.reel{overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scroll-padding-inline:var(--bleed);scrollbar-width:none;overscroll-behavior-x:contain;padding:24px 0 96px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent);mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent)}
.reel::-webkit-scrollbar{display:none}
.reel-track{display:flex;gap:24px;width:max-content;padding:0 var(--bleed)}
.reel li{flex:none;width:clamp(220px,20vw,300px);scroll-snap-align:start}
.reel .shot{display:block;aspect-ratio:4/5;box-shadow:0 24px 60px rgba(0,0,0,.55)}
.reel-nav{position:absolute;top:calc(50% - 36px);z-index:3;width:52px;height:52px;display:grid;place-items:center;transform:translateY(-50%);
  border:1px solid rgba(200,200,204,.55);background:rgba(6,6,7,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:var(--text);
  opacity:0;transition:opacity .3s var(--ease),border-color .3s,color .3s}
.reel-nav.prev{left:max(10px,calc(var(--bleed) - 26px))}
.reel-nav.next{right:max(10px,calc(var(--bleed) - 26px))}
.reel-wrap:hover .reel-nav,.reel-nav:focus-visible{opacity:1}
.reel-nav:hover{background:var(--chrome-fill);border-color:#EDECF1;color:#0B0B0D}
.reel-nav svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:square}
@media (hover:none){.reel-nav{display:none}}

/* ===== 3 · Artists (black stage): heading first, then portrait left with Jeremy and Kain beside it =====
   Elementor: container grid 5fr/7fr; the portrait spans two rows. The name sits flush with the bio (Carlos, 09-24:
   the name crossing into the photo read as odd). Actions are real buttons + the Instagram link (no animated text
   link; Carlos, 09-29), stacked the same way for both artists: the button, then the handle under it.
   Kain mirrors Jeremy at a smaller size (his own profile, not an afterthought). */
.artists-flow{padding-top:160px;padding-bottom:160px}
.art-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);column-gap:72px;align-items:start}
.art-intro{grid-column:1/-1;max-width:700px;margin-bottom:64px}
.art-intro .lead{margin:0}
.art-portrait{grid-column:1;grid-row:2/span 2;display:block;aspect-ratio:4/5}
.art-body{grid-column:2;grid-row:2;padding-top:40px;max-width:600px}
.role{display:block;font:500 11px/1 var(--sans);letter-spacing:.3em;text-transform:uppercase;color:var(--purple-light)}
.art-name{font-size:clamp(44px,3.9vw,58px);line-height:1.08;margin:16px 0 22px}
.art-body p{max-width:540px;text-wrap:pretty}
.art-actions{display:flex;flex-direction:column;align-items:flex-start;gap:14px;margin-top:28px}
.art-second{grid-column:2;grid-row:3;display:grid;grid-template-columns:190px minmax(0,1fr);gap:36px;align-items:center;max-width:620px;margin-top:56px;padding-top:44px;position:relative}
.art-second::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;background:linear-gradient(90deg,rgba(200,200,204,.45),transparent 80%)}
.kain-shot{aspect-ratio:4/5}
.art-second h3{font-size:34px;line-height:1.1;margin:12px 0 14px}
.art-second p{font-size:var(--body-sm);text-wrap:pretty}
.art-second .art-actions{margin-top:20px}
.artists-foot{margin:144px auto 0;text-align:center;max-width:640px;text-wrap:pretty}

/* ===== 4 · Cover-ups (black stage): the "after" large, the "before" as an inset crossing the seam =====
   Pattern from Human Rights Tattoo (references/fable-references/tattoo-awwwards.md #3).
   Elementor: two Image widgets; the inset gets Position: Absolute, offsets, Z-Index and a Box Shadow. */
.coverups{padding-top:120px;padding-bottom:160px}
.cov-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:0 88px;align-items:center}
.cov-text{max-width:560px}
.cov-text .btn{margin-top:12px}
.cov-media{position:relative;justify-self:end;width:min(100%,460px);margin-left:110px}
.cov-after{aspect-ratio:492/750}
.cov-before{position:absolute;left:-110px;bottom:-56px;width:clamp(160px,14vw,210px);aspect-ratio:4/5;z-index:3;box-shadow:0 0 50px #000}
.cov-before::before{border-color:rgba(200,200,204,.35)}
.cov-after figcaption,.cov-before figcaption{position:absolute;left:12px;bottom:10px;z-index:1;font:500 10px/1 var(--sans);letter-spacing:.3em;text-transform:uppercase;color:var(--text);text-shadow:0 1px 8px #000}
/* the inset covers the after's bottom-left on desktop, so its label moves right (back left once the inset flips right) */
.cov-after figcaption{left:auto;right:14px}

/* ===== 5 · What You Can Expect (marble interlude): sticky heading, commitments scroll past it =====
   Each commitment comes into focus as it passes the middle of the screen (full brightness, its hairline draws out)
   and dims as it leaves, so the list reads one promise at a time beside the sticky heading.
   Elementor: 2 columns; left column Sticky (Motion Effects > Sticky); each item Motion Effects > Scrolling Effects >
   Transparency (fade in, then out). The hairline draw is optional custom CSS. */
.expect{padding-top:180px}
.expect-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:64px;align-items:start}
.expect-head{position:sticky;top:150px}
.expect-head h2{max-width:460px}
.expect-list li{padding:40px 0 44px;position:relative}
.expect-list li::before{content:"";position:absolute;left:0;top:0;right:0;height:1px;transform-origin:left;background:linear-gradient(90deg,rgba(200,200,204,.55),rgba(136,88,184,.35) 45%,transparent 85%)}
.expect-list h3{font-size:var(--h3);margin-bottom:16px}
.expect-list p{max-width:580px;text-wrap:pretty}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference) and (min-width:1024px){
    .expect-list li{view-timeline:--commit block;animation:commit-focus linear both;animation-timeline:--commit;animation-range:cover 0% cover 100%}
    .expect-list li::before{animation:commit-line linear both;animation-timeline:--commit;animation-range:entry 0% cover 45%}
  }
}
@keyframes commit-focus{0%{opacity:.25}30%,62%{opacity:1}100%{opacity:.25}}
@keyframes commit-line{from{transform:scaleX(.12)}to{transform:scaleX(1)}}

/* ===== 6 · Process (marble interlude): one line through four steps, a plain dot at each =====
   Elementor: the line is one SVG image behind a 2-column zig-zag; the dots are small circles (Divider or Icon);
   the draw-on-scroll is optional custom CSS (or a Lottie widget with a Scroll trigger). */
.process{padding-top:180px}
.process-h{text-align:center;max-width:780px;margin:0 auto 24px}
.vein-wrap{position:relative;max-width:1000px;margin:0 auto;view-timeline:--vein block}
.vein{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.vein-path{fill:none;stroke:url(#veinGrad);stroke-width:1.5;vector-effect:non-scaling-stroke;opacity:.85}
.vein-steps{position:relative;display:grid;gap:24px;padding:96px 0 40px}
.vstep{position:relative;width:min(440px,48%);padding:28px 0}
.vstep:nth-child(odd){justify-self:start}
.vstep:nth-child(even){justify-self:end}
.vstep::before{content:"";position:absolute;inset:-10% -12%;z-index:-1;background:radial-gradient(closest-side,rgba(6,6,7,.9),rgba(6,6,7,0))}
/* process markers: small flat-top hexagons like the honeycomb cells (Carlos, 09-30: "same shape... instead of a circle
   it's a honeycomb"), the same light core, dark gap and violet outline the dots had. Elementor: the SVG as an Image. */
.node{position:absolute;left:var(--x);top:var(--y);width:24px;height:24px;transform:translate(-50%,-50%);z-index:1;pointer-events:none;
  background:url(../assets/brand/hex-node.svg) center/contain no-repeat}
.vstep .num{display:block;font:400 96px/1.1 var(--display);margin-bottom:6px}
.vstep h3{font-size:var(--h3);margin-bottom:14px}
.vstep p{font-size:var(--body-sm);text-wrap:pretty}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .vein-path{stroke-dasharray:1;stroke-dashoffset:1;animation:vein-draw linear both;animation-timeline:--vein;animation-range:entry 20% exit 70%}
  }
}
@keyframes vein-draw{to{stroke-dashoffset:0}}

/* ===== 7 · Studio (the shared .studio in site.css; 10-02 late: a registered bleed, flipped) =====
   The photo left, out to the left edge, its top edge on the H2's cap line; the words right on a pool. Studio (photo
   left) and Visit (map right) alternate instead of reading as twins on one grid. Its own river (c-home-studio-b: Home's
   brighter step, strip 640-2440 mirrored, tools/imagegen/cut_studio.py) enters top right, behind the words. */
.home-studio{--mimg:url(../assets/marble/c-home-studio-b.webp);--s-pos:0% 50%}
/* the rise follows the Process's image, which is width-scaled while its wrapper is not (about 3110px at every desktop
   width): from about 1480 up the image runs on past the wrapper, so its tail covers the join and this river starts
   at its own top; narrower, the image ends before the wrapper does (224px above it at 1280, 38 at 1366), so this river
   rises into that gap, as before (240px at 1280 and below) */
@media (min-width:768px){.home-studio{--s-up:clamp(0px,(1480px - 100vw) * 1.2,240px);--s-in:340px;--s-out:300px}}
/* below: the river runs on 160px under Visit's top (something crosses that seam too) and is gone 37px before its heading;
   the shade sits behind the words, not the photo: the photo is opaque and its free edges sit on the dark part of the
   cut, while the cut's bright lobe runs behind the words' right end (body text 6.5:1 or better from 1280 to 1920, the
   eyebrow 6.1:1) */
@media (min-width:1024px){.home-studio{--s-down:160px;--s-shade:74% 40%}}

/* ===== 9 · Visit (black stage): details left, Google's regular map right =====
   The details are the block Contact shares (site.css, "the visit details", 10-02 late), the map frame too.
   Elementor: 2-column container; the saved details template; Google Maps widget. */
.visit-home{padding:160px 0}
.visit-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:72px;align-items:center}
.visit-info h2{margin-bottom:26px}

/* ===== 10 · Final CTA (marble interlude): the heading sits on two lines =====
   Home's own ending (10-02: the inner pages keep their strip, pages.css, so Home's centred call stays its own). The
   button and the phone link under it: .cta-actions and .call-link, site.css. */
.cta-final{position:relative;padding:220px 0 240px;text-align:center}
.cta-inner{max-width:900px;margin:0 auto}
.cta-inner h2{margin-bottom:30px}
/* the logo separator, centred under the two-line heading (Carlos 10-02): 360 wide, well short of the heading's lines, as in
   the logo, where the mark is shorter than the name. Elementor: Image widget, centred, width 360 / 300 / 240. */
.cta-inner .sep{width:360px;margin:-12px auto 30px}
.cta-inner p{max-width:560px;margin:0 auto 44px;text-wrap:pretty}

/* ===== Responsive ===== */
@media (max-width:1023px){
  .cta-inner .sep{width:300px}
  .hero{padding:140px 0 140px;min-height:88svh}
  .statement{padding-top:96px}
  .stmt{margin-left:0}
  .art-grid{grid-template-columns:minmax(0,1fr)}
  .art-intro{margin-bottom:40px}
  .art-portrait,.art-body,.art-second{grid-column:1;grid-row:auto}
  .art-portrait{max-width:520px}
  .art-body{padding-top:32px}
  .cov-grid{grid-template-columns:1fr;gap:48px}
  .cov-media{justify-self:start;margin-left:0;width:min(100%,420px)}
  .cov-before{left:auto;right:-20px;bottom:-40px}
  .cov-after figcaption{left:12px;right:auto}
  .expect-grid{grid-template-columns:1fr;gap:24px}
  .expect-head{position:static}
  .visit-grid{grid-template-columns:1fr;gap:48px}
}
@media (max-width:767px){
  .cta-inner .sep{width:240px;margin:-10px auto 24px}
  .hero{padding:120px 0 110px;min-height:80svh}
  .hero-tag{flex-direction:column;gap:.16em;white-space:normal}
  .hero-tag .gem{height:.46em;transform:none}
  .reel-wrap{margin-top:56px}
  .reel{padding-bottom:64px}
  .reel li{width:62vw}
  /* Kain stacks like Jeremy: photo, then text (side by side, the button had no room) */
  .art-second{grid-template-columns:1fr;gap:22px}
  .kain-shot{width:180px}
  .art-second h3{font-size:30px}
  .cov-before{right:-8px;width:38vw}
  .cov-after{aspect-ratio:984/750}   /* 10-14 (Tannis): half the height on phones, the photo cropped to its middle */
  .cov-after img{object-position:50% 45%}
  .vein,.node{display:none}
  .vein-steps{padding:40px 0 0;border-left:1px solid rgba(169,138,214,.4);padding-left:24px}
  .vstep,.vstep:nth-child(even){width:100%;justify-self:stretch}
  .vstep .num{font-size:64px}
  .visit-home{padding:120px 0}
  .cta-final{padding:140px 0 160px}
  .artists-flow::after{background-size:auto,var(--msize-m,250% auto)}   /* Meet's river at the phone scale, like the others */
  .artists-flow{--mtail:160px}   /* and a shorter tail under Cover-ups */
  :root{--m-rise:160px}
}

/* ===== 10-06 river (the 10-06 river QA) =====
   Cover-ups to What You Can Expect: Cover-ups' underlay faded out, 96px of black, then the Expect/Process river came
   back at full width within 210px (two rivers meeting on a line). Now that river starts 96px higher, under Cover-ups'
   bottom padding (the inset photo, which hangs below the text, ends 97 to 113px above the seam from 768 to 1512, so
   the lift never reaches it), and rises over 380px with the inner pages' eased entry, so the two cross-fade. The bottom stops are unchanged (counted from the end). #54 (the
   Process/studio repeat) and Visit are left as they are. Phones keep the default fades.
   Elementor: the Expect/Process wrapper's margin-top -96px and padding-top +96px (Tablet and Desktop), the overlay
   gradient's first stops = these. */
@media (min-width:768px){
  .flow-steps{--mlift:96px;--mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.06) 60px,rgba(0,0,0,.2) 140px,rgba(0,0,0,.46) 220px,rgba(0,0,0,.76) 300px,#000 380px,#000 calc(100% - var(--steps-tail) - 200px),rgba(0,0,0,.88) calc(100% - (var(--steps-tail) + 200px) * .78),rgba(0,0,0,.5) calc(100% - (var(--steps-tail) + 200px) * .52),rgba(0,0,0,.12) calc(100% - (var(--steps-tail) + 200px) * .26),transparent 100%)}
}

/* ===== 10-06 night: Visit's river and the studio-to-Visit seam (Carlos, on his phone: "there are some areas where it's
   all black... we should fix that") =====
   Visit had no river: at 390 the page was black from the studio's last line to the finale (about 1500 rows), at 1512
   about 665 rows. Now Visit carries its own underlay (.m-under, c-home-visit-b: strip 2200-5120 mirrored and flipped top
   to bottom, tools/imagegen/cut_canvas.py FLOP; every upright and mirrored view of the strip already shows on Home, a
   flipped one never does). Top-anchored; it rises under the heading, is full behind the details and faint under the
   map (desktop: a second, horizontal mask layer tied to the grid's map column, as FAQ's body does), and is gone before
   the finale's marble rises (the finale layer starts --m-rise above the CTA). The details sit on Contact's lighter
   pool. Phones: it starts under the studio's bottom padding (the studio's own river ends with its section there), and
   Visit's top padding drops to the house rhythm (--section-y, 72px: the studio-to-Visit gap is 144px, as the Process
   to Studio seam above it).
   Elementor: Visit's container: background image c-home-visit-b, top center, 100% auto (Mobile 180%), Background
   Overlay = these gradient stops (route B, 7.2; the native fallback is the vertical gradient alone, which loses only the
   dimming under the map, which the map covers anyway); Mobile margin-top -72px / padding-top +72px for the lift (or
   bake it: the image's top 72px are its fade); Mobile padding-top 72px. The details container: radial gradient
   #060607 80% / 60% at 55% / 0% (Contact's). */
.c-home-visit{--mimg:url(../assets/marble/c-home-visit-b.webp)}
.visit-home{--mop:1;--v-end:calc(100% - var(--m-rise) + 80px);
  --mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.12) 60px,rgba(0,0,0,.5) 120px,rgba(0,0,0,.88) 180px,#000 240px,#000 calc(var(--v-end) - 280px),rgba(0,0,0,.88) calc(var(--v-end) - 218px),rgba(0,0,0,.5) calc(var(--v-end) - 134px),rgba(0,0,0,.12) calc(var(--v-end) - 62px),transparent var(--v-end))}
.visit-home .pool::before{background:radial-gradient(closest-side,rgba(6,6,7,.8),rgba(6,6,7,.6) 55%,rgba(6,6,7,0))}
@media (min-width:1024px){
  .visit-home{--v-mapx:calc(max(var(--gutter),(100% - var(--container)) / 2) + (min(100% - var(--gutter) * 2,var(--container)) - 72px) * 5 / 12 + 72px);
    --mmask:linear-gradient(180deg,transparent 0,rgba(0,0,0,.12) 60px,rgba(0,0,0,.5) 120px,rgba(0,0,0,.88) 180px,#000 240px,#000 calc(var(--v-end) - 280px),rgba(0,0,0,.88) calc(var(--v-end) - 218px),rgba(0,0,0,.5) calc(var(--v-end) - 134px),rgba(0,0,0,.12) calc(var(--v-end) - 62px),transparent var(--v-end)),
      linear-gradient(90deg,#000 0,#000 calc(var(--v-mapx) - 60px),rgba(0,0,0,.5) calc(var(--v-mapx) + 80px))}
  .visit-home::after{-webkit-mask-composite:source-in;mask-composite:intersect}
}
@media (max-width:767px){
  .visit-home{padding-top:var(--section-y);--mlift:var(--section-y);
    --mmask-m:linear-gradient(180deg,transparent 0,rgba(0,0,0,.12) 50px,rgba(0,0,0,.5) 100px,rgba(0,0,0,.88) 150px,#000 200px,#000 calc(100% - 560px),rgb(0 0 0/var(--m-dim)) calc(100% - 420px),rgba(0,0,0,.5) calc(100% - 280px),rgba(0,0,0,.12) calc(100% - 160px),transparent calc(100% - 80px))}
}
