/* ============================================================
   v2c: v2 with the On Process story full bleed (Michael, 2026-10-03).
   v2: v1's layout set in v4's type (Michael, 2026-10-03).
   v2b is the same page in Instrument Serif, for comparison.

   - Bodoni Moda: the Didone of Vogue and Harper's Bazaar, with
     optical sizes so its hairlines hold. the hero title and the
     line under it, section headings, the pull quote, the form's
     questions.
   - Archivo: a grotesk with a width axis. body copy at normal
     width; eyebrows, the name and the location stretched wide.
   ============================================================ */

:root{
  --display:'Bodoni Moda', 'Didot', 'Bodoni 72', Georgia, serif;
  --sans:'Archivo', 'Helvetica Neue', system-ui, sans-serif;
}
body{font-family:var(--sans); font-weight:400}

/* ---------- wide grotesk caps: eyebrows, the name, the location ---------- */
.label{
  font-family:var(--sans); font-stretch:125%; font-weight:500;
  font-size:11px; line-height:16px; letter-spacing:.32em; color:var(--paper);
}
.top .t-name{font-family:var(--sans); font-stretch:125%; font-weight:300; font-size:13px; letter-spacing:.28em}
.t-nav, .vswitch a{font-family:var(--sans)}
.t-meta, .caption, .t-form, button, input[type=text], input[type=email], textarea, footer{font-family:var(--sans)}
.caption{font-size:13px; line-height:20px}

/* ---------- display: Bodoni ---------- */
.t-h1, .t-h2{font-family:var(--display); font-weight:400; font-optical-sizing:auto; letter-spacing:-.02em}
.t-h2{font-size:clamp(36px,4vw,64px); line-height:1.05}

/* ---------- reading: Archivo ---------- */
.wall{font-family:var(--sans); font-size:17px; line-height:28px; color:var(--paper-dim)}

/* ---------- the hero: title and the line under it in Bodoni, the
   location in the wide caps ---------- */
.hero__type{max-width:none}
.hero__type .t-intro{font-family:var(--display); font-style:normal; font-weight:400; letter-spacing:-.005em}
.hero__type .t-meta{
  font-family:var(--sans); font-stretch:125%; font-weight:500; font-size:11px; line-height:16px;
  letter-spacing:.32em; text-transform:uppercase; color:var(--paper);
}
@media (min-width:900px){
  .hero__type .t-h1{font-size:clamp(64px,6.4vw,104px); line-height:1.02}
  .hero__type .t-intro{font-size:clamp(20px,1.6vw,26px); line-height:1.35; max-width:30em}
}
@media (max-width:899px){
  .hero__type .t-h1{font-size:clamp(36px, calc((100vw - 48px) / 8.6), 46px); line-height:1.08}
  .hero__type .t-intro{font-size:21px; line-height:1.4; max-width:none}
  .hero__type .t-meta{font-size:13px; line-height:20px}
}

/* ---------- the weave: 50/50, the same photo as a portrait, the paragraph
   at pull-quote size in Bodoni italic ---------- */
@media (min-width:900px){
  .band--quote{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .band--quote .band__media{aspect-ratio:2 / 3; max-height:100svh}
}
.band--quote .band__media{aspect-ratio:2 / 3}
.band--quote .plate--edges{background-position:30% 50%}
.pullquote{
  margin:0; font-family:var(--display); font-style:italic; font-weight:400; font-optical-sizing:auto;
  font-size:clamp(28px,3.2vw,52px); line-height:1.16; letter-spacing:-.012em;
  color:var(--paper); text-wrap:pretty; max-width:22em;
}

/* ---------- the end: the form and footer fill the screen together ---------- */
section.opt{min-height:100svh; box-sizing:border-box}

/* ---------- phones: the vertical hero (IMG_3601), a little right of center
   to keep the red column in frame ---------- */
@media (max-width:899px){
  .hero .plate{background-position:58% 50%}
}

/* ---------- the inquiry form (ported from v4): questions in Bodoni ---------- */
section .inq{--inq-display:var(--display); --inq-q-size:clamp(28px,2.6vw,40px); --inq-q-weight:400}

/* ============================================================
   v2c: the On Process story, full bleed (Michael, 2026-10-03).
   the frame breaks out of the sheet to the screen edges and fills
   the pinned stage; the copy sits lower left, where the hero's does.
   the frame is sized to the tallest screen height (lvh) so iOS
   toolbars can't re-scale it; the copy is placed within the small
   screen height so it never hides behind them.
   ============================================================ */
.story--bleed{margin-inline:calc(-1 * var(--frame))}
.story--bleed .story__stage{display:block; padding:0; height:100svh; overflow:visible}
.story--bleed .story__inner{position:relative; width:100%; height:100%}
.story--bleed .story__frame{position:absolute; top:0; left:0; right:0; width:auto; height:100vh; height:100lvh; aspect-ratio:auto}
/* a gradient behind the copy only, dark at the foot, gone two thirds up */
.story--bleed .story__frame::after{content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(to top, rgba(10,10,11,.88) 0%, rgba(10,10,11,.78) 28%,
    rgba(10,10,11,.5) 46%, rgba(10,10,11,0) 68%)}
.story--bleed .story__copy{position:absolute; z-index:2; margin:0;
  left:calc(var(--frame) + var(--pad)); right:calc(var(--frame) + var(--pad)); bottom:96px; max-width:620px}
.story--bleed .story__copy .wall{color:var(--paper)}
@media (max-width:899px){
  .story--bleed .story__copy{bottom:64px; padding-inline:0}
}

/* frame one: Adam's full RAW frame (color-matched to his JPEG). it zooms from the
   center of his crop (39% across, 47% down), so it opens on his framing */
.story--bleed .story__img--raw{object-position:39% 47%; transform-origin:39% 47%}

/* body copy in Newsreader (Michael, 2026-10-03), the editorial reading serif from v2b */
:root{--read:'Newsreader', 'Iowan Old Style', Georgia, serif}
.wall{font-family:var(--read); font-size:clamp(17px,1.3vw,19px); line-height:1.6; font-optical-sizing:auto}

/* the story sits inside the same 13px frame as every other section (Michael,
   2026-10-03): just short of full bleed. the copy stays on the page's rail. */
.story--bleed{margin-inline:0}
.story--bleed .story__copy{left:var(--pad); right:var(--pad)}
/* phones: the story goes full bleed again (Michael, 2026-10-03); desktop keeps the frame */
@media (max-width:899px){
  .story--bleed{margin-inline:calc(-1 * var(--frame))}
  .story--bleed .story__copy{left:calc(var(--frame) + var(--pad)); right:calc(var(--frame) + var(--pad))}
}

/* phones: In Place copy (eyebrow, heading, paragraph) above its photo (Michael, 2026-10-03) */
@media (max-width:899px){
  .band:has(> .band__fig) > .band__copy{order:-1; padding:0 var(--pad) 32px}
}

/* the story copy sits lower (Michael, 2026-10-03): 32px from the bottom on phones, 64 on
   desktop, so the gradient behind it can be shorter and the photos read brighter.
   one ease-in-out curve again, holding only under the copy. */
.story--bleed .story__copy{bottom:64px}
.story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.88) 0%, rgba(10,10,11,0.88) 14%, rgba(10,10,11,0.865) 17.0%, rgba(10,10,11,0.821) 20.0%, rgba(10,10,11,0.751) 23.0%, rgba(10,10,11,0.660) 26.0%, rgba(10,10,11,0.554) 29.0%, rgba(10,10,11,0.440) 32.0%, rgba(10,10,11,0.326) 35.0%, rgba(10,10,11,0.220) 38.0%, rgba(10,10,11,0.129) 41.0%, rgba(10,10,11,0.059) 44.0%, rgba(10,10,11,0.015) 47.0%, rgba(10,10,11,0.000) 50.0%)}
@media (max-width:899px){
  .story--bleed .story__copy{bottom:32px}
  .story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.88) 0%, rgba(10,10,11,0.88) 18%, rgba(10,10,11,0.865) 20.8%, rgba(10,10,11,0.821) 23.7%, rgba(10,10,11,0.751) 26.5%, rgba(10,10,11,0.660) 29.3%, rgba(10,10,11,0.554) 32.2%, rgba(10,10,11,0.440) 35.0%, rgba(10,10,11,0.326) 37.8%, rgba(10,10,11,0.220) 40.7%, rgba(10,10,11,0.129) 43.5%, rgba(10,10,11,0.059) 46.3%, rgba(10,10,11,0.015) 49.2%, rgba(10,10,11,0.000) 52.0%)}
}

/* phones: the rigidity image as a square (Michael, 2026-10-03). a square from a 3:2 photo
   uses its full height, so the in-focus beads stay centered top to bottom; across, the
   sharp cord column (34% of the photo) lands a little left of center with depth behind it */
@media (max-width:899px){
  .band--quote .band__media{aspect-ratio:1 / 1}
  .band--quote .plate--edges{background-position:15% 50%}
}
/* phones: zoomed so three full beads stand on the left column with the ones above and
   below cut off (bead pitch ~19% of the photo's height: the square shows 69% of it),
   centered on the middle bead, cord column at ~30% across (Michael, 2026-10-03) */
@media (max-width:899px){
  .band--quote .plate--edges{background-size:auto 145%; background-position:37% 60%}
}

/* ============================================================
   the end of the page (Michael, 2026-10-03): you can't scroll past the
   Commission + Collaboration section. it and the footer together fill one
   screen (footer ~100px), so at the furthest scroll the heading is still in
   view; if the form's details step needs more room, the page grows by only
   that much.
   ============================================================ */
section.opt{min-height:calc(100svh - 100px); padding-top:128px; padding-bottom:64px}
@media (max-width:899px){ section.opt{min-height:calc(100svh - 96px); padding-top:96px; padding-bottom:48px} }

/* labels inside the fields: ghosted where you type; on focus or once filled they shrink
   up into the top of the field instead of vanishing (a vanishing placeholder-label is a
   known usability problem, NN/g). saves a label line per field. */
.inq .inq-field{position:relative}
.inq .inq-field > .inq-field__label{
  position:absolute; left:0; right:0; top:24px; z-index:1; pointer-events:none;
  font-size:18px; line-height:28px; font-weight:400; letter-spacing:0; color:rgba(236,231,223,.62);
  transform-origin:0 0; transition:transform .24s var(--ease), color .24s var(--ease), top .24s var(--ease);
}
.inq .inq-field__opt{font-size:13px; color:rgba(236,231,223,.5)}
.inq .inq-field > .inq-field__box{margin-top:0; padding-top:16px}
.inq .inq-field:focus-within > .inq-field__label,
.inq .inq-field.is-filled > .inq-field__label{
  top:0; transform:scale(.72); color:var(--inq-dim)}
.inq .inq-field:focus-within > .inq-field__label .inq-field__opt,
.inq .inq-field.is-filled > .inq-field__label .inq-field__opt{opacity:0}
.inq .inq-field + .inq-field, .inq .inq-avail + .inq-field{margin-top:0}
.inq .inq-field__msg{margin-top:4px}
.inq .inq-field__help{margin-top:4px; margin-bottom:16px}
.inq .inq-field textarea + *, .inq .inq-avail .inq-field > .inq-field__box{padding-top:16px}
/* desktop: tighten so at the furthest scroll the heading clears the top bar */
@media (min-width:900px){
  section.opt{padding-top:112px; padding-bottom:16px}
  .inq .inq__nav{margin-top:16px}
  .inq .inq-send{margin-top:16px}
  .inq .inq-send__status{margin-top:8px}
}

/* touch tablets, landscape (Michael, 2026-10-07): the end of the page was cramped; the form section
   takes a full screen with room under "Or write to Adam directly", and the footer scrolls in below */
@media (min-width:900px) and (hover:none) and (pointer:coarse){
  section.opt{min-height:100svh; padding-bottom:128px}
}

/* short desktop windows (under 860px tall): the form holds only the current step's height
   instead of reserving room for the tallest, so the first question fits beside the heading
   and the page grows only when the details step arrives (Michael, 2026-10-03) */
@media (min-width:900px) and (max-height:859px){
  section.opt{padding-top:88px}
  .inq .inq-step:not(.is-on){display:none}
}

/* desktop: the rigidity image fills its whole half of the band as the screen widens,
   revealing more of the photo, instead of holding a 2:3 width capped by screen height and
   drifting to the edge (Michael, 2026-10-03). one height for the band. */
@media (min-width:900px){
  .band--quote .band__media{aspect-ratio:auto; max-height:none; height:min(100svh, max(640px, 72vw))}
  .band--quote .plate--edges{background-position:22% 50%}
}

/* ---------- hero, desktop (Michael, 2026-10-03) ----------
   copy moves 32px lower (two 16px steps); the title gets more line height so the g of
   "Weaving" and the f of "of" no longer touch; the line beneath is set in the reading
   serif (Newsreader) at a larger size and runs on one line, so the title stands out and
   the line reads as information. */
@media (min-width:900px){
  .hero__type{bottom:64px}
  .hero__type .t-h1{line-height:1.14}
  .hero__type .t-intro{font-family:var(--read); font-weight:400; font-size:clamp(22px,1.75vw,30px);
    line-height:1.4; letter-spacing:0; max-width:none; white-space:nowrap}
}
/* desktop: the title on one line (Michael, 2026-10-03). sized to fit the frame:
   at 1440 it spans ~70% of the width */
@media (min-width:900px){
  .hero__type .t-h1 br{display:none}
  .hero__type .t-h1{white-space:nowrap; font-size:clamp(56px,5.6vw,112px); line-height:1.05}
}

/* the hero title stands out (Michael, 2026-10-03): the row banding behind the copy, not
   the whole photo. stronger, and held to the copy's left: the ellipse sits at 38% across
   and stops shortly past the text on the right, so the bright blurred right side and the
   rest of the frame stay clean. plus a soft, invisible shadow on every letter. */
.hero__type{--band:.97; --spread-y:46%; --fade:56%}
.hero__type.fx-cyl::before{inset:calc(-1 * var(--spread-y)) -8% calc(-1 * var(--spread-y)) -14%;
  -webkit-mask-image:radial-gradient(ellipse 62% 54% at 38% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%);
  mask-image:radial-gradient(ellipse 62% 54% at 38% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%)}
.hero__type .t-h1, .hero__type .t-intro, .hero__type .t-meta{
  text-shadow:0 1px 2px rgba(6,6,7,.45), 0 0 18px rgba(6,6,7,.35)}

/* the hero photo aligned to the viewport's left edge (Michael, 2026-10-03) */
.hero .plate{background-position:0% 50%}

/* ---------- parked notes, 2026-10-04 (Michael) ---------- */
/* In Place, desktop: the room photo zoomed in a little (12%), held on the piece
   (52% across, 45% down). phones keep their own crop. */
@media (min-width:900px){
  .band--flip .plate{background-size:auto 112%; background-position:52% 45%}
}
/* the palette, shot from further away: its white extended in the image itself
   (desktop 3:2, phones a 1:2 portrait cut). the close-in still starts on the urchin. */
.story--bleed .story__img--palette{transform-origin:43% 33%}
@media (max-width:899px){ .story--bleed .story__img--palette{transform-origin:40% 27%} }
/* On Process, slower and calmer: a longer pin (420 → 520svh), so each change takes
   about a quarter more scroll. the script also eases the images after the scroll. */
@media (prefers-reduced-motion:no-preference){ .story{height:560svh} }  /* 460svh of pin, as v2b (2026-10-04) */
/* shorter weave (Michael, 2026-10-07): pins of 440svh (phones) and 395svh (desktop); site.js compresses
   only the weave's stretch to match, so the three images get about equal scroll */
@media (prefers-reduced-motion:no-preference){ .story{height:540svh} }
@media (min-width:900px) and (prefers-reduced-motion:no-preference){ .story{height:495svh} }
/* reduced motion: no pin, so no runway; site.css's later .story{height:420svh} had undone its height:auto (testing, 2026-10-07) */
/* reduced motion keeps the story (2026-10-07): pinned as usual, crossfades only (site.js holds the framing);
   undoes site.css's older reduce rules that unpinned it and showed only the weave */
@media (prefers-reduced-motion:reduce){
  .story{height:540svh}
  .story__stage{position:sticky; top:0}
  .story__img--raw{display:block}
  .story--bleed .story__copy{padding-inline:0}
}
@media (min-width:900px) and (prefers-reduced-motion:reduce){ .story{height:495svh} }

/* On Process, desktop: the treatment behind the copy only as dark as AA needs (Michael,
   2026-10-04). measured over every photo state through the scroll at 1024x768, 1280x720,
   1440x900 and 1920x1080: the resting paragraph text (64% white) is the limit, 4.62:1 at
   worst (5th percentile of the pixels behind it), label 9.3:1. .78 held to just above the
   copy (188px), one eased curve to nothing at 296px; set in px since the copy sits at a
   fixed distance from the bottom. was .88, fading out at half the screen. */
@media (min-width:900px){
  .story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.78) 0px, rgba(10,10,11,0.78) 188px, rgba(10,10,11,0.761) 199px, rgba(10,10,11,0.706) 210px, rgba(10,10,11,0.619) 220px, rgba(10,10,11,0.511) 231px, rgba(10,10,11,0.390) 242px, rgba(10,10,11,0.269) 253px, rgba(10,10,11,0.161) 264px, rgba(10,10,11,0.074) 274px, rgba(10,10,11,0.019) 285px, rgba(10,10,11,0.000) 296px)}
}

/* ---------- brought up to v2b (Michael, 2026-10-04); v2c keeps its fonts and the full-bleed
   story ---------- */
/* On Process heading: eyebrow 8, heading, then 16 to the paragraph */
.story__copy > .t-h2 + *{margin-top:16px}
/* the contact section's eyebrow, 8 above the heading */
.opt .label{margin:0}
.opt .label + .t-h2{margin-top:8px}
/* the form starts on its line: no "Contact" word (the eyebrow says it). set here so the
   v4 port can't bring it back */
.inq .inq__label{display:none}
/* On Process, desktop: with the heading added the copy stands taller (its eyebrow 203-293px
   up, the heading wraps at wide screens), so the treatment's hold now scales with the
   screen: .78 to 140px + 9vw, one eased curve to nothing 108px above. re-measured over every
   photo state at 1280x720, 1440x900, 1920x1080: paragraph 4.67:1 at worst, eyebrow 9.0,
   heading 8.7 (2026-10-04) */
@media (min-width:900px){
  .story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.78) 0px, rgba(10,10,11,0.78) calc(140px + 9vw), rgba(10,10,11,0.761) calc(140px + 9vw + 10.8px), rgba(10,10,11,0.706) calc(140px + 9vw + 21.6px), rgba(10,10,11,0.619) calc(140px + 9vw + 32.4px), rgba(10,10,11,0.511) calc(140px + 9vw + 43.2px), rgba(10,10,11,0.390) calc(140px + 9vw + 54.0px), rgba(10,10,11,0.269) calc(140px + 9vw + 64.8px), rgba(10,10,11,0.161) calc(140px + 9vw + 75.6px), rgba(10,10,11,0.074) calc(140px + 9vw + 86.4px), rgba(10,10,11,0.019) calc(140px + 9vw + 97.2px), rgba(10,10,11,0.000) calc(140px + 9vw + 108.0px))}
}

/* ================= MOBILE PASS, v2c (Michael, from his phone, 2026-10-05) =================
   phones only; desktop untouched. */
/* On Process, phones: the copy lower in the frame (32 -> 8 from the bottom of the small
   screen height), so more of each photo shows above it and the words sit deeper in the dark
   end of the gradient */
@media (max-width:899px){
  .story--bleed .story__copy{bottom:8px}
}
/* On Process, phones: the treatment behind the copy follows the copy. the copy sits in the
   small screen height (svh) but the photo and its gradient fill the tall one (lvh); when
   Safari's toolbar tucks away the copy rides ~130px up the photo, so every stop is offset by
   (lvh - svh). .78 measured AA but turned the palette grey; dialed back on purpose (Michael,
   2026-10-05): .55, held only up to the bottom of "Materially" (190px above the copy's foot
   on a 393 phone) and gone by just above "On process" (270): the edge dissolves through the
   heading's first line, and the eyebrow sits nearly on the clean photo (it's read over the
   darker frames). over the white palette that is under AA on purpose: paragraph ~2.7:1,
   "Transformed" ~3.8, "Materially" and the eyebrow lower. */
@media (max-width:899px){
  .story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.605) 0px, rgba(10,10,11,0.605) calc(100lvh - 100svh + 190px), rgba(10,10,11,0.590) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.1), rgba(10,10,11,0.547) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.2), rgba(10,10,11,0.480) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.3), rgba(10,10,11,0.396) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.4), rgba(10,10,11,0.302) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.5), rgba(10,10,11,0.209) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.6), rgba(10,10,11,0.125) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.7), rgba(10,10,11,0.058) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.8), rgba(10,10,11,0.015) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.9), rgba(10,10,11,0.000) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 1.0))}
}

/* v2d (forked from v2c, 2026-10-05): the one difference from v2c.
   phones: while the white palette is up, the words go charcoal and the dark behind them steps
   away, so the palette stays clean white (Michael, 2026-10-05). --pk, set by the story script,
   follows the palette's own fade (0 to 1). dark on the white: ~15:1 for the heading, the
   paragraph's resting charcoal (72%) ~6:1. the thread goes dark too (site.js) */
@media (max-width:899px){
  .story--bleed .story__copy .label, .story--bleed .story__copy .t-h2{
    color:color-mix(in srgb, #141416 calc(var(--pk, 0) * 100%), var(--paper))}
  .story--bleed .story__frame::after{opacity:calc(1 - var(--pk, 0))}
}

/* (Michael, 2026-10-05) 10% darker behind the copy for the raw wood and the weave on phones:
   .55 -> .605. in v2d the palette has no dark behind it anyway (the words go charcoal) */

/* (Michael, 2026-10-05, last pass on this section) the dark behind the copy now ends at half
   the screen: holds to just under "Materially", fades to nothing at 50% up, a purposeful
   cutoff. the palette's push centers on the collection */
@media (max-width:899px){
  .story--bleed .story__img--palette{transform-origin:45% 33%}
}

/* phones: plain line breaking for copy. Safari's text-wrap:pretty re-balances whole paragraphs
   and broke lines early with room to spare (Michael's screenshot: "into", "as"); greedy wrap
   fills each line before breaking (2026-10-05) */
@media (max-width:899px){
  .wall, .t-intro, .caption, .pullquote, .weave-text{text-wrap:wrap}
}

/* phones (Michael, 2026-10-05): a little more room on the right for copy, no hyphenation. text
   now runs to 16px from the right edge (left stays 24: a ragged right reads balanced with a
   slightly narrower margin) */
@media (max-width:899px){
  .band__copy, .band:has(> .band__fig) > .band__copy{padding-right:3px}
  .caption{padding-right:3px}
  .hero__type{right:16px}
  section.opt{padding-right:16px}
  .story--bleed .story__copy{right:16px}
}

/* ===== the rigidity section on phones, copied from v2b (Michael, 2026-10-05): same full bleed,
   pin, eased words and wash; this version's own typeface ===== */
/*    the rigidity section, phones (Michael, 2026-10-05): the photo full bleed, filling the
   screen, pinned. then the words scroll up from the bottom over its right two thirds (the
   cord threading the beads stays clear on the left), lock in place for a few scrolls, and
   the page carries on with both. pure sticky: the image pins at the top; the copy sits in
   the flow right after it, so it rises with the scroll, then pins too; a 60svh spacer at
   the end is the hold. both are a full tall screen (lvh) so they let go together. a
   portrait cut of Adam's full-size export (edges-m.jpg, 1440x2400) puts the cord about 11%
   in from the left. the wash on the image darkens as the copy rises (--q, set by
   "rigidity, phones" in site.js). */
@media (max-width:899px){
  .band--quote{display:block; position:relative; margin-inline:calc(-1 * var(--frame)); height:auto}
  .band--quote::after{content:""; display:block; height:60svh}
  .band--quote .band__media{position:sticky; top:0; z-index:0; height:100vh; height:100lvh;
    aspect-ratio:auto; max-height:none}
  .band--quote .band__media .plate{inset:0}
  .band--quote .plate--edges{background-size:cover; background-position:0% 50%}
  /* the wash: clear over the cord, darkening across the right two thirds, only as dark as
     AA needs (measured at 26px: 4.83:1 at 393, 4.92 at 375, 4.82 at 430; at 30px the
     words count as large text, so AA asks only 3:1) */
  .band--quote .band__media::after{content:""; position:absolute; inset:0; z-index:1;
    pointer-events:none; opacity:var(--q, 0);
    background:linear-gradient(to right, rgba(10,10,11,0) 0%, rgba(10,10,11,0) calc(24% + 30px),
      rgba(10,10,11,.36) calc(36% + 30px), rgba(10,10,11,.53) calc(52% + 30px), rgba(10,10,11,.53) 100%)}
  /* (Michael, 2026-10-05) the photo moved 30px right so the cord lines up with the second A
     of the name (edges-m.jpg re-cut 85px wider on the left); the wash moved with it */
  /* (darkened behind the words so they pop, Michael 2026-10-05: .42 -> .48 -> .53; the
     cord's side stays fully clear) */
  .band--quote .band__copy{position:sticky; top:0; z-index:1; height:100vh; height:100lvh;
    margin:0; box-sizing:border-box; display:flex; flex-direction:column; justify-content:center;
    padding:64px calc(var(--frame) + var(--pad)) 0 33.333vw}
  /* right-aligned, ragged left (Michael, 2026-10-05): the lines end on the page's right rail
     (24px, the same edge as the top bar's v2c), not against the glass, where italics clip.
     64 at the top so the words center in the space below the top bar (44px) */
  /* the words: 27 (30 read a touch big), condensed, the left margin a third in */
  .band--quote .pullquote{font-size:27px; line-height:1.15; opacity:1; transform:none; transition:none;
    text-align:right}
}

/* the rigidity sequence, eased (Michael, 2026-10-05), where the browser can link animation
   to scroll (it runs on the compositor, so it doesn't stutter on iOS the way script-moved
   images do). measured in screens (lvh) of scroll past the moment the section's top meets
   the top of the screen (u):
     -20..20  the photo eases into its lock: it slows to a stop instead of halting
      45..135 the words rise from just below the fold at scroll speed, easing into place
     135..185 they hold
     185..275 they ease out of place and scroll up and away
     275..298 the photo alone again, the same beat as before the words came
     298..338 the photo eases out of its lock and the page carries on
   ranges are percentages of the 'cover' range (section 418lvh + one screen = 518lvh;
   x = u + 100): Safari ignored them written in lvh, which broke it there (2026-10-05).
   it only switches on (html.rig-sda) once the script has confirmed the browser attached the
   animations to the scroll; anywhere else the plain sticky version above stands. */
@media (max-width:899px){
    html.rig-sda .band--quote{view-timeline:--rig block}
    html.rig-sda .band--quote::after{height:318lvh}
    html.rig-sda .band--quote .band__media{
      animation:rig-img-in linear both, rig-img-out linear both;
      animation-timeline:--rig, --rig;
      animation-range:cover 15.444% cover 23.166%, cover 76.834% cover 84.556%}
    html.rig-sda .band--quote .band__media::after{
      animation:rig-wash linear both; animation-timeline:--rig;
      animation-range:cover 27.992% cover 72.394%}
    html.rig-sda .band--quote .band__copy{margin-top:-100vh; margin-top:-100lvh;
      animation:rig-text-in linear both, rig-text-out linear both;
      animation-timeline:--rig, --rig;
      animation-range:cover 27.992% cover 45.367%, cover 55.019% cover 72.394%}
}
/* the photo's lock, eased: offsets from plain sticky. in: it slows to rest over 40lvh of
   scroll (quadratic, starting at scroll speed); out: the mirror */
@keyframes rig-img-in{
  0%{translate:0 0} 12.5%{translate:0 .312lvh} 25%{translate:0 1.25lvh} 37.5%{translate:0 2.812lvh}
  50%{translate:0 5lvh} 62.5%{translate:0 2.812lvh} 75%{translate:0 1.25lvh} 87.5%{translate:0 .312lvh}
  100%{translate:0 0}}
@keyframes rig-img-out{
  0%{transform:translateY(0)} 12.5%{transform:translateY(-.312lvh)} 25%{transform:translateY(-1.25lvh)}
  37.5%{transform:translateY(-2.812lvh)} 50%{transform:translateY(-5lvh)} 62.5%{transform:translateY(-2.812lvh)}
  75%{transform:translateY(-1.25lvh)} 87.5%{transform:translateY(-.312lvh)} 100%{transform:translateY(0)}}
/* the words: at scroll speed, then easing to rest (quadratic); leaving, the mirror */
@keyframes rig-text-in{
  0%{translate:0 70lvh; animation-timing-function:linear}
  55.556%{translate:0 20lvh; animation-timing-function:cubic-bezier(.333,.667,.667,1)}
  100%{translate:0 0}}
@keyframes rig-text-out{
  0%{transform:translateY(0); animation-timing-function:cubic-bezier(.333,0,.667,.333)}
  44.444%{transform:translateY(-20lvh); animation-timing-function:linear}
  100%{transform:translateY(-70lvh)}}
/* the wash comes in with the words and goes with them */
@keyframes rig-wash{0%{opacity:0} 21.7%{opacity:1} 78.3%{opacity:1} 100%{opacity:0}}

/* phones: the rigidity quote keeps its earlier, better line breaking (pretty), even though
   the rest of the copy now wraps plainly (Michael, 2026-10-05) */
@media (max-width:899px){
  .band--quote .pullquote{text-wrap:pretty}
}

/* the form (Michael, 2026-10-05): no labels on the fields. each field shows its name as a
   ghosted placeholder inside it (set from the label by site.js) that clears as you type, to
   win back vertical space on desktop and phones. the label stays for screen readers, hidden
   from view */
.inq .inq-field > .inq-field__label{position:absolute !important; width:1px; height:1px; margin:0; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; top:auto; transform:none}
.inq .inq-field > .inq-field__box{margin-top:0; padding-top:0}
.inq .inq-field input::placeholder, .inq .inq-field textarea::placeholder{color:rgba(236,231,223,.5); opacity:1}
.inq .inq-field input:focus::placeholder, .inq .inq-field textarea:focus::placeholder{color:rgba(236,231,223,.32)}


/* ============================================================
   the form, round 2 (Michael, 2026-10-05)
   questions: the display face at its own size, a clear step below the H2 (type scale), not
   the H2's size. accent: teal #5fc2b5, replacing the olive; one per version to compare.
   it passes AA as text on the dark ground; as a fill, the label on it is the site's ink,
   not white (no one color can carry white text and also read as text on this ground).
   ============================================================ */
section .inq{--inq-q-size:clamp(26px,2.2vw,34px); --inq-accent:#5fc2b5}
section .inq .inq-opt:hover{border-color:var(--inq-accent)}
section .inq .inq-opt:has(input:checked){border-color:var(--inq-accent); background:rgba(95,194,181,.08)}
section .inq .inq-opt:has(input:checked) .inq-opt__feather{stroke:var(--inq-accent)}
section .inq .inq__sentence .ans{color:var(--inq-accent)}
/* send: quiet until the form is ready, then it fills with the accent */
section .inq .inq-send__btn{background:transparent; color:var(--inq-paper); box-shadow:inset 0 0 0 1px var(--inq-line);
  transition:background-color .4s var(--ease), color .4s var(--ease), box-shadow .4s var(--ease), transform .16s var(--ease)}
section .inq .inq-send__btn:hover{background:transparent; color:var(--inq-paper); box-shadow:inset 0 0 0 1px var(--inq-paper)}
section .inq.is-ready .inq-send__btn{background:var(--inq-accent); color:var(--ink, #0a0a0b); box-shadow:none}
section .inq.is-ready .inq-send__btn:hover{background:var(--inq-accent); color:var(--ink, #0a0a0b); filter:brightness(1.08)}
section .inq .inq-send__line{background:currentColor}
/* the way to reach Adam that needs no steps */
section .inq .inq-direct{margin:32px 0 0; font-size:14px; line-height:20px; color:var(--inq-dim)}
section .inq .inq-direct a{color:var(--inq-paper); text-decoration:underline; text-decoration-color:var(--inq-line); text-underline-offset:4px}
section .inq .inq-direct a:hover{text-decoration-color:var(--inq-paper)}
section .inq[data-state="sent"] .inq-direct{opacity:0}

/* one family per job in this section (Michael, 2026-10-05): the display face for headings and
   questions; the reading face for everything read or typed (the sentence, options, placeholders,
   notes, the direct line), matching the paragraph beside it; the sans only for the small
   uppercase labels (eyebrow, step count, send) */
section .inq .inq__sentence, section .inq .inq-opt__t, section .inq .inq-body,
section .inq .inq-field input, section .inq .inq-field textarea, section .inq .inq-field__label,
section .inq .inq-field__msg, section .inq .inq-field__help, section .inq .inq-direct,
section .inq .inq-sent__receipt{font-family:var(--read); font-optical-sizing:auto}
section .inq .inq-opt__t{font-size:18px}

/* focus rings (Michael, 2026-10-05): none for mouse or touch, and none when the form moves
   focus to the next question for screen readers. a ring shows only for keyboard users, who
   need it to see where they are (WCAG 2.4.7) */
:focus:not(:focus-visible){outline:none}
[tabindex="-1"]:focus, .inq .inq-step:focus, .inq .inq-sent:focus{outline:none}
/* the progress row holds the height of its back / start over icons before they appear, so the
   first answer doesn't push the form down by their height */
section .inq .inq__progress{min-height:32px}

/* the rest of the form and the footer, on the same rule (Michael, 2026-10-05): anything read in
   sentence case is in the reading face; the sans only in the small uppercase labels, so the
   step count reads as one of them, set like the eyebrow */
section .inq .inq-opt__n, section .inq .inq-send__status, section .inq [data-again],
section .inq .inq-sent__body, footer .t-meta, footer .t-meta a{font-family:var(--read); font-optical-sizing:auto; letter-spacing:0; font-stretch:100%}
section .inq .inq-opt__n{font-size:14px; font-variant-numeric:lining-nums tabular-nums}
section .inq [data-again]{font-size:16px}
section .inq .inq-send__status{font-size:14px}
footer .t-meta, footer .t-meta a{font-size:14px}
section .inq .inq__count, section .inq .inq__label{font-family:var(--sans); text-transform:uppercase; font-size:11px; font-weight:500; letter-spacing:.32em; font-stretch:125%}
/* the rule above the footer stops at the footer's text, from the copyright to Terms, instead
   of running edge to edge (Michael, 2026-10-05) */
section.opt{border-bottom:0}
footer{position:relative}
footer::before{content:""; position:absolute; top:0; height:1px; background:rgba(233,229,223,.10);
  left:calc(var(--frame) + var(--pad)); right:calc(var(--frame) + var(--pad))}
/* the sent screen (Michael, 2026-10-05): the receipt's answers in the accent, as they were in the
   sentence; "Write another note", its one action, carries a faint underline so it reads as a
   link on touch screens too, and turns the accent on hover */
section .inq .inq-sent__receipt b{color:var(--inq-accent)}
section .inq .inq-sent__again span{text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:5px;
  text-decoration-color:rgba(236,231,223,.28); transition:color .24s var(--ease), text-decoration-color .24s var(--ease)}
section .inq .inq-sent__again:hover{color:var(--inq-accent)}
section .inq .inq-sent__again:hover span{text-decoration-color:var(--inq-accent)}

/* ============================================================
   the hero copy higher (Michael, 2026-10-05), phones and desktop: the top of the title sits
   on the middle of the screen, where the rows of beads angle in toward it. measured to the
   top of the letters, not the line box: the title is lifted by the space its line box holds
   above the ascenders (.131em at desktop's 1.05 line height, .146em at phones' 1.08), so
   "Weaving" starts exactly at 50%.
   ============================================================ */
.hero__type{top:50%; bottom:auto; transform:none}
@media (min-width:900px){ .hero__type .t-h1{margin-top:-.131em} }
@media (max-width:899px){ .hero__type .t-h1{margin-top:-.146em} }
/* the darkening behind the hero copy moves up with it, at the same strength: held at its full
   .43 from the foot to the middle of the screen, where the title now starts, then gone by a
   quarter from the top as before, so the top of the photograph stays as shot. measured with the
   old gradient, the copy at the middle fell under AA: the phone line under the title to 4.2:1,
   desktop's location to 4.3:1 (WCAG asks 4.5) */
.hero::before{background:linear-gradient(to top, rgba(10,10,11,.43) 0%, rgba(10,10,11,.43) 50%,
  rgba(10,10,11,.23) 62%, rgba(10,10,11,0) 76%)}
/* short screens (phones on their side, very short windows): there isn't room for the copy
   below the middle, so it keeps its old place at the foot */
@media (max-height:540px){
  .hero__type{top:auto; bottom:64px}
  .hero__type .t-h1{margin-top:0}
}
/* desktop (Michael, 2026-10-05): the title starts at 45%, on two lines ("Weaving a world" /
   "of meaning"); the block is as wide as the first line, and the line beneath wraps inside it */
@media (min-width:900px) and (min-height:541px){
  .hero__type{top:45%; width:min-content; max-width:none}
  .hero__type .t-h1 br{display:inline}
  .hero__type .t-intro{white-space:normal}
}

/* the rigidity passage in roman, not italic (Michael, 2026-10-05): it isn't a quotation or a
   different voice, it's the site describing the work, so italics would signal a shift that
   isn't there. its size and the space around it set it apart */
.pullquote, .band--quote .pullquote{font-style:normal}

/* the rigidity passage, sturdier hairlines (Michael, 2026-10-05, preview): Bodoni Moda's
   optical size pinned to a text size (14) instead of following the font size, which picked the
   display cut with the thinnest hairlines; and the Mac's thinning "antialiased" smoothing off
   for this passage only */
.band--quote .pullquote{font-optical-sizing:none; font-variation-settings:'opsz' 14;
  -webkit-font-smoothing:auto; -moz-osx-font-smoothing:auto}
.band--quote .pullquote{font-optical-sizing:auto; font-variation-settings:normal}
/* ^ test (Michael, 2026-10-05): v2d keeps only the smoothing change (2); optical size back to auto */

/* Bodoni on the dark ground, sturdier (Michael, 2026-10-05): the rigidity passage and the
   section H2s at Bodoni Moda's text optical size (14) for firmer hairlines, and weight 450
   (from 400) so the stems stand out. smoothing as the rest of the site. replaces the split test */
.band--quote .pullquote, .t-h2{font-optical-sizing:none; font-variation-settings:'opsz' 14;
  font-weight:450; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale}

/* hero title, optical fixes (Michael, 2026-10-05). the W of "Weaving" sits too far from its e:
   Bodoni Moda has no kern for the pair, and the W's diagonal leaves 0.28em at mid-height against
   0.09em between ordinary letters, so the pair is kerned in -0.12em. and the lines under the
   title are tucked in under the W: its top serif sits on the left edge but its body slants in,
   so lines aligned to the edge read as sticking out. tucked 0.1 of the title size */
.hero__type .kern-w{letter-spacing:-.12em}
.hero__type .t-intro, .hero__type .t-meta{margin-left:clamp(5.6px,.56vw,11.2px)}
@media (max-width:899px){ .hero__type .t-intro, .hero__type .t-meta{margin-left:4px} }

/* the hero subheading takes the intro-paragraph style, the rigidity passage's (Michael,
   2026-10-05): Newsreader 250, the same step (37.5px at 1440), line height 1.4; phones 22px.
   it wraps within the title's width */
.hero__type .t-intro{font-family:var(--read); font-weight:250; font-style:normal; font-optical-sizing:auto;
  font-variation-settings:normal; letter-spacing:0; line-height:1.4; white-space:normal;
  font-size:clamp(27px,2.6vw,53px)}
@media (min-width:900px){ .hero__type{width:min-content; max-width:none} }
@media (max-width:899px){ .hero__type .t-intro{font-size:22px} }

/* the hero block grouped (Michael, 2026-10-05): title and subheading tight as one unit, the
   location set apart as the sign-off (Gestalt proximity). was an even 16px between all three */
.hero__type{gap:0}
.hero__type .t-intro{margin-top:10px}
.hero__type .t-meta{margin-top:44px}
@media (max-width:899px){
  .hero__type .t-intro{margin-top:8px}
  .hero__type .t-meta{margin-top:32px}
}
/* desktop: the top of the W back on the middle of the screen (was 45%), the same anchor as v2c,
   so the two compare fairly (Michael, 2026-10-05) */
@media (min-width:900px) and (min-height:541px){ .hero__type{top:50%} }
/* desktop (Michael, 2026-10-05): a little more line height in the stacked title so the g of
   "Weaving" clears "of" below (1.05 -> 1.12); the lift that keeps the W's top on its anchor
   grows to match (.131em -> .166em) */
@media (min-width:900px){ .hero__type .t-h1{line-height:1.12; margin-top:-.166em} }

/* ============================================================
   type system brought over from v2c (Michael, 2026-10-05). replaces v2d's 450 / opsz 14 test.
   Bodoni for headings only: one setting for every Bodoni line; change the stems or weight here.
   ============================================================ */
:root{--bodoni-opsz:26; --bodoni-wght:400}
.t-h1, .t-h2, .pullquote, .inq .inq-step__q, .inq .inq-sent__head{font-optical-sizing:none;
  font-variation-settings:'opsz' var(--bodoni-opsz); font-weight:var(--bodoni-wght);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale}
/* H2 a minor seventh (1.78) below the H1 on desktop, 45px at 1440; phones 24px */
.t-h2{font-size:clamp(32px,3.15vw,63px)}
@media (max-width:899px){ .t-h2{font-size:24px} }
/* the rigidity passage: the intro-paragraph style, Newsreader 250, a minor third below the H2
   (37.5px at 1440), line height 1.4; phones 22px */
.band--quote .pullquote{font-family:var(--read); font-weight:250; font-style:normal; font-optical-sizing:auto;
  font-variation-settings:normal; letter-spacing:0; line-height:1.4; font-size:clamp(27px,2.6vw,53px)}
@media (max-width:899px){ .band--quote .pullquote{font-size:22px; line-height:1.4} }
/* desktop: the top of the W at 39% (Michael, 2026-10-07, from the tuner; was 45, and 47 his sweet spot 2026-10-05) */
@media (min-width:900px) and (min-height:541px){ .hero__type{top:39%} }
/* desktop: the subheading a perfect fourth below the H2, 34px at 1440, as v2c (Michael, 2026-10-05) */
@media (min-width:900px){ .hero__type .t-intro{font-size:clamp(21px,2.35vw,47px)} }

/* ============================================================
   the rigidity section on desktop pauses, a smaller version of what On Process does next
   (Michael, 2026-10-05). the photo locks when its top meets the top of the screen; the words
   fade in on that moment in the dark half (no slide); both hold for most of a screen of scroll,
   then leave together. the band is one screen plus the hold tall; photo and words are pinned
   inside it. the photo's parallax is off here so it sits still while locked. the trigger is set
   by "rigidity, desktop" in site.js
   ============================================================ */
@media (min-width:900px){
  .band--quote{--rig-h:min(100svh, max(640px, 72vw)); --rig-hold:90lvh;
    grid-template-rows:calc(var(--rig-h) + var(--rig-hold)); align-items:start}
  .band--quote .band__media, .band--quote .band__copy{position:sticky; top:0; height:var(--rig-h)}
  .band--quote .band__copy{display:flex; flex-direction:column; justify-content:center}
  .band--quote .band__media .plate{inset:0; transform:none !important}
  .band--quote .pullquote.rise{transform:none; opacity:0; transition:opacity 1.4s var(--ease-out)}
  .band--quote.is-locked .pullquote.rise{opacity:1}
}
@media (min-width:900px) and (prefers-reduced-motion:reduce){ .band--quote .pullquote.rise{opacity:1} }
/* gentler (Michael, 2026-10-05: it was blasting in): a beat after the lock, then a slow
   ease-in-out over 2.8s instead of 1.4s ease-out, which put most of the change in the first
   moment. leaving (scrolling back up) stays quicker */
@media (min-width:900px){
  .band--quote .pullquote.rise{transition:opacity 1s var(--ease-out)}
  .band--quote.is-locked .pullquote.rise{transition:opacity 2.8s cubic-bezier(.45,0,.25,1) .4s}
}

/* desktop: the photo eases into its lock instead of stopping dead (Michael, 2026-10-05), as on
   phones: it slows to rest over 40lvh of scroll around the lock (quadratic), and eases out the
   same way at the release. the words ride with it; their fade still starts on the lock and runs
   on its own, so nobody has to keep scrolling to see them. measured on the 'cover' range: band
   190lvh (a screen plus the 90lvh hold) + one screen = 290lvh; lock at 100lvh into it.
   in: 80..120 = 27.586%..41.379%; out (release at 190): 170..210 = 58.621%..72.414% */
@supports (animation-timeline: view()) and (animation-range: cover 10% cover 20%){
  @media (min-width:900px) and (prefers-reduced-motion:no-preference){
    .band--quote{view-timeline:--rigd block}
    .band--quote .band__media, .band--quote .band__copy{
      animation:rig-img-in linear both, rig-img-out linear both;
      animation-timeline:--rigd, --rigd;
      animation-range:cover 27.586% cover 41.379%, cover 58.621% cover 72.414%}
  }
}
/* desktop: the rigidity photo moved left by about 15% of its frame (Michael, 2026-10-05): less of
   the empty wall and cord side, another row of beads in view. 22% -> 38% across */
@media (min-width:900px){ .band--quote .plate--edges{background-position:38% 50%} }
/* dialed back to about 10% of the frame (Michael, 2026-10-05): 38% -> 33% across */
@media (min-width:900px){ .band--quote .plate--edges{background-position:33% 50%} }

/* ============================================================
   from v2b (Michael, 2026-10-05): ~208px between every section on desktop, and each image fading
   in gently as it arrives, then staying. On Process is full bleed here, its image starting at the
   top of its pinned stage, so it takes the full gap and its fade is timed for the same screen
   positions as v2b's: starting when the image's top is ~58% down the screen, done just before
   the pin (cover 42vh-95vh of the section)
   ============================================================ */
@media (min-width:900px){ .band{margin-top:208px} }
@keyframes img-arrive{from{opacity:0} to{opacity:1}}
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    /* the photo frames clip, so the frame carries the timeline (measured against the page) */
    .band__media{view-timeline:--media block}
    .band__media > .plate{animation:img-arrive ease-in-out both; animation-timeline:--media;
      animation-range:cover 18% cover 49%}
  }
  @media (min-width:900px) and (prefers-reduced-motion:no-preference){
    .band.story{view-timeline:--story block}
    .story__frame{animation:img-arrive ease-in-out both; animation-timeline:--story;
      animation-range:cover 42vh cover 95vh}
  }
}

/* In Place's beat (Michael, 2026-10-05): no pause here, the calm opener; instead the wall label
   under the photo fades in a moment after it. on its own view of the page, it starts as the label
   enters the screen and finishes about a third of the way up, by which point the photo is in */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    .band__fig > .caption{animation:img-arrive ease-in-out both; animation-timeline:view();
      animation-range:cover 10% cover 40%}
  }
}


/* ============================================================
   the form, slower and quieter (Michael, 2026-10-05): the intro copy starts level with "I want
   to" (inquiry.js); the progress line stays hidden until the first answer, then arrives with
   the answer sentence; and everything after a choice moves gently: a longer beat before the
   next question (900ms, was 420), questions crossing over ~1s instead of ~0.4s, answer words
   fading in over 1.2s, the progress line filling over 1.4s
   ============================================================ */
.inq .inq__progress{opacity:0; transition:opacity 1.2s var(--ease)}
.inq.has-choice .inq__progress{opacity:1}
.inq .inq-step{transition:opacity .7s var(--ease), transform .7s var(--ease), visibility 0s .7s}
.inq .inq-step.is-on{transition:opacity 1.1s var(--ease) .35s, transform 1.1s var(--ease) .35s}
.inq .inq__sentence .w{animation:inq-word 1.2s var(--ease-out) forwards}
.inq .inq__fill{transition:width 1.4s var(--ease-out)}

/* desktop too (Michael, 2026-10-05): while the whole palette is in view, the words go charcoal and
   the dark behind them steps away (--pk from site.js, 0 to 1), coming back as it closes in */
@media (min-width:900px){
  .story--bleed .story__copy .label, .story--bleed .story__copy .t-h2{
    color:color-mix(in srgb, #141416 calc(var(--pk, 0) * 100%), var(--paper))}
  .story--bleed .story__frame::after{opacity:calc(1 - var(--pk, 0))}
}
/* rigidity words, desktop (Michael, 2026-10-05): a touch quicker, 2.2s after a .25s beat (was
   2.8s after .4s); they now start 25% of a screen before the lock (site.js) */
@media (min-width:900px){
  .band--quote.is-locked .pullquote.rise{transition:opacity 2.2s cubic-bezier(.45,0,.25,1) .25s}
}

/* photo arrivals timed in screens, not as a share of each photo's own travel (Michael, 2026-10-05):
   the full-height rigidity photo was fading late, right at its lock, because a taller photo's
   percentages land later. now every photo starts fading when its top is ~30% of a screen up and
   is fully in by ~83% (the timing In Place had at 1440x900) */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    .band__media > .plate{animation-range:cover 30vh cover 83vh}
  }
}
/* the "nothing is available" note reads as a paragraph, so it gets reading leading (Michael, 2026-10-06) */
section .inq .inq-avail__note{line-height:1.55}


/* ============================================================
   rigidity, phones: the words fade in over the photo as it locks, like desktop (Michael,
   2026-10-06). they no longer rise from below: the copy sits over the photo from the start,
   unseen; on the lock (desktop's trigger, "rigidity" in site.js) the words and the wash fade in
   together, hold with the photo for 60lvh of scroll (a bit shorter than desktop's 90), then all
   leave together. where scroll-linked animation works, the photo's eased lock now carries the
   copy too. cover = section 160lvh + one screen = 260lvh, x = u + 100: in -20..20, out 40..80
   ============================================================ */
@media (max-width:899px){
  .band--quote::after{height:60svh; height:60lvh}
  .band--quote .band__copy{margin-top:-100vh; margin-top:-100lvh}
  .band--quote .pullquote.rise{opacity:0; transform:none; transition:opacity 1s var(--ease-out)}
  .band--quote.is-locked .pullquote.rise{opacity:1; transition:opacity 1.7s cubic-bezier(.45,0,.25,1) .25s}
  .band--quote .band__media::after{opacity:0; transition:opacity 1s var(--ease-out)}
  .band--quote.is-locked .band__media::after{opacity:1; transition:opacity 2.2s cubic-bezier(.45,0,.25,1) .25s}
  html.rig-sda .band--quote::after{height:60lvh}
  html.rig-sda .band--quote .band__media, html.rig-sda .band--quote .band__copy{
    animation:rig-img-in linear both, rig-img-out linear both;
    animation-timeline:--rig, --rig;
    animation-range:cover 30.769% cover 46.154%, cover 53.846% cover 69.231%}
  html.rig-sda .band--quote .band__media::after{animation:none}
}
@media (max-width:899px) and (prefers-reduced-motion:reduce){
  .band--quote .pullquote.rise, .band--quote .band__media::after{opacity:1; transition:none}
}


/* the form on phones (Michael, 2026-10-06): no empty space held above the first question. the
   progress line and the answer sentence take no room until the first choice, so the copy sits one
   step (64, the grid gap) above "I want to" (was 236). they open up on that first choice, while
   the question is already changing */
@media (max-width:899px){
  section .inq:not(.has-choice) .inq__progress{min-height:0; height:0; margin-bottom:0; overflow:hidden}
  /* !important over the inline reserve (inquiry.js), which still holds from the first choice on */
  section .inq:not(.has-choice) .inq__sentence{min-height:0 !important; margin-bottom:0}
}

/* corners knocked off (Michael, 2026-10-06): 2px on images inset in the frame, felt more than
   seen. In Place everywhere; rigidity and On Process on desktop only (full bleed on phones keeps
   square corners against the screen edge). the form stays square for now */
.band__fig .band__media{border-radius:2px; overflow:hidden}
@media (min-width:900px){
  .band--quote .band__media, .story__frame{border-radius:2px; overflow:hidden}
}


/* ============================================================
   Contact in the top bar (Michael, 2026-10-06): hidden until the visitor has seen the opening
   picture; it fades in slowly as the In Place photo fades in (its top 30% of a screen up), quiet
   enough to be found rather than noticed. a click fades the page to the ground, moves to the
   form while it's dark, and fades back up, so nothing flies past and no pinned section plays on
   the way ("Contact" in site.js). the version switcher waits in the lower right for review
   ============================================================ */
.top__contact{opacity:0; visibility:hidden; transition:opacity 2.4s var(--ease), visibility 0s 2.4s}
.top.has-contact .top__contact{opacity:1; visibility:visible; transition:opacity 2.4s var(--ease), visibility 0s}
.go-veil{position:fixed; inset:0; z-index:40; background:var(--ink-2, #121214); opacity:0; pointer-events:none;
  transition:opacity .5s var(--ease)}
.go-veil.is-on{opacity:1}
.go-veil.is-off{transition:opacity .9s var(--ease)}
.top .vswitch{position:fixed; left:auto; top:auto; transform:none; z-index:25;
  right:calc(var(--frame) + var(--pad)); bottom:calc(24px + env(safe-area-inset-bottom));
  padding:10px 20px; border-radius:999px; pointer-events:auto;
  background:rgba(18,18,20,.72); -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px)}

/* Contact in the site's sans as the eyebrows set it (Michael, 2026-10-06): Archivo wide, tracked
   capitals, not the plain-width cut that read as Arial */
.top .top__contact{font-family:var(--sans); font-stretch:125%; font-weight:400; font-size:12px;
  letter-spacing:.28em; text-transform:uppercase}


/* Adam's name is the home link (Michael, 2026-10-06): back to the top, the same fade-jump as
   Contact so the pinned sections don't play in reverse */
.top a.t-name{pointer-events:auto; color:inherit; text-decoration:none}
.top a.t-name:focus-visible{outline:2px solid var(--paper); outline-offset:4px}


/* ============================================================
   v2d (Michael, 2026-10-06, trial): the strips from v2c behind the copy on the raw wood and the
   weave, in place of the gradient; over the palette they step away with the charcoal words (--pk)
   ============================================================ */
/* On Process, desktop (Michael, 2026-10-06, trial): the hero's treatment behind the copy, the row
   banding (the strips Adam likes), held to the text area, in place of the full-width gradient
   strip. hero values: band .97, the eased ellipse falloff, the soft shadow on every letter;
   the ellipse centered on the copy, and ending inside its box so no edge shows (2026-10-06) */
@media (min-width:900px){
  .story--bleed .story__frame::after{display:none}
  .story--bleed .story__copy > *{position:relative; z-index:2}
  .story--bleed .story__copy::before{content:""; position:absolute; z-index:1; pointer-events:none;
    inset:-46% -14% -46% -22%; /* wider to the left only; the right edge stays (Michael, 2026-10-06) */
    background-image:repeating-linear-gradient(to bottom,
      rgba(6,6,7,.97) 0px, rgba(6,6,7,.97) 3px, rgba(6,6,7,calc(.97 * .66)) 7px,
      rgba(6,6,7,calc(.97 * .91)) 12px, rgba(6,6,7,.97) 16px);
    -webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%);
    mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%)}
}

/* the strips come in from the left (Michael, 2026-10-06): no fade on the left; they run off the
   page and end in the rounded right end they had. ::before keeps only its right half (the
   rounded end, unchanged); ::after carries the same strips from off-page to the ellipse's
   center, faded top and bottom exactly as the ellipse is down its middle, so the two meet
   without a seam */
@media (min-width:900px){
  .story--bleed .story__copy::before{
    -webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%),
      linear-gradient(to right, transparent 50%, #000 50%);
    -webkit-mask-composite:source-in, source-over;
    mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%),
      linear-gradient(to right, transparent 50%, #000 50%);
    mask-composite:intersect, add}
  .story--bleed .story__copy::after{content:""; position:absolute; z-index:1; pointer-events:none;
    top:-46%; bottom:-46%; left:-50vw; right:54%;
    background-image:repeating-linear-gradient(to bottom,
      rgba(6,6,7,.97) 0px, rgba(6,6,7,.97) 3px, rgba(6,6,7,calc(.97 * .66)) 7px,
      rgba(6,6,7,calc(.97 * .91)) 12px, rgba(6,6,7,.97) 16px);
    -webkit-mask-image:linear-gradient(to bottom, transparent 2%, rgba(0,0,0,.1) 11%,
      rgba(0,0,0,.38) 21%, rgba(0,0,0,.78) 33%, #000 45%, #000 55%, rgba(0,0,0,.78) 67%,
      rgba(0,0,0,.38) 79%, rgba(0,0,0,.1) 89%, transparent 98%);
    mask-image:linear-gradient(to bottom, transparent 2%, rgba(0,0,0,.1) 11%,
      rgba(0,0,0,.38) 21%, rgba(0,0,0,.78) 33%, #000 45%, #000 55%, rgba(0,0,0,.78) 67%,
      rgba(0,0,0,.38) 79%, rgba(0,0,0,.1) 89%, transparent 98%)}
}
@media (min-width:900px){
  .story--bleed .story__copy::before, .story--bleed .story__copy::after{opacity:calc(1 - var(--pk, 0))}
}

/* On Process paragraph (Michael, 2026-10-06, v2d trial): full-strength letters at rest; the
   moving window is an olive highlighter band (site.js), not a brighter color */
.weave-text .ch{color:var(--paper)}
/* the highlighter band 2px taller above and below the letters (Michael, 2026-10-06); inline
   padding grows the band without moving the lines */
.weave-text .ch{padding-block:2px}

/* paragraphs larger on desktop (Michael, 2026-10-06): 17px at 1300 sat on the floor and Newsreader
   runs small; now ~19 at 1300, 21 from ~1450 up, and On Process's lines shorten toward 65
   characters. every paragraph in the reading face; phones unchanged */
@media (min-width:900px){ .wall{font-size:clamp(18px,1.45vw,21px)} }

/* hero strips run in from the left edge (Michael, 2026-10-06, hero only, a one-off): the oval
   faded out and its box stopped short of the screen edge, leaving a gap. as On Process: ::before
   keeps only its right half (the rounded end, unchanged; oval center 38% of its box = 32.36% of
   the type's width); ::after carries the same strips from off-screen to that center, faded top
   and bottom as the oval is down its middle */
.hero__type.fx-cyl::before{
  -webkit-mask-image:radial-gradient(ellipse 62% 54% at 38% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%),
    linear-gradient(to right, transparent 38%, #000 38%);
  -webkit-mask-composite:source-in, source-over;
  mask-image:radial-gradient(ellipse 62% 54% at 38% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%),
    linear-gradient(to right, transparent 38%, #000 38%);
  mask-composite:intersect, add}
.hero__type.fx-cyl::after{content:""; position:absolute; z-index:1; pointer-events:none;
  top:calc(-1 * var(--spread-y)); bottom:calc(-1 * var(--spread-y)); left:-50vw; right:67.64%;
  background-image:repeating-linear-gradient(to bottom,
      rgba(6,6,7,var(--band)) 0px, rgba(6,6,7,var(--band)) 3px,
      rgba(6,6,7,calc(var(--band) * .66)) 7px,
      rgba(6,6,7,calc(var(--band) * .91)) 12px,
      rgba(6,6,7,var(--band)) 16px);
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.1) 7.88%,
      rgba(0,0,0,.38) 18.68%, rgba(0,0,0,.78) 31.64%, #000 44.6%, #000 55.4%, rgba(0,0,0,.78) 68.36%,
      rgba(0,0,0,.38) 81.32%, rgba(0,0,0,.1) 92.12%, transparent 100%);
  mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.1) 7.88%,
      rgba(0,0,0,.38) 18.68%, rgba(0,0,0,.78) 31.64%, #000 44.6%, #000 55.4%, rgba(0,0,0,.78) 68.36%,
      rgba(0,0,0,.38) 81.32%, rgba(0,0,0,.1) 92.12%, transparent 100%)}
/* paragraphs at 300 on desktop (Michael, 2026-10-06; was 400) */
@media (min-width:900px){ .wall{font-weight:300} }


/* home replays the arrival (Michael, 2026-10-06): clicking the name brings the load veil up, jumps
   to the top while it's dark, resets the opening (hero copy, top bar, Contact hidden), then runs
   the page-load sequence with its own timing ("the name goes home" in site.js) */
body.going-home .veil{transition:opacity .5s var(--ease)}
body.resetting .veil, body.resetting .top, body.resetting .hero .rise, body.resetting .top__contact{transition:none !important}

/* v2d hero strips, dialed (Michael, 2026-10-06; hero only, v2d only): the rounded left end back
   (no run to the screen edge), the whole oval moved right ~15% of the copy's width so more of it
   sits past "world", and up ~10% of the copy's height; the words don't move. the oval ends inside
   its box on every side, so no edge shows */
.hero__type.fx-cyl::after{display:none}
.hero__type.fx-cyl::before{inset:-56% -20% -36% -24%;
  -webkit-mask-image:radial-gradient(ellipse 50% 54% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%);
  -webkit-mask-composite:source-over;
  mask-image:radial-gradient(ellipse 50% 54% at 50% 50%,
      #000 10%, rgba(0,0,0,.78) 34%, rgba(0,0,0,.38) 58%, rgba(0,0,0,.1) 78%, transparent 96%);
  mask-composite:add}
/* v2d hero strips 10% heavier (Michael, 2026-10-06): the bands were at .97, so they go to 1.0
   and the oval's falloff holds 10% more at each step (.78/.38/.10 -> .86/.42/.11) */
.hero__type{--band:1}
.hero__type.fx-cyl::before{
  -webkit-mask-image:radial-gradient(ellipse 50% 54% at 50% 50%,
      #000 10%, rgba(0,0,0,.86) 34%, rgba(0,0,0,.42) 58%, rgba(0,0,0,.11) 78%, transparent 96%);
  mask-image:radial-gradient(ellipse 50% 54% at 50% 50%,
      #000 10%, rgba(0,0,0,.86) 34%, rgba(0,0,0,.42) 58%, rgba(0,0,0,.11) 78%, transparent 96%)}

/* H2s on phones up one 8px step, 24 -> 32 (Michael, 2026-10-06): they read too small; now level
   with desktop's floor */
@media (max-width:899px){ .t-h2{font-size:32px} }

/* rigidity words on phones 4px larger, 22 -> 26 (Michael, 2026-10-06) */
@media (max-width:899px){ .band--quote .pullquote{font-size:26px} }

/* rigidity words on phones (Michael, 2026-10-06): line height 1.25 for 26px type (was 1.3-1.4),
   and a little more room on the left: the copy starts 26% across instead of a third. the dark
   behind the words stays exactly where it was */
@media (max-width:899px){
  .band--quote .pullquote{line-height:1.25}
  .band--quote .band__copy{padding-left:26vw}
}

/* sections on phones twice as far apart (Michael, 2026-10-06): 96 -> 192, a step on the scale */
@media (max-width:899px){
  .band{margin-top:192px}
  section.opt{padding-top:192px}
}
/* unity (Michael, 2026-10-06): the contact section sits 13px further down (the page frame below On
   Process), so its top padding gives that back: every gap on phones measures 192 */
@media (max-width:899px){ section.opt{padding-top:calc(192px - var(--frame))} }

/* the form's options, a bead (Michael, 2026-10-06, the pick for all three (Michael's call,
   2026-10-06; v2b had none, v2d letters)): the numbers read as steps in a five-step flow. a hollow circle, the radio button's
   single-choice signal and a bead, fills with the accent when chosen */
section .inq .inq-opt__n{font-size:0; width:14px; height:14px; place-self:center start; box-sizing:border-box;
  border:1px solid rgba(236,231,223,.45); border-radius:50%; background:transparent;
  transition:background-color .4s var(--ease), border-color .4s var(--ease)}
section .inq .inq-opt:hover .inq-opt__n{border-color:var(--inq-accent)}
section .inq .inq-opt:has(input:checked) .inq-opt__n{background:var(--inq-accent); border-color:var(--inq-accent)}

/* ============================================================
   the form between choices, no bounce (Michael, 2026-10-06): nothing moves, things only fade.
   the old question fades out; the new one washes in left to right; its tiles appear in place one
   after another, top first, so the motion says "these are separate choices". the answer words
   fade in without rising
   ============================================================ */
.inq .inq-step, .inq .inq-step.is-on{transform:none}
.inq .inq-step{transition:opacity .5s var(--ease), visibility 0s .5s}
.inq .inq-step.is-on{transition:opacity .3s var(--ease) .3s}
.inq .inq-step.is-on .inq-step__q{animation:inq-wash 1.2s var(--ease) .35s both;
  -webkit-mask-image:linear-gradient(to right, #000 40%, transparent 60%); mask-image:linear-gradient(to right, #000 40%, transparent 60%);
  -webkit-mask-size:300% 100%; mask-size:300% 100%; -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat}
@keyframes inq-wash{
  from{opacity:0; -webkit-mask-position:100% 0; mask-position:100% 0}
  to{opacity:1; -webkit-mask-position:0 0; mask-position:0 0}}
.inq .inq-step.is-on .inq-opt{animation:inq-tile .8s var(--ease) both}
.inq .inq-step.is-on .inq-opt:nth-child(1){animation-delay:.6s}
.inq .inq-step.is-on .inq-opt:nth-child(2){animation-delay:.8s}
.inq .inq-step.is-on .inq-opt:nth-child(3){animation-delay:1s}
.inq .inq-step.is-on .inq-opt:nth-child(4){animation-delay:1.2s}
.inq .inq-step.is-on .inq-opt:nth-child(5){animation-delay:1.4s}
@keyframes inq-tile{from{opacity:0} to{opacity:1}}
@keyframes inq-word{from{opacity:0} to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .inq .inq-step.is-on .inq-step__q, .inq .inq-step.is-on .inq-opt{animation:none; -webkit-mask-image:none; mask-image:none}
}

/* In Place photo, phones (Michael, 2026-10-06): no longer tied to scroll. it fades in on a short
   timer as it enters the screen and stays at full strength. (.fig-timed is set by site.js; without
   it the scroll-linked fade above still applies) */
@media (max-width:899px){
  .fig-timed .band__fig .band__media > .plate{animation:none; opacity:0; transition:opacity .6s ease-out}
  .fig-timed .band__fig.is-in .band__media > .plate{opacity:1}
}

/* top bar steps aside on the way down and returns on the way up (Michael's proposal, 2026-10-06;
   v2d only). the name, its wash and Contact fade; the version menu stays. site.js "top bar, away" */
.top::before, .top .t-name{transition:opacity .5s var(--ease), color .35s var(--ease), border-color .35s var(--ease)}
.top.is-away::before, .top.is-away .t-name{opacity:0; pointer-events:none}
.top.is-away .top__contact{opacity:0 !important; pointer-events:none; transition:opacity .5s var(--ease) !important}
@media (prefers-reduced-motion:reduce){ .top.is-away::before, .top.is-away .t-name, .top.is-away .top__contact{opacity:1 !important; pointer-events:auto} }

/* Privacy and Terms as dialogs (Michael, 2026-10-06): black ground, the site's own type, no page of
   their own. opened from the footer links in site.js "legal dialogs"; X, Esc or a click outside closes */
dialog.legal{border:0; padding:0; margin:0; width:100%; max-width:none; height:100%; max-height:none;
  background:var(--ink-2,#121214); color:var(--paper,#e9e5df); overflow:auto; overscroll-behavior:contain}
dialog.legal::backdrop{background:var(--ink-2,#121214)}
dialog.legal[open]{animation:legal-in .35s var(--ease,ease) both}
@keyframes legal-in{from{opacity:0} to{opacity:1}}
.legal__body{max-width:44em; margin:0 auto; padding:96px 24px 128px}
@media (min-width:900px){ .legal__body{padding:128px 64px 160px} }
.legal__x{position:fixed; top:16px; right:16px; width:48px; height:48px; border:0; background:none; color:var(--paper-dim,#cfc9c1);
  font:300 36px/1 var(--sans); cursor:pointer; z-index:2}
.legal__x:hover, .legal__x:focus-visible{color:var(--paper,#e9e5df)}
.legal .t-h1{font-size:clamp(40px,5vw,64px); line-height:1.05; margin:0 0 32px}
.legal p, .legal li{font-family:var(--serif); font-weight:400; font-size:clamp(17px,1.3vw,19px); line-height:1.65; color:var(--paper-dim,#cfc9c1)}
.legal p{margin:0 0 16px}
.legal ul{margin:0 0 16px; padding-left:1.2em}
.legal li{margin:0 0 8px}
.legal h2.label{margin:48px 0 16px}
.legal strong{font-weight:500; color:var(--paper,#e9e5df)}
.legal a{color:inherit}
.legal .legal__draft{font-style:italic; margin-bottom:24px}
html.legal-open{overflow:hidden}
@media (prefers-reduced-motion:reduce){ dialog.legal[open]{animation:none} }

/* the close X takes none of the global button treatment (olive pill on hover) */
button.legal__x, button.legal__x:hover{background:none; border:0; border-radius:0; padding:0; margin:0; letter-spacing:normal; text-transform:none; box-shadow:none}
button.legal__x:hover{color:var(--paper,#e9e5df)}

/* the version menu is gone from final (Michael, 2026-10-06), so the footer drops the room it kept
   for it: back to the footer's own bottom padding, plus the phone's home-bar inset */
footer{padding-bottom:calc(48px + env(safe-area-inset-bottom))}

/* ============================================================
   rigidity, no pin at all (Michael, 2026-10-06, review with Adam): the photo and the words
   scroll with the page like any other section. no lock, no hold, no eased stop; the words
   still fade in slowly. phones keep the words over the full-bleed photo; desktop keeps the split. same as v2c
   ============================================================ */
.band--quote, .band--quote .band__media, .band--quote .band__copy, .band--quote .pullquote{animation:none !important}
.band--quote{view-timeline:none}
/* the words still fade in slowly as the section reaches the upper quarter of the screen
   ("rigidity" in site.js sets .is-locked; the slow fade rules above stay as they were) */
@media (min-width:900px){
  .band--quote{grid-template-rows:var(--rig-h)}
  .band--quote .band__media, .band--quote .band__copy{position:relative; top:auto}
}
@media (max-width:899px){
  .band--quote::after, html.rig-sda .band--quote::after{display:none; height:0}
  .band--quote .band__media{position:relative; top:auto}
  .band--quote .band__copy{position:relative; top:auto}
}

/* Adam's name in Jost ExtraLight (Michael, 2026-10-06: option 05 on the names page), set as
   the names page shows it on the bar: 14px, uppercase, .34em tracking. a face used nowhere
   else on the page, so the name reads as the mark */
.top .t-name{font-family:'Jost', var(--sans); font-stretch:normal; font-weight:200; font-size:14px; letter-spacing:.34em}

/* Contact and the menu in Archivo at its normal width (Michael, 2026-10-06): the wide cut stays
   the eyebrows' voice; normal width is the tool voice, and narrower on phones. uppercase, 400,
   lightly tracked so the capitals don't crowd */
.top .top__contact, .vswitch a{font-family:var(--sans); font-stretch:100%; font-weight:400; font-size:12px;
  letter-spacing:.14em; text-transform:uppercase}

/* the rigidity passage smaller on desktop (Michael, 2026-10-06): ceiling 53 -> 51, rate 2.6vw -> 2.45vw (about 35px at 1440, was 37) */
@media (min-width:900px){ .band--quote .pullquote{font-size:clamp(27px,2.45vw,51px)} }

/* the form in Adam's golden green, as v2c (Michael, 2026-10-06): the accent, the chosen option's
   tint, and the send button outlined in it at rest, filled once name and email are good */
section .inq{--inq-accent:#aea65a}
section .inq .inq-opt:has(input:checked){background:rgba(174,166,90,.08)}
section .inq .inq-send__btn, section .inq .inq-send__btn:hover{background:transparent; color:var(--inq-accent);
  box-shadow:inset 0 0 0 1px var(--inq-accent)}
section .inq.is-ready .inq-send__btn, section .inq.is-ready .inq-send__btn:hover{background:var(--inq-accent);
  color:var(--ink, #0a0a0b); box-shadow:none}

/* footer Privacy and Terms in the navigation's type (Michael, 2026-10-06): Archivo normal width,
   uppercase 400, 12px, lightly tracked */
footer .t-meta a{font-family:var(--sans); font-stretch:100%; font-weight:400; font-size:12px;
  letter-spacing:.14em; text-transform:uppercase}
/* (Michael, 2026-10-06) at rest the label is the site's white, the outline stays green */
section .inq:not(.is-ready) .inq-send__btn, section .inq:not(.is-ready) .inq-send__btn:hover{color:var(--paper)}

/* Adam's name stands out on load (Michael, 2026-10-06): 14 -> 16px, same ExtraLight, and a soft dark
   pool behind it (no blur) so the hairline strokes have a ground over the bright photo. it lives on
   the name, so it leaves with the name on scroll. strength set so the name clears WCAG 4.5:1 over
   the brightest part of the hero behind it */
.top .t-name{font-size:16px; position:relative; display:inline-block; isolation:isolate}
.top .t-name::before{content:""; position:absolute; z-index:-1; pointer-events:none;
  inset:-44px -72px -44px -64px;
  background:radial-gradient(closest-side, rgba(10,10,11,var(--name-pool,.8)) 0%, rgba(10,10,11,calc(var(--name-pool,.8) * .62)) 45%, rgba(10,10,11,0) 100%)}

/* the top glass is gone (Michael, 2026-10-06): no blur and no dark veil across the top of the screen.
   the name carries its own soft pool (above) for contrast */
.top::before{display:none}

/* the top bar's dark gradient is gone (Michael, 2026-10-07): it didn't work over the white palette.
   nothing behind the name and Contact for now; a new treatment to come. .top::before stays off
   (the "top glass is gone" rule above) */
.top .t-name::before{display:none}
/* no full-width darkening over the hero, desktop and phones (Michael, 2026-10-07): the photo at full strength,
   only the stripes behind the copy */
.hero::before{background:none}
/* desktop hero strips evened out (Michael, 2026-10-07): lighter in the middle (no dark spot behind
   "meaning"), a little stronger toward the edges, still feathered off before the oval's edge
   (was #000 10% / .86 34% / .42 58% / .11 78% / 0 96%) */
/* (Michael, 2026-10-07) then 10% darker all around: every step x1.1; the oval's center moved left and up, 50% 50% -> 40% 46% */
@media (min-width:900px){
  .hero__type.fx-cyl::before{
    -webkit-mask-image:radial-gradient(ellipse 50% 54% at 40% 46%,
        rgba(0,0,0,.77) 0%, rgba(0,0,0,.79) 30%, rgba(0,0,0,.66) 50%, rgba(0,0,0,.44) 66%,
        rgba(0,0,0,.2) 80%, rgba(0,0,0,.055) 90%, transparent 97%);
    mask-image:radial-gradient(ellipse 50% 54% at 40% 46%,
        rgba(0,0,0,.77) 0%, rgba(0,0,0,.79) 30%, rgba(0,0,0,.66) 50%, rgba(0,0,0,.44) 66%,
        rgba(0,0,0,.2) 80%, rgba(0,0,0,.055) 90%, transparent 97%)}
}
/* TRIAL (Michael, 2026-10-07): the hero photo a touch less bright with more definition, to judge by
   eye before baking into hero.jpg. desktop only; phones have their own image, treated separately. the stripes and the copy aren't touched (the filter is on the photo only) */
@media (min-width:900px){ .hero .plate{filter:brightness(.86) contrast(1.16)} }
/* desktop: the hero photo moved down (Michael, 2026-10-07) so the vanishing lines sit nearer the
   middle. --hero-drop is the one knob, in % of the screen's height; keep it under 12 (the layer's
   overscan above the screen) or the photo's top edge shows on load */
@media (min-width:900px){
  .hero .plate{--hero-drop:5%; top:calc(-12% + var(--hero-drop)); bottom:calc(-12% - var(--hero-drop))}
}
/* desktop: the hero photo turned .3deg (Michael, 2026-10-07, from the tuner) so the vanishing lines run
   level from left to right. scale 1.012 is a little more than any desktop shape needs (the worst,
   a tall window, needs ~1.008) so no corner ever shows, with the drop and the parallax allowed for */
@media (min-width:900px){ .hero .plate{rotate:.3deg; scale:1.012} }
/* desktop hero copy (Michael, 2026-10-07, trial): the tight shadow stays (it gives the strokes an
   edge so they stand off the photo between the stripes); the wide 18px glow is gone (it hazed the
   thin strokes; the stripes carry that job now) */
@media (min-width:900px){
  .hero__type .t-h1, .hero__type .t-intro, .hero__type .t-meta{text-shadow:0 1px 2px rgba(6,6,7,.45)}
}
/* desktop hero title and subhead crisper (Michael, 2026-10-07, trial): about halfway from the warm
   off-white (#e9e5df) to white, still warm; the location keeps the site's off-white */
@media (min-width:900px){
  .hero__type .t-h1, .hero__type .t-intro{color:#f4f2ef}
}

/* ============================================================
   desktop hero, option B from the tuner (Michael, 2026-10-07; stopgap/hero-tuner-options.md), in for
   now, to revisit at the end: the oval wide and left (center 19% 51%, size 100% 95%, darkness 1.29x,
   edge softness .83x), its box reaching far up (-129% -0% -58% -20%), finer stripes (6px spacing,
   shifted 28px, darkness .7), the photo at brightness .91, contrast 1
   ============================================================ */
@media (min-width:900px){
  .hero__type{--band:.7}
  .hero__type.fx-cyl::before{inset:-129% 0% -58% -20%;
    -webkit-mask-image:radial-gradient(ellipse 100% 95% at 19% 51%, rgba(0,0,0,.993) 0%, rgba(0,0,0,1) 24.9%, rgba(0,0,0,.851) 41.5%, rgba(0,0,0,.568) 54.8%, rgba(0,0,0,.258) 66.4%, rgba(0,0,0,.071) 74.7%, rgba(0,0,0,0) 80.5%);
    mask-image:radial-gradient(ellipse 100% 95% at 19% 51%, rgba(0,0,0,.993) 0%, rgba(0,0,0,1) 24.9%, rgba(0,0,0,.851) 41.5%, rgba(0,0,0,.568) 54.8%, rgba(0,0,0,.258) 66.4%, rgba(0,0,0,.071) 74.7%, rgba(0,0,0,0) 80.5%);
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,var(--band)) 0px, rgba(6,6,7,var(--band)) 1.125px,
        rgba(6,6,7,calc(var(--band) * .66)) 2.625px,
        rgba(6,6,7,calc(var(--band) * .91)) 4.5px,
        rgba(6,6,7,var(--band)) 6px);
    background-position:0 28px}
  .hero .plate{filter:brightness(.91) contrast(1)}
}
/* On Process H2 a little sturdier over the palette (Michael, 2026-10-07, trial): a hair of stroke in
   its own color, fading in and out with the palette (--pk) as the charcoal does; no change to its
   width, so nothing re-wraps */
.story--bleed .story__copy .t-h2{-webkit-text-stroke:calc(var(--pk, 0) * .4px) currentColor}
/* On Process copy lifted on desktop (Michael, 2026-10-07): 64 -> 96px from the bottom, the next step
   on the spacing scale; bottom-weighted like a mat, so it reads even with the 64px left */
@media (min-width:900px){ .story--bleed .story__copy{bottom:96px} }
/* In Place wall label (Michael, 2026-10-07): no longer tied to scroll. once it's 10% up into the screen
   it fades to full on a short timer and stays full; scrolling back below that point fades it away
   (.cap-in, site.js "In Place label") */
.band__fig > .caption{animation:none !important; opacity:0; transition:opacity .8s ease-out}
.band__fig > .caption.cap-in{opacity:1}
@media (prefers-reduced-motion:reduce){ .band__fig > .caption{opacity:1; transition:none} }
/* footer Privacy and Terms 12 -> 10px (Michael, 2026-10-07) */
footer .t-meta a{font-size:10px}
/* On Process on desktop stops 13px below the top of the screen (Michael, 2026-10-07), the same as the
   frame's left and right margin (--frame), so the pinned image has equal spacing on three sides; it
   runs to the bottom of the screen as before */
@media (min-width:900px){
  .story--bleed .story__stage{top:var(--frame); height:calc(100svh - 2 * var(--frame))}
  /* (Michael, 2026-10-07) and 13px clear of the bottom too: equal on all four sides */
  .story--bleed .story__frame{height:100%}
}
/* phones, hero (Michael, 2026-10-07): "Oakland, California" down from 13 to 11px (tracking scales with
   it); the subhead 8 -> 16px below the title so the g's descender has room */
@media (max-width:899px){
  .hero__type .t-meta{font-size:11px}
  .hero__type .t-intro{margin-top:16px}
}
/* phones, hero (Michael, 2026-10-07): the copy up 5% of the screen, 50% -> 45% */
@media (max-width:899px) and (min-height:541px){ .hero__type{top:45%} }
/* phones, hero title line height 1.08 -> 1.16 (Michael, 2026-10-07): room between the g's descender and the i's dot */
@media (max-width:899px){ .hero__type .t-h1{line-height:1.16} }
/* phones, hero photo a touch brighter (Michael, 2026-10-07, trial): brightness 1.12 once loaded (the
   blur-up still runs first) */
@media (max-width:899px){ .hero .plate.loaded{filter:blur(0) brightness(1.12)} }
/* phones, hero photo shifted left 5% (Michael, 2026-10-07): 58% -> 46% across (the right-edge column cut in half by the screen edge; 63-57 tried), so more of its right side shows */
@media (max-width:899px){ .hero .plate{background-position:46% 50%} }
/* phones: On Process fades in on scroll like the rigidity photo above it (Michael, 2026-10-07): the
   same fade, timed in screens the same way (starts as its top is 30% of a screen up, full by 83%) */
@supports (animation-timeline: view()){
  @media (max-width:899px) and (prefers-reduced-motion:no-preference){
    .band.story{view-timeline:--story block}
    .story__frame{animation:img-arrive ease-in-out both; animation-timeline:--story;
      animation-range:cover 30vh cover 83vh}
  }
}
/* phones, H2 line height 1.05 -> 1.16 (Michael, 2026-10-07): more room when they stack on two lines;
   matches the hero title's phone line height */
@media (max-width:899px){ .t-h2{line-height:1.16} }
/* phones, hero stripes as a tone, not lines (Michael, 2026-10-07, trial): fine 6px stripes (as option B)
   so they blend into an even darkening instead of running through the letters; a band that runs past
   both screen edges and fades only above and below the copy, so no dark spot */
@media (max-width:899px){
  .hero__type{--band:.85}
  .hero__type.fx-cyl::before{top:-55%; bottom:-45%; left:-50vw; right:-50vw;
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,var(--band)) 0px, rgba(6,6,7,var(--band)) 1.125px,
        rgba(6,6,7,calc(var(--band) * .66)) 2.625px,
        rgba(6,6,7,calc(var(--band) * .91)) 4.5px,
        rgba(6,6,7,var(--band)) 6px);
    background-position:0 0;
    -webkit-mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.35) 12%, rgba(0,0,0,.8) 24%,
        #000 34%, #000 72%, rgba(0,0,0,.8) 82%, rgba(0,0,0,.35) 91%, transparent 100%);
    mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.35) 12%, rgba(0,0,0,.8) 24%,
        #000 34%, #000 72%, rgba(0,0,0,.8) 82%, rgba(0,0,0,.35) 91%, transparent 100%);
    -webkit-mask-composite:source-over; mask-composite:add}
}
/* phones, hero (Michael, 2026-10-07): the whole copy block up 5% of the screen (45% -> 40%; 35 tried), spacing
   unchanged; the fine stripes behind it shaped as half an ellipse whose center sits on the screen's
   left edge: full strength along the left, its curve passing over the title, just past "by" at the end
   of the subhead's first line on the right, and back through the gap between "Oakland," and
   "California", so the lower right fades and shows the photo. measured at 375 wide on the words
   themselves; the box's left edge is the screen's (the copy is inset 24px) */
@media (max-width:899px) and (min-height:541px){ .hero__type{top:40%} }
@media (max-width:899px){
  .hero__type.fx-cyl::before{top:-120px; bottom:-120px; left:-24px; right:-40px;
    -webkit-mask-image:radial-gradient(120vw 145px at 0px 225px, #000 0%, #000 62%, rgba(0,0,0,.75) 80%,
        rgba(0,0,0,.45) 96%, rgba(0,0,0,.2) 110%, rgba(0,0,0,.06) 122%, transparent 132%);
    mask-image:radial-gradient(120vw 145px at 0px 225px, #000 0%, #000 62%, rgba(0,0,0,.75) 80%,
        rgba(0,0,0,.45) 96%, rgba(0,0,0,.2) 110%, rgba(0,0,0,.06) 122%, transparent 132%)}
}
/* (Michael, 2026-10-07) the phone half-ellipse 125 -> 145px tall: a little further above the W and below Oakland */
/* (Michael, 2026-10-07) and wider to the right, 100 -> 120vw (left edge unchanged): more behind "Adam A. Wier" and "California" */
/* (Michael, 2026-10-07) the phone half-ellipse down 20px, 205 -> 225 (copy unmoved): less under "Weaving", more under Oakland */
/* phones, hero subhead heavier (Michael, 2026-10-07, trial): Newsreader 250 -> 350, so the strokes hold
   their shape over the bead texture; same color and size */
@media (max-width:899px){ .hero__type .t-intro{font-weight:350} }

/* phones, On Process paragraph (Michael, 2026-10-07): paragraphs one step up, 17 -> 18px (every
   paragraph on phones, type changes are system-wide), and the dark behind the copy over the wood and
   the weave .605 -> .72 at its base, every stop scaled the same; over the palette it still steps away */
@media (max-width:899px){
  .wall{font-size:18px}
  .story--bleed .story__frame::after{background:linear-gradient(to top, rgba(10,10,11,0.720) 0px, rgba(10,10,11,0.720) calc(100lvh - 100svh + 190px), rgba(10,10,11,0.702) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.1), rgba(10,10,11,0.651) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.2), rgba(10,10,11,0.571) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.3), rgba(10,10,11,0.471) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.4), rgba(10,10,11,0.359) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.5), rgba(10,10,11,0.249) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.6), rgba(10,10,11,0.149) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.7), rgba(10,10,11,0.069) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.8), rgba(10,10,11,0.018) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 0.9), rgba(10,10,11,0.000) calc(100lvh - 100svh + 190px + (50% - (100lvh - 100svh + 190px)) * 1.0))}
}
/* phones, hero (Michael, 2026-10-07): the title and subhead centered on the screen as one block (equal
   space from the top of the screen to the W and from the subhead to the bottom); "Oakland, California"
   is left out of the centering and hangs below at its usual distance. the stripes ride with the block */
@media (max-width:899px) and (min-height:541px){
  .hero__type{top:50%; transform:translateY(calc(-50% + 9.5px)); width:calc(100vw - 40px); max-width:none}
  /* (Michael, 2026-10-07, from his phone: the whole block down 20px, -25.5 -> -5.5) */
  /* (Michael, 2026-10-07) copy and stripes together down another 15px, -5.5 -> +9.5 */
  /* (-25.5px: measured on the letters at 375x812, the top of the W's ink to the top of the screen equals the baseline under "Wier" to the bottom of the screen, 332px each) */
  .hero__type .t-meta{position:absolute; left:0; top:100%}
  /* (the width holds the block at its old measure, so the subhead breaks after "by" as before) */
}
/* phones, hero copy crisper (Michael, 2026-10-07, trial), as desktop: the wide 18px glow gone (no soft glow
   anywhere), only the tight shadow stays; title and subhead to #f4f2ef, the location keeps the off-white */
@media (max-width:899px){
  .hero__type .t-h1, .hero__type .t-intro, .hero__type .t-meta{text-shadow:0 1px 2px rgba(6,6,7,.45)}
  .hero__type .t-h1, .hero__type .t-intro{color:#f4f2ef}
}
/* phones, hero stripes (Michael, 2026-10-07, trial, subtle): a little more darkness above and to the left
   of the W, as if the half-ellipse came down on an angle there. a second, smaller mask layer added over
   the half-ellipse, strongest at the screen's left edge just above the W, fading to the right and up */
@media (max-width:899px){
  .hero__type.fx-cyl::before{
    -webkit-mask-image:radial-gradient(55vw 60px at 0px 112px, rgba(0,0,0,.42) 0%, rgba(0,0,0,.28) 45%, rgba(0,0,0,.1) 75%, transparent 100%),
        radial-gradient(120vw 145px at 0px 225px, #000 0%, #000 62%, rgba(0,0,0,.75) 80%,
        rgba(0,0,0,.45) 96%, rgba(0,0,0,.2) 110%, rgba(0,0,0,.06) 122%, transparent 132%);
    mask-image:radial-gradient(55vw 60px at 0px 112px, rgba(0,0,0,.42) 0%, rgba(0,0,0,.28) 45%, rgba(0,0,0,.1) 75%, transparent 100%),
        radial-gradient(120vw 145px at 0px 225px, #000 0%, #000 62%, rgba(0,0,0,.75) 80%,
        rgba(0,0,0,.45) 96%, rgba(0,0,0,.2) 110%, rgba(0,0,0,.06) 122%, transparent 132%)}
}
/* phones, hero (Michael, 2026-10-07, trial): stripes a touch darker behind the copy (--band .85 -> .9),
   and the photo brightness back down, 1.12 -> 1.05 */
@media (max-width:899px){
  .hero__type{--band:.9}
  .hero .plate.loaded{filter:blur(0) brightness(1.05)}
}
/* eyebrows dialed back (Michael, 2026-10-07, trial, desktop and phones): off the bright off-white to the
   site's secondary tone (--paper-dim, #cfc9c1), so they read less prominent than the headings under them.
   one knob, --eyebrow. On Process keeps its fade to charcoal over the palette, from the new tone */
:root{--eyebrow:var(--paper-dim)}
section .label{color:var(--eyebrow)}
.story--bleed .story__copy .label{color:color-mix(in srgb, #141416 calc(var(--pk, 0) * 100%), var(--eyebrow))}
/* phones, On Process palette (Michael, 2026-10-07, trial): the palette fitted to the screen (site.js)
   so on load the objects sit between the top and the eyebrow; the photo (palette-m-room2.jpg) has room
   around it, so it always fills the frame. a white glass behind the charcoal words, off on load: it comes in only as the
   objects reach the eyebrow (--pg), its top feathered so it has no edge */
@media (max-width:899px){
  .story--bleed .story__copy::before{content:""; position:absolute; z-index:-1; pointer-events:none;
    top:-30px; bottom:-140px; left:-24px; width:100vw; /* (Michael, 2026-10-07) its edge at the eyebrow, no haze above; a 44px soft edge, no hard line. edge to edge (the copy sits 24px in): on iPad portrait the 620px copy cap had left it short of the right edge */
    background:rgba(255,255,255,.38); /* .55 -> .38 (Michael, 2026-10-07): more color through */
    -webkit-backdrop-filter:blur(16px) saturate(1.15); backdrop-filter:blur(16px) saturate(1.15);
    -webkit-mask-image:linear-gradient(to bottom, transparent 0, rgba(0,0,0,.15) 11px, rgba(0,0,0,.5) 22px, rgba(0,0,0,.85) 33px, #000 44px);
    mask-image:linear-gradient(to bottom, transparent 0, rgba(0,0,0,.15) 11px, rgba(0,0,0,.5) 22px, rgba(0,0,0,.85) 33px, #000 44px);
    opacity:var(--pg, 0)}
}
/* ============================================================
   desktop hero, from the tuner (Michael, 2026-10-07), replaces option B: oval center 16% 55%, size
   100% 61%, darkness 1.5x, edge softness .68x; box -112% -100% -59% -41%; stripes darkness .8,
   6px spacing, shifted 28px; photo brightness 1.1, contrast 1
   ============================================================ */
@media (min-width:900px){
  .hero__type{--band:.8}
  .hero__type.fx-cyl::before{inset:-112% -100% -59% -41%;
    -webkit-mask-image:radial-gradient(ellipse 100% 61% at 16% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    mask-image:radial-gradient(ellipse 100% 61% at 16% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,var(--band)) 0px, rgba(6,6,7,var(--band)) 1.125px,
        rgba(6,6,7,calc(var(--band) * .66)) 2.625px,
        rgba(6,6,7,calc(var(--band) * .91)) 4.5px,
        rgba(6,6,7,var(--band)) 6px);
    background-position:0 28px}
  .hero .plate{filter:brightness(1.1) contrast(1)}
}
/* ============================================================
   desktop hero, from the tuner (Michael, 2026-10-07, locked in): the oval moved right and made
   smaller, center 30% 55%, size 78% 46%; darkness 1.5x, edge softness .68x; box -112% -100% -59% -41%;
   stripes darkness .8, 6px spacing, shifted 28px; photo brightness 1.1, contrast 1
   ============================================================ */
@media (min-width:900px){
  .hero__type{--band:.8}
  .hero__type.fx-cyl::before{inset:-112% -100% -59% -41%;
    -webkit-mask-image:radial-gradient(ellipse 78% 46% at 30% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    mask-image:radial-gradient(ellipse 78% 46% at 30% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,var(--band)) 0px, rgba(6,6,7,var(--band)) 1.125px,
        rgba(6,6,7,calc(var(--band) * .66)) 2.625px,
        rgba(6,6,7,calc(var(--band) * .91)) 4.5px,
        rgba(6,6,7,var(--band)) 6px);
    background-position:0 28px}
  .hero .plate{filter:brightness(1.1) contrast(1)}
}
/* On Process, desktop, the raw wood and the weave (Michael, 2026-10-07, starting point to dial in):
   the hero's treatment behind the copy, same units: one oval, center 30% 55%, size 78% 46%, darkness
   1.5x, softness .68x, box -112% -100% -59% -41% of the copy's box, the fine 6px stripes at .8, shifted
   28px. replaces the 16px strips and their run-in from the left (::after off). over the palette it
   still steps away (--pk) */
@media (min-width:900px){
  .story--bleed .story__copy::after{display:none}
  .story--bleed .story__copy::before{inset:-112% -100% -59% -41%;
    -webkit-mask-image:radial-gradient(ellipse 78% 46% at 30% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    -webkit-mask-composite:source-over;
    mask-image:radial-gradient(ellipse 78% 46% at 30% 55%, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 20.4%, rgba(0,0,0,.99) 34%, rgba(0,0,0,.66) 44.9%, rgba(0,0,0,.3) 54.4%, rgba(0,0,0,.083) 61.2%, rgba(0,0,0,0) 66%);
    mask-composite:add;
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,.8) 0px, rgba(6,6,7,.8) 1.125px,
        rgba(6,6,7,calc(.8 * .66)) 2.625px,
        rgba(6,6,7,calc(.8 * .91)) 4.5px,
        rgba(6,6,7,.8) 6px);
    background-position:0 28px}
}
/* On Process, desktop, raw wood and weave, from ?tune=process (Michael, 2026-10-07): oval center
   47% 60%, size 59% 46%, darkness 1.26x, edge softness .81x; box -140% -68% -82% -100% of the copy's
   box; stripes darkness 1, 6px, shifted 28px; those two photos at brightness .96, contrast 1 */
@media (min-width:900px){
  .story--bleed .story__copy::before{inset:-140% -68% -82% -100%;
    -webkit-mask-image:radial-gradient(ellipse 59% 46% at 47% 60%, rgba(0,0,0,.970) 0%, rgba(0,0,0,.995) 24.3%, rgba(0,0,0,.832) 40.5%, rgba(0,0,0,.554) 53.5%, rgba(0,0,0,.252) 64.8%, rgba(0,0,0,.069) 72.9%, rgba(0,0,0,0) 78.6%);
    mask-image:radial-gradient(ellipse 59% 46% at 47% 60%, rgba(0,0,0,.970) 0%, rgba(0,0,0,.995) 24.3%, rgba(0,0,0,.832) 40.5%, rgba(0,0,0,.554) 53.5%, rgba(0,0,0,.252) 64.8%, rgba(0,0,0,.069) 72.9%, rgba(0,0,0,0) 78.6%);
    background-image:repeating-linear-gradient(to bottom,
        rgba(6,6,7,1) 0px, rgba(6,6,7,1) 1.125px,
        rgba(6,6,7,.66) 2.625px,
        rgba(6,6,7,.91) 4.5px,
        rgba(6,6,7,1) 6px);
    background-position:0 28px}
  .story--bleed .story__img--raw, .story--bleed .story__img--made{filter:brightness(.96) contrast(1)}
}
/* On Process, desktop, raw wood and weave (Michael, 2026-10-07, trial): the copy held crisp as the
   weave zooms out to small, busy beads. (1) a soft blur of the photo behind the words, under the
   stripes, shaped by the same oval and box so it has no edge; it steps away over the palette with
   the stripes (--pk). (2) the heading and paragraph brighter, #f4f2ef as the hero (the paragraph's
   color is set in site.js), with the hero's tight 1-2px shadow, no glow; the shadow fades out over
   the palette, where the words are charcoal */
@media (min-width:900px){
  .story--bleed .story__copy::after{display:block; content:""; position:absolute; z-index:0; pointer-events:none;
    inset:-140% -68% -82% -100%; background:none;
    -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); /* 10 -> 6px (Michael, 2026-10-07) */
    -webkit-mask-image:radial-gradient(ellipse 59% 46% at 47% 60%, rgba(0,0,0,.970) 0%, rgba(0,0,0,.995) 24.3%, rgba(0,0,0,.832) 40.5%, rgba(0,0,0,.554) 53.5%, rgba(0,0,0,.252) 64.8%, rgba(0,0,0,.069) 72.9%, rgba(0,0,0,0) 78.6%);
    mask-image:radial-gradient(ellipse 59% 46% at 47% 60%, rgba(0,0,0,.970) 0%, rgba(0,0,0,.995) 24.3%, rgba(0,0,0,.832) 40.5%, rgba(0,0,0,.554) 53.5%, rgba(0,0,0,.252) 64.8%, rgba(0,0,0,.069) 72.9%, rgba(0,0,0,0) 78.6%);
    opacity:calc(1 - var(--pk, 0))}
  .story--bleed .story__copy .label, .story--bleed .story__copy .t-h2{position:relative; z-index:2}
  .story--bleed .story__copy .t-h2{color:color-mix(in srgb, #141416 calc(var(--pk, 0) * 100%), #f4f2ef)}
  .story--bleed .story__copy .t-h2, .story--bleed .story__copy .wall{text-shadow:0 1px 2px rgba(6,6,7,calc(.45 * (1 - var(--pk, 0))))}
}
/* On Process, desktop, raw wood and weave, from ?tune=process (Michael, 2026-10-07, second set): oval
   center 47% 64%, size 59% 46%, darkness 1.27x, edge softness .76x; box -140% -60% -82% -63%; stripes
   darkness 1, 6px, shifted 28px; photos brightness .96, contrast 1; the blur behind the words 6px on the
   same oval and box */
@media (min-width:900px){
  .story--bleed .story__copy::before, .story--bleed .story__copy::after{inset:-140% -60% -82% -63%;
    -webkit-mask-image:radial-gradient(ellipse 59% 46% at 47% 64%, rgba(0,0,0,.978) 0%, rgba(0,0,0,1) 22.8%, rgba(0,0,0,.838) 38%, rgba(0,0,0,.559) 50.2%, rgba(0,0,0,.254) 60.8%, rgba(0,0,0,.07) 68.4%, rgba(0,0,0,0) 73.7%);
    mask-image:radial-gradient(ellipse 59% 46% at 47% 64%, rgba(0,0,0,.978) 0%, rgba(0,0,0,1) 22.8%, rgba(0,0,0,.838) 38%, rgba(0,0,0,.559) 50.2%, rgba(0,0,0,.254) 60.8%, rgba(0,0,0,.07) 68.4%, rgba(0,0,0,0) 73.7%)}
}
/* ============================================================
   desktop hero, from the tuner (Michael, 2026-10-07, latest): oval center 30% 55%, size 78% 76%,
   darkness 1.17x, edge softness .63x; box -90% -100% -40% -41%; stripes darkness 1, 6px, shifted
   28px; photo brightness .85, contrast 1
   ============================================================ */
@media (min-width:900px){
  .hero__type{--band:1}
  .hero__type.fx-cyl::before{inset:-90% -100% -40% -41%;
    -webkit-mask-image:radial-gradient(ellipse 78% 76% at 30% 55%, rgba(0,0,0,.901) 0%, rgba(0,0,0,.924) 18.9%, rgba(0,0,0,.772) 31.5%, rgba(0,0,0,.515) 41.6%, rgba(0,0,0,.234) 50.4%, rgba(0,0,0,.064) 56.7%, rgba(0,0,0,0) 61.1%);
    mask-image:radial-gradient(ellipse 78% 76% at 30% 55%, rgba(0,0,0,.901) 0%, rgba(0,0,0,.924) 18.9%, rgba(0,0,0,.772) 31.5%, rgba(0,0,0,.515) 41.6%, rgba(0,0,0,.234) 50.4%, rgba(0,0,0,.064) 56.7%, rgba(0,0,0,0) 61.1%);
    background-position:0 28px}
  .hero .plate{filter:brightness(.85) contrast(1)}
}
/* ============================================================
   top bar (Michael, 2026-10-07, from ?tune=nav): a top-down dark gradient behind the name and
   Contact, full darkness at the top easing out over 182px, no blur. over the white palette (--pk,
   handed from the story script) the gradient fades away and the name and Contact go charcoal, so the
   white stays clean. it still leaves with the name on scroll (.is-away)
   ============================================================ */
.top::before{display:block; height:182px;
  background:linear-gradient(to bottom, rgba(18,18,20,1) 0%, rgba(18,18,20,.845) 10%, rgba(18,18,20,.700) 20%,
    rgba(18,18,20,.565) 30%, rgba(18,18,20,.442) 40%, rgba(18,18,20,.330) 50%, rgba(18,18,20,.231) 60%,
    rgba(18,18,20,.146) 70%, rgba(18,18,20,.076) 80%, rgba(18,18,20,.025) 90%, rgba(18,18,20,0) 100%);
  -webkit-backdrop-filter:none; backdrop-filter:none;
  -webkit-mask-image:linear-gradient(to bottom, #000 0%, #000 40%, transparent 100%);
  mask-image:linear-gradient(to bottom, #000 0%, #000 40%, transparent 100%);
  opacity:calc(1 - var(--pk, 0))}
.top a.t-name, .top a.top__contact{color:color-mix(in srgb, #141416 calc(var(--pk, 0) * 100%), var(--paper))}

/* tablets in portrait (600-899 wide, Michael 2026-10-07): the phone layout, scaled up so the words
   read as the phone's column, not four long lines across the beads; phones keep 26px */
@media (min-width:600px) and (max-width:899px){
  .band--quote .pullquote{font-size:clamp(30px,4.2vw,37px)}
  .band--quote .band__copy{padding-left:40vw}
}

/* the form section, desktop (Michael, 2026-10-07): the screen split 50/50 and the intro free to fill its
   half, as In Place's copy does, so "Commission + Collaboration" can sit on one line and the paragraph
   opens up on wide screens. the answers keep their width (the form column's 34rem cap stays) */
@media (min-width:900px){ .opt__inner > div:first-child{max-width:none} }
/* 50/50 from 1400 up, where the form's half is already wider than the answers' 34rem: the answers
   come out exactly as before at every width */
@media (min-width:1400px){ .opt__inner{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }
