/* ===== ported from SERA-site-index-v2 — the after-the-Measure chapters ===== */
:root{--hairline-dark:rgba(16,17,20,.16)}
.caps{font-family:var(--sans);font-weight:400}
.prose{font-family:var(--serif);font-size:clamp(16px,1.3vw,19.5px);line-height:1.8}
/* the chapter variant of the label — same 11px / 500 / .24em spec as base.css */
.plates .eyebrow,.doctrine .eyebrow,.house .eyebrow,.path .eyebrow,.voices .eyebrow,.faq .eyebrow,.begin .eyebrow{display:flex;align-items:center;gap:14px;font-family:var(--sans);font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:rgba(233,236,238,.55);font-weight:500}
.plates .eyebrow::after,.doctrine .eyebrow::after,.house .eyebrow::after,.path .eyebrow::after,.voices .eyebrow::after,.faq .eyebrow::after,.begin .eyebrow::after{content:none}
.plates .eyebrow::before,.doctrine .eyebrow::before,.house .eyebrow::before,.path .eyebrow::before,.voices .eyebrow::before,.faq .eyebrow::before,.begin .eyebrow::before{content:"";width:38px;height:1px;background:linear-gradient(90deg,var(--teal-deep),transparent);flex:none}
/* The ivory-ground variant, doubled up as `.eyebrow.eyebrow--light` so it can
   actually win. As a single class it is (0,1,0) and the scoped rule above is
   (0,2,0), so it NEVER applied — every ivory eyebrow was quietly rendering in
   the dark-ground colour instead. That went unseen while both colours were
   --steel, a mid blue-grey that survives either ground; the moment the label
   colour moved to porcelain it became invisible on ivory. Doubling the class
   matches specificity, and source order does the rest. */
/* .62, not the .55 used on dark grounds. Obsidian ink on ivory is a weaker
   pairing than porcelain ink on obsidian, so the symmetric alpha is not the
   symmetric result: .55 measures 4.01:1 here against 5.44:1 there. .62 puts it
   at 5.0:1 — still recessive, and now actually legible. */
.eyebrow.eyebrow--light{color:rgba(16,17,20,.62)}
.eyebrow.eyebrow--light::before{background:linear-gradient(90deg,rgba(16,17,20,.5),transparent)}
/* line-mask title reveal */
/* The mask needs room under the baseline. These titles run at line-height .92
   to 1.04, so the line box is SHORTER than the em box, and `overflow:hidden`
   then slices the descender off any g/j/p/y — visibly, on the "y" of
   "as you are.". Pad the mask and pull the padding back out of the layout, so
   nothing moves and the tail survives.
   The rest position goes to 140% to match: at 112% a taller mask would let the
   top of the glyph peek above the fold before the reveal fires. */
.lm{display:block;overflow:hidden;padding-bottom:.16em;margin-bottom:-.16em}
.js .lm i{display:block;font-style:inherit;transform:translateY(140%);transition:transform 1.15s cubic-bezier(.19,.74,.22,1)}
.lm i{display:block;font-style:inherit}
.lm:nth-child(2) i{transition-delay:.12s}
.tit.on .lm i{transform:none}
/* `.js .lm i` is (0,2,1), so this had to gain the same class or it would have
   silently lost to it — the specificity trap this file keeps walking into.
   `.tit.on .lm i` at (0,3,1) still outranks both, which is correct. */
@media (prefers-reduced-motion:reduce){.js .lm i{transform:none}}
.progress{position:fixed;top:0;left:0;height:2px;width:100%;z-index:700;transform-origin:0 50%;transform:scaleX(0);background:linear-gradient(90deg,var(--teal-deep),var(--teal))}
.rail{position:fixed;left:26px;top:50%;z-index:590;transform:translateY(-50%) rotate(180deg);writing-mode:vertical-rl;font-family:var(--sans);font-size:9px;font-weight:400;letter-spacing:.5em;text-transform:uppercase;color:rgba(233,236,238,.55);opacity:.85;transition:color .5s;pointer-events:none;white-space:nowrap}
.rail--dark{color:rgba(16,17,20,.45)}
@media (max-width:1100px){.rail{display:none}}
@media (max-width:900px){.nav__links{display:none}}

.ghostword{position:absolute;z-index:1;font-family:var(--serif);font-weight:500;line-height:1;pointer-events:none;user-select:none;color:transparent;-webkit-text-stroke:1px rgba(233,236,238,.06)}
.ghostword--dark{-webkit-text-stroke:1px rgba(16,17,20,.06)}
/* S2 plates — matted, framed prints */
.plates{background:var(--obsidian)}
.plateWrap{height:200vh;position:relative}
.plate{position:sticky;top:0;height:100svh;overflow:hidden;display:grid;grid-template-columns:55% 45%;background:var(--obsidian)}
.plate--flip{grid-template-columns:45% 55%}
.plate__media{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:radial-gradient(120% 90% at 50% 45%,#121317 0%,var(--obsidian) 70%)}
.plate--flip .plate__media{order:2}
.plate__ghost{position:absolute;z-index:1;font-family:var(--serif);font-style:italic;font-weight:500;font-size:clamp(120px,15vw,260px);color:transparent;-webkit-text-stroke:1px rgba(233,236,238,.07);line-height:1;pointer-events:none;left:6%;bottom:4vh}
.plate__frame{position:relative;z-index:2;height:min(74svh,820px);border:1px solid rgba(233,236,238,.14);background:#0d0e11;padding:12px;box-shadow:0 60px 120px -50px rgba(0,0,0,.85);will-change:clip-path}
.plate__frame .ph{width:100%;height:100%;overflow:hidden}
.plate__frame img{height:100%;width:100%;object-fit:cover;will-change:transform}
.plate__cap{position:relative;z-index:2;font-family:var(--sans);font-size:8.5px;font-weight:400;letter-spacing:.4em;text-transform:uppercase;color:rgba(233,236,238,.4)}
.plate__copy{position:relative;display:flex;flex-direction:column;justify-content:center;padding:0 clamp(28px,4.5vw,84px);z-index:2}
.plate__tick{position:absolute;top:12vh;right:clamp(28px,4.5vw,84px);font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.4em;color:rgba(233,236,238,.55)}
.plate__num{font-family:var(--serif);font-style:italic;font-weight:500;font-size:17px;color:var(--teal);opacity:.85}
.plate__name{font-family:var(--serif);font-weight:500;font-size:clamp(30px,3.4vw,54px);line-height:1.02;letter-spacing:.02em;text-transform:uppercase;margin-top:14px}
.plate__promise{font-family:var(--serif);font-style:italic;font-weight:500;font-size:clamp(18px,1.6vw,25px);color:rgba(233,236,238,.8);margin-top:12px}
.plate__body{margin-top:22px;color:rgba(233,236,238,.68);max-width:46ch}
.plate__list{margin-top:26px;border-top:1px solid var(--hairline)}
.plate__list div{padding:12px 0;border-bottom:1px solid var(--hairline);font-family:var(--sans);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:rgba(233,236,238,.55);font-weight:400;display:flex;justify-content:space-between;gap:14px}
.plate__list b{font-weight:500;color:rgba(233,236,238,.42);font-family:var(--serif);font-style:italic;text-transform:none;letter-spacing:.04em;font-size:14px}
.plate__cta{margin-top:32px}
.plate__cta a{display:inline-block;font-family:var(--sans);font-size:10px;letter-spacing:.3em;text-transform:uppercase;font-weight:500;border-bottom:1px solid rgba(233,236,238,.35);padding-bottom:5px;transition:border-color .4s,color .4s}
.plate__cta a:hover{border-color:var(--teal);color:#fff}
@media (max-width:900px){
  .plateWrap{height:auto}
  .plate{position:relative;height:auto;grid-template-columns:1fr;padding:64px 0 24px}
  /* was `order:-1 !important` — it only had to beat `.plate--flip .plate__media`
     at (0,2,0). Matching the specificity says which rule wins and why; the
     !important said only that one of them did. */
  .plate__media,.plate--flip .plate__media{order:-1;padding:0 var(--gutter)}
  .plate__frame{height:auto;width:100%}
  .plate__frame img{height:auto}
  .plate__copy{padding:30px var(--gutter) 46px}
  .plate__ghost,.plate__tick{display:none}
}

/* S3 doctrine — ivory editorial */
.doctrine{position:relative;background:var(--ivory);color:#141518;overflow:hidden}
.doctrine .ghostword{right:-2%;top:4%;font-size:clamp(160px,22vw,360px)}
.doctrine__grid{position:relative;z-index:2;display:grid;grid-template-columns:44% 56%;gap:clamp(30px,5vw,80px);max-width:1360px;margin:0 auto;padding:clamp(100px,13vw,170px) var(--gutter)}
.doctrine__mediaCol{display:flex;flex-direction:column;align-items:center}
.doctrine__frame{width:min(100%,470px);border:1px solid rgba(16,17,20,.2);background:#fff;padding:12px;box-shadow:0 50px 100px -45px rgba(16,17,20,.5)}
.doctrine__frame .ph{aspect-ratio:4/5;overflow:hidden;background:var(--coal)}
.doctrine__frame img{width:100%;height:100%;object-fit:cover;object-position:center 10%}
.doctrine__credit{margin-top:18px;text-align:center}
.doctrine__credit .name{font-family:var(--serif);font-weight:500;font-size:20px;letter-spacing:.06em}
.doctrine__credit .role{font-family:var(--sans);font-size:9px;font-weight:400;letter-spacing:.36em;text-transform:uppercase;color:rgba(16,17,20,.5);margin-top:7px}
.doctrine__mono{margin-top:20px;font-family:var(--serif);font-style:italic;font-weight:500;font-size:25px;color:rgba(16,17,20,.65);letter-spacing:.14em}
.doctrine__copy{max-width:660px}
.doctrine__title{font-family:var(--serif);font-weight:500;font-size:clamp(30px,3.6vw,56px);line-height:1.04;letter-spacing:.02em;text-transform:uppercase;margin-top:24px}
.doctrine__p{margin-top:24px;color:rgba(16,17,20,.78);max-width:58ch}
.doctrine__p:first-of-type::first-letter{font-family:var(--serif);font-weight:500;font-size:3.3em;float:left;line-height:.84;padding:5px 12px 0 0;color:#141518}
.doctrine__pull{margin:40px 0 0;padding:26px 0;border-top:1px solid var(--hairline-dark);border-bottom:1px solid var(--hairline-dark);font-family:var(--serif);font-style:italic;font-weight:500;font-size:clamp(20px,1.9vw,30px);color:#141518;line-height:1.4}
@media (max-width:900px){.doctrine__grid{grid-template-columns:1fr}}

/* S5 path */
.path{position:relative;background:var(--obsidian);padding:clamp(110px,14vw,180px) var(--gutter);overflow:hidden}
.path .ghostword{left:-1%;top:8%;font-size:clamp(150px,20vw,330px)}
.path__head{position:relative;z-index:2;text-align:center;margin-bottom:clamp(60px,8vw,110px)}
.path__head .eyebrow{justify-content:center}.path__head .eyebrow::before{display:none}
.path__title{font-family:var(--serif);font-weight:500;font-size:clamp(30px,4vw,60px);letter-spacing:.02em;text-transform:uppercase;margin-top:16px}
.path__lede{margin-top:14px;font-family:var(--serif);font-style:italic;font-weight:500;font-size:clamp(15px,1.3vw,20px);color:rgba(233,236,238,.55)}
.path__rail{position:relative;z-index:2;max-width:1060px;margin:0 auto}
.path__line{position:absolute;left:50%;top:0;bottom:0;width:1px;background:var(--hairline)}
.path__fill{position:absolute;left:50%;top:0;width:1px;height:100%;background:linear-gradient(180deg,var(--teal-deep),var(--teal) 70%,var(--teal-ice));transform-origin:50% 0;transform:scaleY(0);box-shadow:0 0 12px rgba(43,197,196,.35)}
.step{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,6vw,90px);padding:clamp(34px,4.5vw,64px) 0}
.step__cell{max-width:440px}
.step:nth-of-type(odd) .step__cell{grid-column:1;justify-self:end;text-align:right}
.step:nth-of-type(even) .step__cell{grid-column:2;justify-self:start}
.step__num{font-family:var(--serif);font-style:italic;font-weight:500;font-size:16px;color:var(--teal);opacity:.9}
.step__name{font-family:var(--serif);font-weight:500;font-size:clamp(22px,2.2vw,34px);text-transform:uppercase;letter-spacing:.04em;margin-top:10px}
.step__body{margin-top:12px;color:rgba(233,236,238,.66)}
.step__dot{position:absolute;left:50%;top:clamp(44px,5.4vw,74px);width:5px;height:5px;margin-left:-2.5px;border-radius:50%;background:var(--teal);opacity:.85;box-shadow:0 0 8px rgba(43,197,196,.5)}
.path__bead{position:relative;z-index:2;width:26px;margin:10px auto 0;filter:drop-shadow(0 6px 14px rgba(43,197,196,.35))}
.path__bead img{width:100%;height:auto}
.path__after{position:relative;z-index:2;text-align:center;margin-top:18px;font-family:var(--serif);font-style:italic;font-weight:500;font-size:17px;color:rgba(233,236,238,.72)}
.path__cta{position:relative;z-index:2;text-align:center;margin-top:clamp(34px,4vw,54px)}
/* the same closing move on /house — one shared rule, so the pages cannot drift */
.house__cta{position:relative;z-index:2;text-align:center}
/* `.person.person--close`, not `.person--close`. The modifier is declared here,
   570 lines ABOVE `.person` itself — same specificity, earlier in the file, so
   `.person`'s own padding won and the modifier had never once applied. This is
   the fifth instance of the pattern, found by sweeping for it rather than by
   noticing something render wrong; unlike the other four it is invisible,
   which is exactly why it survived. */
.person.person--close{padding:clamp(46px,6vw,86px) var(--gutter)}
/* .btn in ink polarity, the values the inverted nav already uses */
.btn--ink{border-color:rgba(16,17,20,.35);color:#101114}
.btn--ink:hover{border-color:rgba(16,17,20,.7)}
/* The straight rail is retired — components/sera-coil.js replaced it and
   initPath() is a stub — so .path__line and .path__fill draw nothing, and the
   44px indent they were paired with belonged to a component that no longer
   exists. It was still winning between 768 and 900, where it put the copy at
   44px and left the coil crossing it by a measured 31px. Removed with the
   system it served: deleting a component means auditing the CSS that dressed
   it, which is the fourth time that has been the lesson. */
@media (max-width:900px){
  .step{grid-template-columns:1fr}
}

/* S6 voices */
#voicesWrap{height:280vh;position:relative}
/* The poster is the section background, not just the video element's poster:
   a <video> drops its poster attribute once metadata arrives but before it has
   painted a frame, and that window renders as a black section. Behind the film
   there is now always an image, so the gap cannot exist. */
/* The photograph meets the ground in the ground's OWN colour, so there is no
   transition to see and nothing to feather. No poster background any more —
   the film it stood in for is gone, and an <img> does not drop its picture the
   way a <video> drops its poster. */
.voices{position:sticky;top:0;height:100svh;overflow:hidden;display:flex;align-items:center;
  justify-content:flex-start;padding-left:var(--gutter);background:var(--obsidian)}
.voices .ghostmark{position:absolute;z-index:1;left:50%;top:44%;transform:translate(-50%,-50%);font-family:var(--serif);font-size:clamp(300px,44vw,720px);line-height:1;color:rgba(233,236,238,.045);pointer-events:none}
/* LEFT, IN THE DARK THIRD — the hero's language, subject right and void left,
   spoken here too. The chair and the lamp hold the right of the frame; the
   quote takes the black wall beside them and is ranged left, not centred. */
.voices__stage{position:relative;z-index:4;width:min(680px,46vw);height:46svh;text-align:left}
.voice{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;opacity:0;will-change:transform,opacity;transform-origin:50% 50%}
.voice .q{font-family:var(--serif);font-style:italic;font-weight:500;font-size:clamp(27px,3.9vw,58px);line-height:1.17;letter-spacing:-.005em;color:var(--porcelain);text-shadow:0 2px 34px rgba(10,11,13,.5)}
/* Small and quiet, but it has to survive the lifted film: --steel over the lit
   band measures about 1.3:1 and simply vanishes. Porcelain at low alpha keeps
   it recessive without making it a guess. */
.voice .a{margin-top:clamp(20px,2.4vw,32px);font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.34em;
  text-transform:uppercase;color:rgba(233,236,238,.66);text-shadow:0 1px 16px rgba(10,11,13,.7)}
/* the label follows the quote to the left edge — a centred label over a
   left-ranged quote reads as an oversight rather than a composition */
.voices .eyebrow{position:absolute;top:9vh;left:var(--gutter);transform:none;z-index:2}
.voices .eyebrow::before{display:none}

/* S7 questions */
.faq{background:var(--ivory);color:#101114;padding:clamp(100px,13vw,170px) var(--gutter);position:relative;overflow:hidden}
.faq .ghostword{left:-2%;bottom:-6%;font-size:clamp(150px,20vw,330px)}
.faq__grid{position:relative;z-index:2;display:grid;grid-template-columns:38% 62%;gap:clamp(30px,5vw,80px);max-width:1240px;margin:0 auto}
.faq__title{font-family:var(--serif);font-weight:500;font-size:clamp(28px,3.4vw,52px);line-height:1.05;text-transform:uppercase;letter-spacing:.02em;margin-top:18px}
.faq__sub{margin-top:16px;color:rgba(16,17,20,.66);max-width:38ch}
.qa{border-top:1px solid var(--hairline-dark)}
.qa:last-child{border-bottom:1px solid var(--hairline-dark)}
.qa__btn{width:100%;display:flex;align-items:baseline;gap:18px;background:none;border:none;cursor:pointer;padding:22px 0;text-align:left;font-family:var(--serif);font-weight:500;font-size:clamp(17px,1.5vw,23px);color:#101114}
.qa__no{font-style:italic;font-size:13px;font-weight:400;color:var(--teal-deep);min-width:26px}
.qa__btn .x{margin-left:auto;font-family:var(--sans);font-weight:300;font-size:20px;color:rgba(16,17,20,.5);transition:transform .45s cubic-bezier(.2,.6,.2,1)}
.qa.open .qa__btn .x{transform:rotate(45deg)}
.qa__panel{max-height:0;overflow:hidden;transition:max-height .6s cubic-bezier(.2,.6,.2,1)}
.qa__panel p{padding:0 0 22px 44px;color:rgba(16,17,20,.68);max-width:58ch}
@media (max-width:900px){.faq__grid{grid-template-columns:1fr}}

/* S8 begin */
.begin{background:var(--obsidian);padding:clamp(110px,14vw,180px) var(--gutter) 0;position:relative;overflow:hidden}
/* `.invite` as well as `.begin`. The closing invitation on home carries the same
   BEGIN watermark, but home's section is `.invite` and only `/consultation` is
   `.begin` — so home's has been rendering at the inherited 16px, 48px wide and
   invisible, since the restructure split the two. Found by measuring the
   watermarks rather than by looking at them, which is the only way a 48px word
   on a black ground is ever going to be found. */
.begin__grid{position:relative;z-index:2;display:grid;grid-template-columns:1fr 1fr;gap:clamp(34px,6vw,100px);max-width:1240px;margin:0 auto}
.begin__title{font-family:var(--serif);font-weight:500;font-size:clamp(44px,6.4vw,110px);line-height:.92;letter-spacing:-.01em;text-transform:uppercase;margin-top:20px}
.begin__title em{font-style:italic}
.begin__sub{margin-top:22px;color:rgba(233,236,238,.68);max-width:46ch}
.begin__meta{margin-top:34px;font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.28em;text-transform:uppercase;color:rgba(233,236,238,.55);line-height:2.2}
.form{background:var(--coal);border:1px solid var(--hairline);padding:clamp(26px,3vw,44px)}
.form__head{margin-bottom:26px;padding-bottom:20px;border-bottom:1px solid var(--hairline)}
.form__head .t{font-family:var(--serif);font-weight:500;font-size:22px;letter-spacing:.04em}
.form__head .s{margin-top:6px;font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.26em;text-transform:uppercase;color:rgba(233,236,238,.55)}
.f__row{margin-bottom:22px}
.f__label{display:block;font-family:var(--sans);font-size:9.5px;font-weight:400;letter-spacing:.32em;text-transform:uppercase;color:rgba(233,236,238,.55);margin-bottom:10px}
.f__input,.f__select,.f__area{width:100%;background:transparent;border:none;border-bottom:1px solid rgba(233,236,238,.22);color:var(--porcelain);font-family:var(--serif);font-weight:500;font-size:17px;padding:8px 0 12px;outline:none;transition:border-color .4s;border-radius:0}
.f__select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--steel) 50%),linear-gradient(135deg,var(--steel) 50%,transparent 50%);background-position:calc(100% - 14px) 55%,calc(100% - 9px) 55%;background-size:5px 5px;background-repeat:no-repeat;cursor:pointer}
.f__select option{background:var(--coal);color:var(--porcelain)}
.f__area{min-height:74px;resize:vertical}
.f__input:focus,.f__select:focus,.f__area:focus{border-color:var(--teal)}
.fchips{display:flex;gap:10px;flex-wrap:wrap}
.fchip{position:relative}
.fchip input{position:absolute;opacity:0;pointer-events:none}
.fchip span{display:inline-block;padding:10px 18px;border:1px solid rgba(233,236,238,.22);border-radius:100px;font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.22em;text-transform:uppercase;color:rgba(233,236,238,.7);cursor:pointer;transition:border-color .35s,color .35s,background .35s}
.fchip input:checked + span{border-color:var(--teal);color:#fff;background:rgba(43,197,196,.08)}
.f__submit{margin-top:8px;width:100%}
.f__note{margin-top:14px;font-family:var(--sans);font-size:9px;font-weight:400;letter-spacing:.22em;text-transform:uppercase;color:rgba(233,236,238,.55);text-align:center}
.form.sent .f__hide{opacity:.25;pointer-events:none}
.f__done{display:none;margin-top:6px;text-align:center}
.form.sent .f__done{display:block}
.f__done .t{font-family:var(--serif);font-style:italic;font-weight:500;font-size:22px}
.f__done .u{width:70px;height:1px;margin:14px auto 0;background:linear-gradient(90deg,var(--teal-deep),var(--teal),var(--teal-ice))}
@media (max-width:900px){.begin__grid{grid-template-columns:1fr}}

/* S3b · the house — kinetic team (ported from 21st.dev kinetic-team-hybrid, SÉRA skin) */
.house{position:relative;background:var(--ivory);color:#141518;padding:clamp(100px,13vw,170px) var(--gutter);overflow:hidden}
.house .ghostword{right:-3%;bottom:-4%;font-size:clamp(150px,20vw,340px)}
.house__inner{position:relative;z-index:2;max-width:1360px;margin:0 auto}
.house__head{display:flex;justify-content:space-between;align-items:flex-end;gap:30px;margin-bottom:clamp(20px,3vw,40px)}
.house__title{font-family:var(--serif);font-weight:500;font-size:clamp(30px,3.8vw,58px);line-height:1;letter-spacing:-.01em;text-transform:uppercase;margin-top:22px}
.house__title em{font-style:italic}
.house__label{display:flex;align-items:center;gap:14px;font-family:var(--sans);font-size:9.5px;font-weight:400;letter-spacing:.34em;text-transform:uppercase;color:rgba(16,17,20,.45);white-space:nowrap}
.house__label::before{content:"";width:56px;height:1px;background:rgba(16,17,20,.3)}
.house__story{max-width:66ch;color:rgba(16,17,20,.72);margin-bottom:clamp(40px,5vw,70px)}
.house__story p{margin-top:14px}
.house__story .rule{font-family:var(--serif);font-style:italic;font-weight:500;color:#141518}
.trow{border-top:1px solid var(--hairline-dark)}
.trow:last-of-type{border-bottom:1px solid var(--hairline-dark)}
.trow__btn{width:100%;display:grid;grid-template-columns:auto 1fr auto auto;align-items:center;gap:clamp(18px,3vw,44px);background:none;border:none;cursor:pointer;text-align:left;padding:0;min-height:clamp(96px,11vw,150px);color:inherit;font:inherit}
.trow__btn:focus-visible{outline:2px solid var(--teal-deep);outline-offset:4px}
.trow__group{display:flex;align-items:baseline;gap:clamp(18px,2.6vw,40px);transition:transform .5s cubic-bezier(.22,1,.36,1)}
.trow__idx{font-family:var(--serif);font-style:italic;font-weight:500;font-size:14px;color:var(--teal-deep);opacity:.9;min-width:30px}
.trow__name{font-family:var(--serif);font-weight:500;font-size:clamp(28px,4.4vw,62px);line-height:1;letter-spacing:.01em;color:#8d877c;transition:color .5s cubic-bezier(.22,1,.36,1)}
.trow__role{font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.22em;text-transform:uppercase;color:rgba(16,17,20,.42);transition:color .5s;justify-self:end;white-space:nowrap}
.trow__arrow{width:22px;height:22px;opacity:0;transform:translateX(-10px);transition:opacity .5s cubic-bezier(.22,1,.36,1),transform .5s cubic-bezier(.22,1,.36,1)}
.trow__arrow path{stroke:#141518;stroke-width:1.5;fill:none}
.trow__plus{display:none;font-family:var(--serif);font-weight:500;font-size:24px;line-height:1;color:rgba(16,17,20,.55);transition:transform .4s cubic-bezier(.22,1,.36,1)}
@media (hover:hover) and (min-width:768px){
  .trow:hover .trow__group{transform:translateX(16px)}
  .trow:hover .trow__name{color:#141518}
  .trow:hover .trow__role{color:rgba(16,17,20,.75)}
  .trow:hover .trow__arrow{opacity:1;transform:none}
}
.trow__panel{display:none}
/* cursor-following portrait (desktop) */
#tcard{position:fixed;left:0;top:0;z-index:800;width:300px;pointer-events:none;opacity:0;background:#fff;padding:10px 10px 0;border:1px solid rgba(16,17,20,.14);box-shadow:0 40px 80px -30px rgba(16,17,20,.5);will-change:transform,opacity,filter;transform-origin:50% 50%}
#tcard .ph{aspect-ratio:4/5;overflow:hidden;background:var(--coal)}
#tcard img{width:100%;height:100%;object-fit:cover}
#tcard .cap{padding:11px 4px 12px;text-align:center;font-family:var(--serif);font-style:italic;font-weight:500;font-size:15px;color:#141518;background:#fff}
#tcard.on{opacity:1}
#tcard .fx{transition:opacity .22s cubic-bezier(.22,1,.36,1)}
@media (hover:none),(max-width:767px){
  #tcard{display:none}
  .trow__arrow{display:none}
  .trow__plus{display:block}
  .trow.open .trow__plus{transform:rotate(45deg)}
  .trow__btn{grid-template-columns:auto 1fr auto;min-height:84px}
  .trow__role{display:none}
  .trow__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .56s cubic-bezier(.22,1,.36,1)}
  .trow.open .trow__panel{grid-template-rows:1fr}
  .trow__panelIn{overflow:hidden}
  .trow__fig{margin:6px 0 26px;width:min(78vw,340px);background:#fff;padding:8px 8px 0;border:1px solid rgba(16,17,20,.14);box-shadow:0 24px 50px -24px rgba(16,17,20,.4);opacity:0;transform:translateY(10px);transition:opacity .5s .1s,transform .5s .1s}
  .trow.open .trow__fig{opacity:1;transform:none}
  .trow__fig .ph{aspect-ratio:4/5;overflow:hidden}
  .trow__fig img{width:100%;height:100%;object-fit:cover}
  .trow__fig figcaption{padding:10px 4px 11px;text-align:center;font-family:var(--serif);font-style:italic;font-weight:500;font-size:14px;color:#141518;background:#fff}
  .trow__figrole{display:block;font-family:var(--sans);font-style:normal;font-size:9px;font-weight:400;letter-spacing:.24em;text-transform:uppercase;color:rgba(16,17,20,.5);margin-top:4px}
}
@media (prefers-reduced-motion:reduce){
  .trow__group,.trow__name,.trow__arrow,.trow__plus,.trow__panel,.trow__fig{transition:none}
}

/* ============ THE FOOTER ============
   Variant A of the approved prototype. Every value and proportion below is
   the prototype's; only the selectors are namespaced, because .col, .cta,
   .mark and .rule were free in a standalone document and are not free here.

   It replaces base.css's older .footer wholesale, so the four INHERITED
   properties that rule sets — font-size, letter-spacing, text-transform,
   colour — are reset explicitly. Without that the Cormorant statement and
   the sentence-case links inherit 9.5px uppercase steel and the whole
   column reads as legal small print.

   Obsidian ground on every page, ivory ones included: the site ends on
   black whatever precedes it. */
.footer{position:relative;z-index:2;background:var(--obsidian);overflow:hidden;
  margin-top:0;border-top:0;display:block;padding:clamp(56px,7vw,96px) var(--gutter) 0;
  font-family:var(--sans);font-size:1rem;letter-spacing:normal;text-transform:none;color:var(--porcelain)}
/* the bloom: teal-deep core, teal mid, teal-ice breath. No new colours. */
.footer::before{content:"";position:absolute;left:50%;bottom:-34%;width:min(1500px,150vw);aspect-ratio:1/.62;transform:translateX(-50%);pointer-events:none;background:radial-gradient(ellipse at 50% 100%,rgba(21,127,130,.30) 0%,rgba(21,127,130,.13) 34%,rgba(43,197,196,.05) 56%,transparent 76%)}
.footer::after{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at 50% 118%,rgba(143,244,239,.07),transparent 55%)}
/* must stay ABOVE .footer__film: equal specificity, and the film has to win */
.footer>*{position:relative;z-index:2}

/* The film. The prototype's numbers, restored exactly — founder direction,
   27 Jul: the wave has to flow from edge to edge, the way the first preview
   did, and not pool in the lower centre.

   The width is the whole mechanism, and it is easy to misread. At 190vw the
   film box is far wider than the window, so the mask's horizontal falloff
   (42% -> 78% of 190vw = 80vw -> 148vw) lands OFF-SCREEN. What dissolves is
   the top and the bottom; left and right are still inside the opaque core,
   so the ribbon enters at one edge and leaves at the other. Give the ellipse
   explicit radii and that collapses: `ellipse 40% 96%` turns it into a narrow
   vertical slot and the film becomes a puddle behind the wordmark. No radii —
   the default farthest-corner ellipse is what makes this work.

   aspect-ratio is the single addition to the prototype's rule. It equals the
   delivered film's own 1920x600, so the box is exactly the height the video
   would have given it — geometry unchanged — but it is correct BEFORE
   metadata arrives, so the poster is already the right shape. That poster is
   this element's background rather than the video's poster attribute: a
   <video> drops its poster the moment it has metadata but before it paints,
   which is exactly the black frame that appeared in Voices. */
.footer__film{position:absolute;left:50%;bottom:-4%;width:min(2100px,190vw);aspect-ratio:1920/600;transform:translateX(-50%);z-index:1;mix-blend-mode:screen;opacity:.42;filter:saturate(.9);pointer-events:none;background:url(../../home-v4-assets/sera-footer-wave-poster.jpg) center/100% 100% no-repeat;-webkit-mask-image:radial-gradient(ellipse at 50% 72%,#000 0%,#000 42%,transparent 78%);mask-image:radial-gradient(ellipse at 50% 72%,#000 0%,#000 42%,transparent 78%)}
.footer__film video{width:100%;height:100%;display:block;object-fit:cover}

.footer__cols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:clamp(24px,4vw,64px);padding-bottom:clamp(40px,5vw,64px);border-bottom:1px solid var(--hairline)}
.footer__h{font:500 11px var(--sans);letter-spacing:.24em;text-transform:uppercase;color:rgba(233,236,238,.55);margin-bottom:20px}
/* the address and the hours share the links' type but are not links */
.footer__col a,.footer__line{display:block;font-family:var(--sans);font-weight:400;font-size:13px;line-height:2.25;letter-spacing:normal;text-transform:none;color:rgba(233,236,238,.72);text-decoration:none}
.footer__col a{transition:color .45s}
.footer__col a:hover{color:var(--ivory)}
/* the statement and the CTA are one unit — centred on each other, not ranged
   left against a pill that is wider than the text above it */
.footer__col--say{text-align:center}
.footer__say{font-family:"Cormorant Garamond",Georgia,serif;font-style:italic;font-size:clamp(16px,1.5vw,20px);line-height:1.55;letter-spacing:normal;text-transform:none;color:rgba(233,236,238,.5);max-width:24ch;margin:0 auto 22px}
.footer__col a.footer__cta{display:inline-block;margin-top:6px;font:500 10px var(--sans);letter-spacing:.22em;text-transform:uppercase;color:var(--obsidian);background:var(--ivory);padding:13px 24px;border-radius:999px;text-decoration:none}

/* the whole word, uncropped, nothing inside the letterforms */
.footer__mark{margin-top:clamp(34px,4.5vw,58px);display:flex;justify-content:center}
.footer__mark svg{width:100%;height:auto;display:block}
.footer__mark text{font-family:var(--didone);font-weight:500;letter-spacing:.045em;fill:var(--ivory)}

/* GRID, NOT space-between, BECAUSE THE MIDDLE ITEM HAS TO BE CENTRED IN THE
   ROW. With three flex items, space-between centres the middle one between its
   NEIGHBOURS — and "© SÉRA — a concept clinic" and "Designed and built by Kyren
   Tech" are not the same width, so LEGAL & IP would have sat off-centre by half
   the difference. `1fr auto 1fr` gives the centre cell the row's true middle
   whatever the two ends measure. */
.footer__rule{margin-top:clamp(18px,2.4vw,30px);display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:16px;padding:20px 0 clamp(22px,3vw,34px);border-top:1px solid rgba(233,236,238,.07)}
.footer__rule > :nth-child(1){justify-self:start}
.footer__rule > :nth-child(2){justify-self:center}
.footer__rule > :nth-child(3){justify-self:end}
/* the row is one value now. It was the prototype's .3 — 2.4:1, sub-AA since it
   shipped and flagged as needing sign-off — and with the address gone the mark
   is the only line in it that is not a link. Lifted to the .72 the credit and
   the two links already carry: one row, one weight, 8.74:1. */
.footer__rule span{font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.2em;text-transform:uppercase;color:rgba(233,236,238,.72)}
/* The legal line is the prototype's rgba(233,236,238,.3) — 1.9–2.3:1, sub-AA
   since it shipped, and left alone because the value needs sign-off. A LINK is
   a different matter: it has to be seen to be used. Lifted, and underlined, so
   only the one reachable thing in the row changes. */
.footer__rule a{color:rgba(233,236,238,.72);border-bottom:1px solid rgba(233,236,238,.3);padding-bottom:2px;transition:color .45s,border-color .45s}
.footer__rule a:hover{color:var(--ivory);border-bottom-color:rgba(233,236,238,.6)}
/* `.footer__rule .footer__credit{color:…}` lived here to lift the credit out of
   the row's .3. The whole row is .72 now, so it did nothing, and a rule that
   cannot change anything is the next thing someone fights. Removed with the
   value it was overriding. `.footer__credit` survives in the markup as the name
   of the sentence — the harness reads it to tell the credit from the links. */

/* §2.4 — the statement-and-CTA column leads the footer on desktop, where it sits
   beside the link columns. Stacked, it lands immediately under whatever closing
   CTA the page already ends on — two identical ivory pills back to back, which
   reads as a bug rather than an invitation. Send it to the end of the stack:
   both doors survive, the three link columns separate them, and the invitation
   closes the footer just above the wordmark, which is where it wants to be. */
@media (max-width:860px){
  .footer__cols{grid-template-columns:1fr 1fr;gap:36px}
  /* Measured, the closing block read 9px of air above the statement, 28px to
     the CTA and ZERO below it — so the pill butted straight into the mark and
     the statement was crammed against its own hairline. It is one unit and
     wants to sit in the middle of its band: equal air top and bottom, and a
     gap to the CTA large enough that the button reads as an action rather
     than a third line of the sentence. */
  /* CENTRED BETWEEN ITS TWO HAIRLINES, not merely inside its own box.
     Balancing the column's own padding gave 31 above / 32 below and still read
     lopsided, because the gap the eye measures runs rule-to-rule: the line
     below is `.footer__cols`' bottom border, and 41px of that container's own
     padding sat under the column — so the real figures were 31 and 71.
     The column's bottom padding is therefore ZERO and its top padding is
     raised to match the 41 the container already contributes. Balanced by
     making the two numbers equal rather than by pulling anything with a
     negative margin. (`.footer__mark`'s margin was the wrong lever — it sits
     BELOW that rule, so zeroing it only cramped the wordmark.) */
  .footer__col--say{order:9;grid-column:1/-1;padding-top:40px;padding-bottom:0;
                    border-top:1px solid var(--hairline)}
  .footer__col--say .footer__say{margin-bottom:26px}
  .footer__col--say a.footer__cta{margin-top:0}
}
@media (max-width:560px){.footer__cols{grid-template-columns:1fr}}
/* §2.3 — more air under the wordmark before the legal line at phone widths */
/* Three cells side by side need about 490px of type; a phone has 350. Below
   that the row becomes one column and all three range left, which is what the
   old flex-wrap produced anyway — the difference is that it is now a decision
   rather than whatever the wrap happened to do. */
@media (max-width:860px){
  .footer__rule{grid-template-columns:1fr;gap:11px;justify-items:start}
  .footer__rule > :nth-child(1),
  .footer__rule > :nth-child(2),
  .footer__rule > :nth-child(3){justify-self:start}
}
@media (max-width:767px){.footer__rule{margin-top:clamp(26px,7vw,36px)}}
/* belt and braces — the runtime removes the element, this covers the gap */
@media (prefers-reduced-motion:reduce){.footer__film video{display:none}}

/*@sera:cursor-css*/
/* SÉRA cursor — merged port of 21st.dev magnetic-cursor + cursor-follow, reskinned */
.has-cur,.has-cur a,.has-cur button,.has-cur .mcard,.has-cur .card,.has-cur .qa__btn{cursor:none}
.has-cur input,.has-cur textarea,.has-cur select{cursor:auto}
#cur{position:fixed;top:0;left:0;width:10px;height:10px;border-radius:50%;background:var(--porcelain);mix-blend-mode:exclusion;z-index:9999;pointer-events:none;opacity:0;will-change:transform}
#cur.ring{background:var(--porcelain)}
.has-cur [data-magnetic]:hover{border-color:transparent}
.has-cur [data-magnetic]:hover::after{border-color:transparent}
#curLabel{position:fixed;top:0;left:0;z-index:9999;pointer-events:none;opacity:0;background:rgba(10,11,13,.93);border:1px solid rgba(233,236,238,.16);color:var(--word);font-family:var(--serif);font-style:italic;font-weight:500;font-size:14px;padding:8px 15px;border-radius:100px;white-space:nowrap;transform-origin:0 0}
/*@sera:end cursor-css*/

/* `.js`, for the reason the person from-state below is gated: a from-state in
   the stylesheet hides content that only a script can reveal, and the founder's
   portrait on /house is one of the images that has always been in this set.
   Measured with scripting off before the gate: five elements on /house stayed
   at opacity 0, permanently. (0,2,0), so `.rv.on` below still wins on order.
   Home cannot be helped this way — it mounts its DOM from <template> — but the
   four static pages now read plainly without a line of JavaScript. */
.js .rv{opacity:0;transform:translateY(26px);filter:blur(6px)}
.rv.on{opacity:1;transform:none;filter:none;transition:opacity 1.05s cubic-bezier(.2,.6,.2,1),transform 1.05s cubic-bezier(.2,.6,.2,1),filter 1.05s cubic-bezier(.2,.6,.2,1)}
/* THE PERSON ENTRANCE'S FROM-STATE, AND WHY IT IS HERE AND NOT IN THE TWEEN.

   `.rv` above has always had its from-state in the stylesheet, so an element
   carrying it is at opacity 0 from parse and can never be seen before it is
   hidden. The person sections deliberately do NOT use `.rv` — a section at the
   top of the viewport is already past the reveal trigger — and their entrance
   was a bare gsap.fromTo(). That left a window: a portrait becomes visible at
   the BOTTOM EDGE of the viewport before it crosses `top 82%`, the browser
   paints it sharp, and the trigger callback then applies the from-state to
   something already on screen. Captured at 60fps on an iPhone: painted for
   ~8 frames, blank for ~120ms, then blurred, then sharp. Decode was never the
   variable — an image that has painted sharp has already decoded — which is
   why no amount of CPU throttling could reproduce it.

   So the from-state is authored here, matching the tween's exactly, and
   JavaScript only ever REMOVES it: playNow() adds `.shown` before the tween is
   built, in the same tick, so there is no paint between the two.

   Written for the whole class rather than the two portraits that showed it —
   the Doctrine's parts are listed too even though `.rv` already covers them.
   Gated on `.js` so scripting-off leaves every one of them plainly visible. */
.js .person:not(.shown) .person__frame,
.js .person:not(.shown) .person__name,
.js .person:not(.shown) .person__role,
.js .person:not(.shown) .person__copy p,
.js .doctrine:not(.shown) .doctrine__frame,
.js .doctrine:not(.shown) .doctrine__credit,
.js .doctrine:not(.shown) .doctrine__p,
.js .doctrine:not(.shown) .doctrine__pull{opacity:0;transform:translateY(30px);filter:blur(7px)}
/* Reduced motion marks every section shown as soon as sera-house.js runs, but
   `as soon as` is not `from parse` — without this the sections would be hidden
   for exactly the window this rule set exists to close. SAME SPECIFICITY as the
   block above, deliberately: `:not(.shown)` is repeated so the two rules are
   both (0,4,0) and source order decides. Dropping it would make this (0,3,0)
   and it would silently lose — the trap this file has fallen into eight times. */
@media (prefers-reduced-motion:reduce){
  .js .person:not(.shown) .person__frame,
  .js .person:not(.shown) .person__name,
  .js .person:not(.shown) .person__role,
  .js .person:not(.shown) .person__copy p,
  .js .doctrine:not(.shown) .doctrine__frame,
  .js .doctrine:not(.shown) .doctrine__credit,
  .js .doctrine:not(.shown) .doctrine__p,
  .js .doctrine:not(.shown) .doctrine__pull{opacity:1;transform:none;filter:none}
}
@media (prefers-reduced-motion:reduce){
  #menuWrap,#voicesWrap,.plateWrap,#meetingWrap{height:auto}
  .menu,.voices,.plate{position:relative;height:auto}
  /* matched to `.js .rv` above at (0,2,0) — at (0,1,0) it would now lose */
  .js .rv{opacity:1;transform:none;filter:none}
  /* all three quotes at once, statically composed over the photograph */
  .voices{display:block;padding:clamp(90px,12vw,150px) var(--gutter)}
  .voices .eyebrow{position:static;transform:none;margin-bottom:clamp(40px,6vw,70px)}
  .voices__stage{width:100%;height:auto;max-width:900px;margin:0 auto}
  .voice{position:relative;inset:auto;opacity:1;transform:none;margin-bottom:clamp(50px,7vw,84px)}
  .voice:last-child{margin-bottom:0}
  /* the section grows to hold all three, so the picture spans it and never
     drifts — the drift is the one thing reduced motion is here to stop */
  .vroom{position:absolute;top:0;height:100%;transform:none}
}
/* ===== patch v2: ivory disciplines · lumina voices · boot curtain · path dots · eyebrow ===== */
.plates,.plate{background:var(--ivory)}
.plate__media{background:radial-gradient(120% 90% at 50% 45%,#EAE5DB 0%,var(--ivory) 70%)}
.plate__ghost{-webkit-text-stroke:1px rgba(16,17,20,.09)}
.plate__frame{border-color:rgba(16,17,20,.16);background:#fff;box-shadow:0 50px 100px -45px rgba(16,17,20,.45)}
.plate__cap{color:rgba(16,17,20,.42)}
.plate__tick{color:rgba(16,17,20,.4)}
.plate__num{color:var(--teal-deep)}
.plate__name{color:#141518}
.plate__promise{color:rgba(16,17,20,.72)}
.plate__body{color:rgba(16,17,20,.74)}
.plate__list{border-top:1px solid var(--hairline-dark)}
.plate__list div{border-bottom:1px solid var(--hairline-dark);color:rgba(16,17,20,.55)}
.plate__list b{color:rgba(16,17,20,.48)}
.plate__cta a{color:#141518;border-bottom-color:rgba(16,17,20,.4)}
.plate__cta a:hover{border-color:var(--teal-deep);color:#000}
/* ONE LINE, ONE VALUE. "Private aesthetic medicine" sat at .66 against
   "Jumeirah" at .92, which read as dull rather than as a hierarchy — the two
   halves are one sentence and there was never a reason for the first to be
   quieter. Both at .92 now.
   The DOT stays a step above at full ivory, deliberately: the whole point of
   making it a drawn circle was that it be brighter than the letterforms either
   side, so it reads as a mark and not as a rendering artefact. */
.hero__meta .eyebrow{font-size:10px;font-weight:400;letter-spacing:.34em;color:rgba(233,236,238,.92)}
/* `.loc` no longer sets a colour — it would be declaring the value it already
   inherits, and a rule that cannot change anything is the next thing someone
   fights. The inherit resets stay; they are what keep the span from picking up
   anything of its own. */
.hero__meta .eyebrow .loc{font:inherit;letter-spacing:inherit;text-transform:inherit}
/* A TRUE ROUND DOT, NOT A MIDDOT — founder direction. A middot is a glyph: its
   shape, weight and vertical position belong to the typeface, and at 10px it
   rendered as a faint smear. This is a drawn circle, so it is round by
   construction and its size and position are ours.

   Sized and placed in `em`, so it tracks the eyebrow's own type at every
   breakpoint. .34em is a little over twice the middot's ink and still reads as
   punctuation rather than a bullet. Optically centred on the CAP HEIGHT, not
   on the x-height or the em box: Manrope's caps run about .72em above the
   baseline, so the centre wants to sit at .36em and the box bottom therefore at
   .36 - .17 = .19em.

   BRIGHTER THAN THE LETTERFORMS EITHER SIDE, which is the whole point of the
   change — the type runs porcelain at .66 and .92, so a dot at the same value
   would read as a fat middot. Full ivory is the brightest thing in the eyebrow
   and it is already in the palette. */
.hero__meta .eyebrow .loc::before{content:"";display:inline-block;vertical-align:.19em;
  width:.34em;height:.34em;border-radius:50%;background:var(--ivory);margin:0 .8em}
.step__dot{background:transparent;border:1px solid var(--teal-deep);opacity:.65;box-shadow:none;transition:background .45s,box-shadow .45s,opacity .45s}
.step__dot.lit{background:var(--teal);opacity:1;box-shadow:0 0 10px rgba(43,197,196,.55)}
/* THE ROOM, FULL BLEED. No frame, no inset, no radius, no border.
   104% tall and parked at -2% so the drift has somewhere to go: a cover crop
   of these masters has no vertical slack of its own — 9:19.5 and 16:10 both
   crop the WIDTH — so the only way to move the picture vertically is to give
   it height.

   THE OVERHANG AND THE TRAVEL ARE IN DIFFERENT UNITS, and getting that wrong
   is what opened a gap the first time: `top` is a percentage of the SECTION,
   but a translate in % is a percentage of the ELEMENT — and the element is
   taller than the section. At 102.8%/-1.4% a ±1.4% translate came to 1.439% of
   the section against a 1.4% overhang and uncovered 0.34px at 848, measured.
   Here 2% of overhang absorbs 1.5% x 1.04 = 1.56%, leaving 0.44% in hand. */
/* RIGHT-FLUSH AT EVERY BREAKPOINT, not only on phones. Everything that matters
   in both masters — chair, lamp, side table, notebook — sits on the right, and
   the left is expendable dark wall. Centring spends half of whatever a window
   crops on the side with the subject in it, which is what took the table's
   outer edge on a MacBook 14" and at 4:3. One rule, no breakpoint. */
.vroom{position:absolute;left:0;top:-2%;width:100%;height:104%;z-index:1;
  object-fit:cover;object-position:right center;will-change:transform;pointer-events:none;
  -webkit-user-select:none;user-select:none}
/* NO VEIL, NO SCRIM, NO GRADIENT, NO FEATHER anywhere in this section. The
   masters are around half true black with a median luminance under 5 and
   porcelain reads on them unaided; a veil would flatten the one thing that
   makes them work. `.vveil` and the `.voices::after` radial pass are deleted,
   not disabled — a rule kept "just in case" is the next thing to fight. */
.voices .eyebrow{z-index:5;color:rgba(233,236,238,.62)}
.voices__stage{z-index:4}
/* the only dark chapter that was missing one. Same treatment, same depth
   relationship: behind the type, in front of the film. */
.voices .ghostword{left:-1%;bottom:4%;font-size:clamp(150px,20vw,330px);z-index:3}
/* EVERY responsive rule for Voices lives here, and nowhere else. It used to be
   split across two @media blocks 190 lines apart, and the later one won every
   collision in silence — two measured veil passes read as if they had never
   been applied. One home, below every desktop rule it overrides. */
/* A NARROW WINDOW THAT IS STILL WIDER THAN IT IS TALL — a phone on its side,
   effectively. It keeps the landscape master and the ranged-left composition,
   just at a smaller measure. The `min-aspect-ratio` half is what makes this
   tier and the portrait tier below MUTUALLY EXCLUSIVE rather than two blocks
   overriding each other in source order; a collision here is exactly the bug
   this file has been caught leaving three times. */
@media (max-width:900px) and (min-aspect-ratio:1/1){
  .voices{padding-left:var(--gutter)}
  .voices__stage{width:min(560px,72vw);height:52svh}
  .voice .q{font-size:clamp(24px,6.4vw,40px)}
  /* THE THREE VEIL TIERS ARE GONE — all of them, not softened. They existed to
     hold porcelain above 5:1 over a moving band of lit skin. The room is a
     still photograph that is already near-black where the type sits, so a veil
     would only take the picture's own depth away. */
}
/* ANY WINDOW TALLER THAN IT IS WIDE GETS THE TALL COMPOSITION — phones and
   portrait tablets alike. Founder ruling: a tall screen wants the tall
   composition, and this threshold is the SAME 1:1 the <source> uses, so the
   file's shape and the layout's shape can never disagree.

   A 9:19.5 phone covers the 9:16 master by filling the HEIGHT and gives up 18%
   of its width — spent entirely on the left by `right center`. A 3:4 tablet
   does the opposite: it fills the WIDTH and gives up 25% of the HEIGHT, half
   off the top. So the phone's percentages do not transfer, and the quote band
   was re-measured at each shape rather than assumed (see _r11tier.js):

     390x848   9:19.5   top 45% of the visible frame reads luma 0
     768x1024  3:4      the top 12.5% of the master is cut; the quote band
                        still lands on the wall, measured 0-2
     820x1180  ~9:13    cut 6.6%; band reads 0
     1024x1366 3:4      as 768x1024

   The band is expressed in `svh` so it follows the viewport rather than the
   picture, and it clears the lamp at every one of them. */
@media (max-aspect-ratio:1/1){   /* the <source> threshold, exactly */
  /* THE QUOTE GOES IN THE UPPER THIRD, over the wall, well above the lamp.
     Centred here, unlike desktop — a tall frame has no void to range against,
     only the wall. */
  .voices{padding-left:0;display:block}
  .voices .eyebrow{top:7svh;left:50%;transform:translateX(-50%)}
  .voices__stage{position:absolute;left:50%;transform:translateX(-50%);
    top:14svh;width:86vw;height:26svh;text-align:center;overflow:hidden}
  .voice .q{font-size:clamp(26px,7vw,40px)}
  .voice .a{color:rgba(233,236,238,.62)}
}
/* a tall window with room to spare — a tablet, not a phone. The quote can hold
   a wider measure without the lines going short, and the band has more air. */
@media (max-aspect-ratio:1/1) and (min-width:768px){
  .voices__stage{top:16svh;width:min(680px,74vw);height:24svh}
  .voice .q{font-size:clamp(32px,4.4vw,46px)}
}
#boot{position:fixed;inset:0;z-index:2000;pointer-events:none}
.boot__panel{position:absolute;left:0;right:0;height:50.5%;background:var(--obsidian)}
.boot__panel--t{top:0}.boot__panel--b{bottom:0}
.boot__center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px}
.boot__word{font-family:var(--serif);font-weight:500;font-size:clamp(30px,4.4vw,54px);letter-spacing:.5em;text-indent:.5em;color:var(--word);overflow:hidden}
.boot__word i{display:block;font-style:normal;transform:translateY(115%)}
.boot__line{width:min(320px,56vw);height:1px;background:linear-gradient(90deg,transparent,var(--teal-deep) 20%,var(--teal) 50%,var(--teal-deep) 80%,transparent);transform:scaleX(0)}
.boot__drop{width:15px;opacity:0}
.boot__drop img{width:100%;height:auto}
/* guard — live hero keeps its own eyebrow hairline; feature 4 adds only the serif locality */
.hero__meta .eyebrow{display:inline-block}
.hero__meta .eyebrow::before{content:none}
/* --- Display face: Playfair Display (Didone) everywhere EXCEPT the hero. ---
   Done by re-pointing --serif on <body>; #heroWrap re-asserts Cormorant, so the
   PRESENCE wordmark, hero caption and eyebrow are byte-for-byte unchanged. --- */
:root{--didone:"Playfair Display","Cormorant Garamond",Georgia,serif}
body{--serif:var(--didone)}
#heroWrap{--serif:"Cormorant Garamond",Georgia,serif}

/* Playfair carries more weight and a larger x-height than Cormorant at the same
   size, so the display sizes come down a touch and the leading tightens. */
.menu__title,.doctrine__title,.meeting__title,.meet2__title,.path__title,.house__title,.begin__title,.faq__title,.voices__title{
  font-weight:500;letter-spacing:-.014em;
}
.begin__title{font-size:clamp(40px,5.6vw,96px);line-height:.9}
.menu__title{font-size:clamp(28px,3.7vw,56px);line-height:.94}
.doctrine__title,.meeting__title{font-size:clamp(28px,3.1vw,49px);line-height:1.02;letter-spacing:0}
.path__title,.house__title{font-size:clamp(28px,3.4vw,52px);line-height:1}
.plate__name{letter-spacing:-.012em}
/* body copy: a little more air, closer to the reference's comfortable measure */
.prose{font-size:clamp(16px,1.28vw,18.5px);line-height:1.78}

/* ============================================================
   THE FOUR ITALIC LINES — and only these four.
   Playfair keeps every roman role it holds; Manrope and Cormorant keep theirs.

   Bodoni Moda is loaded with its optical-size axis (opsz 6..96) in the SAME
   Google Fonts request as Playfair, so font-optical-sizing:auto draws the
   ~110px closing line and the ~30px Meeting line each at their proper optical
   size rather than scaling one drawing. Verified live: opsz 6 vs 96 measure
   557.23px vs 554.28px on the same string, so the axis is real, not decorative.

   Cormorant is asked for at WEIGHT 500 in Voices and that is not optional:
   fonts.css carries Cormorant italic at 500 only, and the quotes are light type
   over a dark MOVING film where its thin strokes disappear. `Three hands.` is
   dark type on ivory, where thin serifs hold, so it stays at 400.
============================================================ */
:root{--bodoni:"Bodoni Moda",Georgia,serif;--corm:"Cormorant Garamond",Georgia,serif;
      --instr:"Instrument Serif",Georgia,serif}

/* 1 · The House — "Three hands." */
.house__title em{font-family:var(--corm);font-style:italic;font-weight:500}

/* 2 · the closing invitation — "as you are."  The same sentence closes
   /consultation, so it takes the same face; one line in two places must not be
   set in two faces. */
/* text-transform:none belongs on BOTH. The parents are uppercase, and only the
   home rule carried the reset — so /consultation was shouting AS YOU ARE. in
   caps while home said it quietly in lowercase. The same sentence cannot be set
   two ways, and the lowercase is the one that reads like the Doctrine's pull
   quote: an aside, not an instruction. */
.invite__title em,.begin__title em{font-family:var(--instr);font-style:italic;font-weight:400;text-transform:none;line-height:.98}

/* 3 · The Meeting — "Your plan, before your decision." */
.meeting__sub{font-family:var(--corm);font-style:italic;font-weight:500}

/* 4 · Voices — the three client quotes */
.voice .q{font-family:var(--corm);font-style:italic;font-weight:500}

/* 5 · The Disciplines headline — "One measured approach." */
.menu__title em{font-family:var(--corm);font-style:italic;font-weight:500}

/* Bodoni now dresses exactly THREE glyphs — the i/ii/iii in The Standard.
   That is a whole family for three numerals; if they ever move to Cormorant or
   Instrument, drop Bodoni from the font request with them. */

/* --- Ghostwords: filled instead of hollow. A vertical gradient fill gives the
   watermark real presence and a soft fade, with a hairline edge to keep the
   letterforms defined. Still background — it never competes with the headline. --- */
.ghostword{
  background:linear-gradient(175deg,rgba(233,236,238,.15) 0%,rgba(233,236,238,.075) 55%,rgba(233,236,238,.03) 100%);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;
  -webkit-text-stroke:0;
}
.ghostword--dark{
  background:linear-gradient(175deg,rgba(16,17,20,.16) 0%,rgba(16,17,20,.08) 55%,rgba(16,17,20,.032) 100%);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;
  -webkit-text-stroke:0;
}
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .ghostword{color:rgba(233,236,238,.07);background:none}
  .ghostword--dark{color:rgba(16,17,20,.08);background:none}
}
/* THE WATERMARKS ON MOBILE — scaled to fit, not hidden (founder, 28 Jul).
   At desktop widths the word bleeds past its section edge on purpose: too large
   for the room is the whole idea, and that is unchanged. At phone widths the
   same bleed ate the word — HOUSE read as OUSE, VOICES lost its tail, STANDARD
   ran 228px past the frame. Hiding them fixed the clipping and removed a whole
   layer of the design with it, which is the wrong trade.

   Below 900 the watermark is centred, held inside the gutters, and sized so the
   COMPLETE word fits. The size is per section because the words are not the
   same length — Q&A is three characters and STANDARD is eight, so one shared
   size would either shrink Q&A to nothing or push STANDARD off the frame. Each
   value below is measured, not guessed (htest/ghost.js).

   This is CSS only, deliberately. An auto-fit in JS would be tidier and would
   survive a copy change, but §1 makes scroll smoothness the priority and these
   are seven static words — a layout read per section per page is a cost with
   nothing to show for it. If the copy ever changes, re-measure. */
@media (max-width:900px){
  /* Every declaration is section-scoped at (0,2,0), matching the desktop rules
     it has to override. Written once at (0,1,0) it lost `left` to
     `.voices .ghostword{left:-1%}` and friends and centred nothing — the same
     specificity trap as .eyebrow--light, .nav__menuCta and .person--close, and
     I walked straight into it. Match the specificity; let source order decide. */
  .ghostword{white-space:nowrap;max-width:none;text-align:center;transform:translateX(-50%)}
  /* THE MARGIN IS THE POINT, not merely "not clipped". The first pass sized
     each word to fit and stopped there, which left them at 72-85% of the frame
     — inconsistent between sections, and tight enough that VOICES read as
     touching both edges. They are one system now: every watermark sits at
     roughly 66% of the viewport, so the margin is visible and equal on both
     sides and the seven of them recede together instead of each being its own
     guess. Desktop bleed is untouched. */
  /* STANDARD BELONGS TO THE STANDARD. At bottom:2% it sat 14px above the first
     dark discipline plate, so it read as that section's title rather than this
     one's watermark. Moved to the top, offset from the real nav height rather
     than a percentage — a percentage of a 716px section puts it under the nav,
     which is exactly how the SERA watermark below got clipped. */
  /* EVERY VERTICAL POSITION BELOW IS A MEASURED TEXT-FREE BAND, NOT A GUESS.
     Three rounds of moving these by eye each traded one collision for another,
     because "looks right" was judged from a single screenshot at a single
     scroll position. `_wm.js` collapses all type in a section into merged
     spans, reports the gaps, and then asserts the word covers <=8% of any text
     box at 360/390/414. Where a section had no gap big enough, the section was
     given one — which is what the founder asked for on The Standard. */
  .standard .ghostword {left:50%;right:auto;font-size:12.7vw;top:calc(var(--navH) + 16px);bottom:auto}
  .standard            {padding-top:150px;padding-bottom:40px}  /* word ends y130 */
  /* DOWN INTO THE DARK TAIL, not re-coloured. At bottom:5% the word occupied
     86.6–95.0% of the frame, which on the room photograph is the lit floor —
     the brightest band in the whole picture (luma to 113 there, peaking 189 a
     little higher). A 4.5% porcelain wash over that reads as a smudge, and
     re-deriving its colour for one section would break a system of seven.
     At bottom:0 it occupies 91.5–100%, where the floor has fallen away again:
     luma 28 / 17 / 5 / 0 down the band, mean ~5 — DARKER than --obsidian's 11,
     so the treatment it was derived against still holds. */
  .voices .ghostword   {left:50%;right:auto;font-size:18.5vw;bottom:0;top:auto}
  /* BESIDE THE OPENING LINE, not adrift below the copy — founder direction.
     Parked at the section foot these two sat under a large dead gap; aligned
     with the eyebrow they read as the chapter mark they are. Right-ranged, so
     they occupy the empty half of the heading rows rather than the centre,
     and  is reset because the shared mobile rule centres by
     translateX(-50%). */
  /* ABOVE the eyebrow at top right, not beside it — founder direction. The
     section opens with the mark, then the label, then the heading. That needs
     the eyebrow pushed down (padding-top 100 -> 140), and the bottom padding
     comes off in the same move: with the word no longer parked at the foot,
     the space it needed there was the gap the founder saw before the next
     portrait. */
  .house               {padding-top:124px;padding-bottom:40px}
  /* measured from the INK, not the box: the glyphs carry ~13-20px of leading
     above them, so a box offset that looked tight left a real gap. */
  .house .ghostword    {left:auto;right:4%;font-size:19.6vw;top:27px;bottom:auto;transform:none;text-align:right}
  /* THE BEGIN WATERMARK IS RETIRED — founder direction, mobile AND desktop.
     Its element is gone from index.html and consultation.html, its three rules
     are gone from this file, and the 140px band that existed only to hold it
     below the CTA went with it. Deleting a system means deleting what served
     it: a padding that balances nothing is the counter-force this file has
     been caught leaving behind before. */
  /* SERA was SANDWICHED: the word ran 44-148 with a 64px nav over its top and
     the founder's portrait starting at 96, so only a ~50px band of a 104px
     word was ever visible. `top:3%` is a percentage of a 1467px section, which
     is why it landed under the nav. Anchored to --navH instead, and the
     portrait is pushed clear below it — the founder's own remedy. */
  .doctrine .ghostword {left:50%;right:auto;font-size:26.6vw;top:calc(var(--navH) + 16px);bottom:auto}
  /* `.doctrine--founder{padding-top:clamp(96px,11vw,168px)}` lives ~220 lines
     BELOW this block at equal specificity, so a plain `.doctrine` here loses on
     source order and silently does nothing — the seventh instance of that trap
     in this file. Matched at (0,2,0) so it wins on specificity, not position. */
  .doctrine.doctrine--founder {padding-top:196px}
  /* THE PATH: `top:5%` put the word straight through the eyebrow and headline
     (74%). The section has a genuine 239px gap between the headline block and
     step 01 — the empty stretch you can see above the coil — and the word
     lives there now. Its steps are driven by the coil rather than the reveal
     system, so they sit unlit at rest; measuring by opacity called that whole
     1269px stretch free, which is how a watermark ends up in copy that lights
     up later. Layout, not opacity, decides this. */
  .path .ghostword     {left:50%;right:auto;font-size:25.9vw;top:224px;bottom:auto}
  /* Q&A had NO gap that fits a 117px word — the accordion rows run edge to
     edge. The section is given a closing band rather than the word being
     shrunk out of the system that keeps all seven the same weight. */
  /* the 280px closing band held Q&A at the section foot; with the word up at
     the eyebrow it is dead space, and it is exactly the gap the founder saw. */
  .faq                 {padding-top:170px}
  .faq .ghostword      {left:auto;right:4%;font-size:29.9vw;top:34px;bottom:auto;transform:none;text-align:right}
}

/* --- Meeting: the media column was 56%x92svh (aspect ~0.97) against a 16:9
   photograph, so cover was cropping ~45% of its width. A shorter row brings the
   column closer to the frame and reveals more of the room. --- */
.meeting{min-height:76svh}
@media (max-width:900px){.meeting{min-height:0}}

/* --- Cards: softer radii and layered, restrained shadows --- */
.card{border-radius:14px;overflow:hidden;
  box-shadow:0 28px 60px -30px rgba(16,17,20,.5),0 6px 18px -8px rgba(16,17,20,.18),0 1px 2px rgba(16,17,20,.06)}
.plate__frame{border-radius:20px}
.plate__media{border-radius:12px;overflow:hidden}
#tcard{border-radius:14px;overflow:hidden;
  box-shadow:0 40px 80px -34px rgba(16,17,20,.55),0 8px 20px -10px rgba(16,17,20,.2)}
.sac__card{border-radius:18px}
.sac__thumb{border-radius:12px}

/* ============ /legal — the small print, said out loud ============
   A reading page, so it is built like one: ivory ground (long text on obsidian
   is punishing), one column, a measure capped near 68 characters, and no motion
   of its own — the `.rv`/`.tit` entrance every other page carries and nothing
   more. No film, no image.

   THE NUMERALS ARE THE STANDARDS' NUMERALS, IN CYAN. Same lowercase Roman
   form, same Bodoni Moda italic, same 44px cell and hairline rhythm — because
   on this site that is what a Roman numeral means, and this is a list of
   clauses. The one departure is the colour, which the brief names: the
   Standards set theirs in ink at .38, so `cyan, exactly as the Standards
   section sets them` cannot be literal on both counts. `--teal-deep` is the
   ivory-ground teal the Q&A numerals already use — the ramp as small type,
   which is the one place the palette law allows it. Flagged in the report. */
.legal{background:var(--ivory);color:#101114;padding:clamp(112px,13vw,170px) var(--gutter) clamp(90px,11vw,150px);position:relative}
.legal__inner{max-width:min(68ch,860px);margin:0 auto}
.legal__title{font-family:var(--serif);font-weight:500;font-size:clamp(38px,5.4vw,86px);
  line-height:.94;letter-spacing:-.012em;text-transform:uppercase;margin-top:22px;color:var(--obsidian)}
.legal__title em{font-family:var(--corm);font-style:italic;text-transform:none}
.legal__stamp{margin-top:clamp(26px,3.2vw,38px);font-family:var(--sans);font-size:11px;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:rgba(16,17,20,.62)}
.legal__list{list-style:none;margin-top:clamp(40px,5vw,64px)}
.legal__list li{display:grid;grid-template-columns:44px 1fr;gap:20px;
  padding:clamp(26px,3.2vw,38px) 0;border-bottom:1px solid var(--hairline-dark)}
.legal__list li:first-child{border-top:1px solid var(--hairline-dark)}
.legal__num{font-family:var(--bodoni);font-style:italic;font-weight:400;font-optical-sizing:auto;
  font-size:17px;color:var(--teal-deep);padding-top:3px}
.legal__body h2{font-family:var(--serif);font-weight:500;font-size:clamp(19px,1.9vw,25px);
  letter-spacing:.005em;color:var(--obsidian)}
/* THE MEASURE IS CAPPED ON THE PARAGRAPH, IN THE PARAGRAPH'S OWN FONT.
   `ch` is the advance of "0", which in Manrope is far wider than the average
   lowercase letter — 68ch on the container measured 85 actual characters per
   line, which is the number the brief is about. Set here, where `ch` is 14.5px
   Manrope rather than the 16px body, and tuned against a real count of the
   glyphs on the first line rather than against the unit's name. */
.legal__body p{margin-top:13px;font-family:var(--sans);font-size:14.5px;font-weight:400;
  line-height:1.72;color:rgba(16,17,20,.72);max-width:49ch}
.legal__body a{color:var(--teal-deep);border-bottom:1px solid rgba(21,127,130,.35);
  padding-bottom:1px;transition:border-color .45s}
.legal__body a:hover{border-bottom-color:var(--teal-deep)}
@media (max-width:600px){
  .legal__list li{grid-template-columns:30px 1fr;gap:14px}
  .legal__inner{max-width:none}
}

/* THE FIRST HOUR — what fills the left column of /consultation now that the
   Disciplines deck has gone. Quiet type and nothing else: no cards, no
   thumbnails, no rules, no numerals. It should read as the calmest thing on a
   page whose other half is a form.

   The label reuses the `.begin__stackcap` values the deck's caption had, so the
   column opens at exactly the same weight it did before; the lead lines are the
   site's serif and the sentences under them the body face, at the scale the
   eyebrow and the address block already use. */
.firsthour{margin-top:clamp(30px,4vw,44px);max-width:44ch}
.firsthour__cap{font-family:var(--sans);font-size:10.5px;font-weight:500;letter-spacing:.3em;
  text-transform:uppercase;color:rgba(233,236,238,.55);margin-bottom:clamp(20px,2.6vw,28px)}
.firsthour__item + .firsthour__item{margin-top:clamp(18px,2.2vw,26px)}
.firsthour__lead{font-family:var(--serif);font-weight:500;font-size:clamp(17px,1.5vw,21px);
  line-height:1.25;letter-spacing:-.004em;color:rgba(233,236,238,.9);text-wrap:pretty}
/* .72 is the site's body-copy alpha, set in the type pass — .62 belongs to
   labels. `text-wrap:pretty` because both sentences otherwise ended on a
   two-word widow ("ask." / "say so."), which is loud in a block whose whole
   job is to be quiet. It degrades to a normal wrap where unsupported. */
.firsthour__body{margin-top:5px;font-family:var(--sans);font-size:13.5px;font-weight:400;
  line-height:1.6;color:rgba(233,236,238,.72);text-wrap:pretty}
@media (max-width:900px){.firsthour{margin-top:30px;max-width:none}}

/* ============ CHAPTER I · THE DEALT HAND ============
   The four discipline cards are held as one hand: a shallow, finite fan.
   Four slots, no wrap — the chapter's own headline promises four disciplines,
   so the ends clamp rather than loop. Lives entirely inside the existing
   #menuWrap runway; adds no page height and no new colour.

   Two transforms, deliberately on two elements:
     .card       — the fan pose (slot, arc, tilt, depth), written by the scrub.
     .card__lift — the local hover nudge, CSS only.
   Split so the scroll and the pointer never overwrite one matrix. */
.menu__stage{--fan-ease:cubic-bezier(.16,1,.3,1)}
.card{background:none;box-shadow:none;border-radius:0;overflow:visible}
.card__lift{
  display:block;background:#fff;border-radius:14px;overflow:hidden;
  box-shadow:0 28px 60px -30px rgba(16,17,20,.5),0 6px 18px -8px rgba(16,17,20,.18),0 1px 2px rgba(16,17,20,.06);
  transform:translate3d(var(--hx,0px),var(--hy,0px),0);
  transition:transform .62s var(--fan-ease),box-shadow .62s var(--fan-ease);
  will-change:transform;
}
/* `.is-front` was set by the fan engine, and the fan engine was deleted on
   26 Jul. NOTHING in the codebase has set it since — so `:not(.is-front)`
   matched every card, and the three rules that used to reveal only the front
   card's footer were hiding all four, permanently. That was patched at the time
   with four `opacity:1 !important` overrides further down the file, which is a
   counter-force, not a fix: the dead rules stayed, and the overrides had to
   shout to beat them.
   Both sides removed together. The four cards are peers now — each always names
   itself — so there is nothing left to reveal or to force. */
@media (min-width:768px){
  #menuWrap:not(.flat) .card{outline:none}
  #menuWrap:not(.flat) .card:focus-visible .card__lift{box-shadow:0 0 0 1px #101114,0 28px 60px -30px rgba(16,17,20,.5)}
}
@media (max-width:767px){
}
@media (prefers-reduced-motion:reduce){
  .card__lift{transition:none}
  #menuWrap .card__body,#menuWrap .card__cta{transition:none}
}

/* ============ CHAPTER V · THE SETTLING PARAGRAPH ============
   The site's thinnest chapter carries its statement of intent. The words
   arrive scattered from the right and settle into an ordinary typeset
   paragraph — measure, performed rather than described. They land damped,
   once, and still, the way the bead settles in the hero.

   The pinned runway is 100vh (the brief's ceiling is ~150vh): the whole beat
   is one screen of scroll, and the site never feels endless for it. */
/* 300vh, was 200. The settle is scrubbed across (wrap height - viewport), so
   this doubles the scroll the words take to assemble — slower, and smoother. */
#meetingWrap{position:relative;height:300vh}
#meetingWrap.flat{height:auto}
.meeting{position:sticky;top:0;height:100svh;align-items:center}
#meetingWrap.flat .meeting{position:relative;height:auto;min-height:76svh}
/* ONE RULE, NO BREAKPOINT — the shape comes from the photograph, at every width.
   `height:76svh` made the column's shape a function of the VIEWPORT while the
   picture inside it is 1440x810, so how much of the photograph you saw depended
   on how tall your window was. Boxing it below 1024 fixed phones and tablets and
   moved the cliff to 1025, where one CSS pixel of width changed the box 2.5x in
   height and dropped a third of the frame — 100% visible at 1024, 46.6% at 1025.
   Deriving the height from the width instead removes the cliff rather than
   relocating it: the column is always exactly the photograph's own 16:9, so the
   whole frame survives from 360 to 1920 and there is no breakpoint to get wrong.

   THIS DOES CHANGE DESKTOP, deliberately, and it is the one place the "desktop
   unchanged" guard gives way — because §1 asks for every image shown complete
   "including both figures in the Meeting photograph" and the acceptance line
   carries no width qualifier. At 1440 the picture went from 66% to 100%. */
.meeting__media{height:auto;aspect-ratio:1440/810;align-self:center}
#meetingWrap.flat .meeting__media{height:auto;align-self:stretch}
/* the pinned column has less room than the loose one did */
.meeting__copy{padding-top:clamp(52px,6vw,92px);padding-bottom:clamp(52px,6vw,92px)}

.meeting__say{
  margin-top:clamp(20px,2.2vw,30px);
  font-family:var(--serif);
  font-weight:400;
  font-size:clamp(17px,1.42vw,23px);
  line-height:1.66;
  letter-spacing:.004em;
  color:rgba(233,236,238,.8);
  max-width:34ch;
  /* the runway the words fly in from — clipped here so the page itself
     never gains a millimetre of horizontal scroll */
  overflow:hidden;
}
/* inline-block so it can be transformed; the spaces BETWEEN the spans stay real
   text nodes, otherwise the paragraph loses every line-break opportunity */
.asw{display:inline-block;will-change:transform,opacity}

@media (max-width:900px){
  .meeting__say{max-width:none;font-size:clamp(16px,2vw,20px)}
}
@media (max-width:767px){
  /* touch: no pin, no scroll hijack, no added height — the lines settle instead */
  #meetingWrap{height:auto}
  .meeting{position:relative;height:auto;min-height:0}
  .meeting__media{height:52svh;align-self:stretch}
  .meeting__copy{padding-top:clamp(56px,12vw,90px);padding-bottom:clamp(56px,12vw,90px)}
  .meeting__say{margin-top:20px;line-height:1.72}
}
@media (prefers-reduced-motion:reduce){
  .meeting{position:relative;height:auto;min-height:76svh}
  .meeting__media{align-self:stretch;height:auto}
  .asw{will-change:auto}
}

/* ============ FRAMED MEDIA — the matte comes off ============
   Four photographs sat inside a white card: 12px of paper, a hairline border
   and a shadow. At this scale that reads as a clip-art frame, not a plate
   from an archive. The photograph is the object now — a soft radius, one
   layered shadow, no paper, no border. Nothing else about them changes. */
.plate__frame{
  padding:0;border:0;background:none;will-change:auto;
  border-radius:18px;overflow:hidden;
  box-shadow:0 54px 104px -46px rgba(16,17,20,.5),0 12px 30px -14px rgba(16,17,20,.22);
}
.plate__frame .ph{border-radius:inherit}
/* the media column is a full-bleed ground, not a card — it must not round */
.plate__media{border-radius:0;overflow:visible}

.doctrine__frame{
  padding:0;border:0;background:none;
  border-radius:16px;overflow:hidden;
  box-shadow:0 46px 92px -42px rgba(16,17,20,.5),0 10px 26px -12px rgba(16,17,20,.2);
}

/* the cursor-following portrait: photograph and name, no card around them */
#tcard{background:none;border:0;padding:0;overflow:visible;box-shadow:none}
#tcard .ph{
  border-radius:14px;overflow:hidden;
  box-shadow:0 38px 74px -32px rgba(16,17,20,.55),0 8px 20px -10px rgba(16,17,20,.22);
}
#tcard .cap{background:none;padding:13px 2px 0;color:#141518}

@media (hover:none),(max-width:767px){
  .trow__fig{background:none;border:0;padding:0;box-shadow:none}
  .trow__fig .ph{
    border-radius:14px;overflow:hidden;
    box-shadow:0 24px 50px -26px rgba(16,17,20,.45),0 6px 16px -8px rgba(16,17,20,.18);
  }
  .trow__fig figcaption{background:none;padding:12px 2px 0}
}

/* ============ CHAPTER II — scrolls like a page, not a pin ============
   Each plate was sticky inside a 200vh wrapper: 100vh of hold, four times
   over. They are ordinary full-height spreads now. */
.plateWrap{height:auto}
.plate{position:relative;height:auto;min-height:100svh}
@media (max-width:900px){.plate{min-height:0}}

/* ============ /house — the three ============
   One card form for all three. Identical portrait treatment, type scale and
   role-line weight, so "Dr." reads as one more fact rather than a rank and
   the three sit as equals with different jobs. The copy lengths differ on
   purpose; the cards do not. */
/* the three sit in the same ivory room as the Doctrine and the origin band
   above them — without this they inherit the dark body and the ink copy
   disappears into it */
.page--house{background:var(--ivory)}
.person{background:var(--ivory);border-top:1px solid var(--hairline-dark);padding:clamp(54px,7vw,104px) var(--gutter)}
.person__grid{display:grid;grid-template-columns:minmax(0,clamp(240px,26vw,380px)) 1fr;
  gap:clamp(28px,4.5vw,76px);align-items:start;max-width:1240px;margin:0 auto}
.person__frame{border-radius:16px;overflow:hidden;margin:0;
  box-shadow:0 46px 92px -42px rgba(16,17,20,.5),0 10px 26px -12px rgba(16,17,20,.2)}
.person__frame img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;display:block}
.person__name{font-family:var(--serif);font-weight:500;font-size:clamp(27px,3vw,46px);
  line-height:1.04;letter-spacing:-.012em;color:#141518}
.person__role{margin-top:13px;font-family:var(--sans);font-size:9.5px;font-weight:400;letter-spacing:.34em;
  text-transform:uppercase;color:rgba(16,17,20,.5)}
.person__copy{margin-top:clamp(20px,2.4vw,32px);color:rgba(16,17,20,.74);max-width:52ch}
.person__copy p+p{margin-top:1.05em}
@media (max-width:900px){.person__grid{grid-template-columns:1fr;gap:26px}
  .person__frame{max-width:340px}}
/* the founder opens /house, so she gets more room than she had as one
   chapter among nine on the old single page.

   The grid brings its OWN clamp(100px,13vw,170px) of vertical padding, so
   adding a second helping here stacked 170 + 140 at the foot, and `.house`
   below then contributed another 170 — a 470px void between the credit and
   THE HOUSE, across which both sections are the same ivory and the eye reads
   only emptiness. The section owns the vertical rhythm now and the grid's own
   vertical padding is zeroed for this variant; the horizontal gutter stays. */
.doctrine--founder{padding-top:clamp(96px,11vw,168px);padding-bottom:clamp(40px,4.5vw,72px)}
.doctrine--founder .doctrine__grid{padding-top:0;padding-bottom:0}
.doctrine--founder .doctrine__grid{gap:clamp(36px,5.5vw,92px)}
.doctrine--founder .doctrine__frame{width:min(100%,520px)}
/* home: the practitioner rows are links now; the touch panel carries the way through */
a.trow__btn{text-decoration:none;color:inherit}
.trow__more{display:none}
@media (hover:none),(max-width:767px){
  .trow__more{display:inline-block;margin:2px 0 22px;font-family:var(--sans);font-size:9px;font-weight:400;
    letter-spacing:.3em;text-transform:uppercase;color:rgba(16,17,20,.55);
    border-bottom:1px solid rgba(16,17,20,.28);padding-bottom:4px}
}
/* cross-document view transitions — the portrait carries between pages */
@view-transition{navigation:auto}
@media (prefers-reduced-motion:reduce){@view-transition{navigation:none}}

/* ============ home — the closing invitation ============
   Not the form: a line and a door. Matches the dark-chapter typography. */
.invite{background:var(--obsidian);position:relative;overflow:hidden;
  padding:clamp(110px,15vw,200px) var(--gutter) clamp(90px,12vw,160px);text-align:center}
.invite__inner{position:relative;z-index:2;max-width:960px;margin:0 auto}
/* ~25% larger with tighter leading, so ARRIVE and `as you are.` read as one
   block rather than two stacked elements. margin-top is 0 now — it existed only
   to clear the eyebrow that no longer sits above it. */
.invite__title{font-family:var(--serif);font-weight:500;font-size:clamp(50px,8.7vw,145px);
  line-height:.92;letter-spacing:-.014em;text-transform:uppercase;margin-top:0}
.invite__title em{font-style:italic;text-transform:none;line-height:.98}
/* the sub-line and the CTA close up against the headline — one composition */
.invite__line{margin:clamp(18px,2vw,24px) auto 0;max-width:30ch;font-size:14px;font-weight:400;color:rgba(233,236,238,.72)}
.invite__cta{margin-top:clamp(26px,3.4vw,34px)}

/* ============ THE PATH — the coiling drop-line ============
   The canvas carries the thread; the drop is the existing asset, moved by
   JS. Depth lives in the stroke, so nothing here needs a filter or a blur. */
/* a longer corridor for the coil: same 3.25 turns stretched over ~47% more
   scroll, so the drop descends slowly rather than racing the wheel */
.path__rail{position:relative;min-height:clamp(820px,105vh,1320px)}
/* the coil needs a corridor of its own: the steps open out so the thread
   never crosses the copy it is meant to be leading you through */
.path__rail .step{grid-template-columns:1fr 1fr;gap:clamp(190px,25vw,400px)}
.path__rail .step__cell{max-width:360px}
.path__coil{position:absolute;inset:0;width:100%;height:100%;z-index:1;pointer-events:none}
.path__rail .step{position:relative;z-index:3}
/* the drop: reflective, not emissive. A tight dark contact shadow does more
   for it than any halo — and the halo is what read cheap. */
/* the drop is the sera-2-drop master, cut out with alpha. It arrives bright
   and properly spherical, so it needs no correction filters — only a tight
   dark contact shadow so it reflects rather than emits. */
.path__bead{position:absolute;left:0;top:0;z-index:4;width:42px;margin:0;
  will-change:transform,opacity;transform-origin:50% 50%;
  filter:drop-shadow(0 4px 7px rgba(10,11,13,.72)) drop-shadow(0 1px 2px rgba(10,11,13,.9))}
.path__bead img{width:100%;height:auto;display:block}
@media (max-width:900px){
  /* §2.5 — the coil gets a lane, the copy ranges beside it.
     Centred copy under a centred coil meant the thread crossed every step
     title and every line of body text, with the ghost thread showing through
     from behind. The lane is the desktop corridor turned ninety degrees:
     coil left, copy right, nothing overlapping. sera-coil.js switches to the
     same lane below 560 of rail width — the two must move together.
     No !important here: `.path__rail .step:nth-of-type(n) .step__cell` is
     (0,4,0) and simply outranks the odd/even rules it has to beat. Raising
     specificity says which rule wins; !important only says that one does. */
  .path__rail{min-height:clamp(520px,70vh,720px)}
  .path__rail .step{grid-template-columns:1fr;gap:0;padding-left:118px;text-align:left}
  .path__rail .step:nth-of-type(n) .step__cell{grid-column:1;justify-self:start;
    text-align:left;max-width:none;margin:0}
  .path__rail .step__dot{left:56px}
  .path__bead{width:30px}
}
@media (prefers-reduced-motion:reduce){
  .path__bead{transition:none}
  .path__rail .step__cell{opacity:1;transform:none;filter:none}
}

/* ============ EditorialScatterShowcase — THE DISCIPLINES ============
   A pinned editorial sequence: the fan compresses behind an oversized word,
   separates to four corners, and clears the middle for the closing line.
   Everything tunable lives in these custom properties. */
#menuWrap{
  --showcase-track:650vh;
  --showcase-background:var(--ivory);
  --showcase-foreground:#101114;
  --showcase-muted:rgba(16,17,20,.55);
  --showcase-accent:var(--teal-deep);
  --showcase-ghost-opacity:.05;
  --showcase-card-radius:14px;
  height:var(--showcase-track);
}
.menu{background:var(--showcase-background)}
.menu__head{transition:none;will-change:transform,opacity}
/* the cards are positioned by the module; keep the stage out of its way */
.menu__stage{position:absolute;inset:0;top:0;transform:none;height:auto;overflow:visible;padding:0}
.card{will-change:transform,opacity}

/* the oversized word over the cluster — editorial, decorative, aria-hidden */
.showcase__word{position:absolute;left:50%;top:50%;z-index:3;pointer-events:none;
  transform:translate3d(-50%,-50%,0);opacity:0;white-space:nowrap;
  font-family:var(--serif);font-weight:500;text-transform:uppercase;
  font-size:clamp(64px,13.5vw,230px);line-height:.86;letter-spacing:-.02em;
  color:rgba(16,17,20,.34)}

/* the enormous faint word behind the closing statement */
.showcase__ghost{position:absolute;left:50%;top:52%;z-index:2;pointer-events:none;
  transform:translate3d(-50%,-50%,0);opacity:0;white-space:nowrap;
  font-family:var(--serif);font-weight:500;text-transform:uppercase;
  font-size:clamp(90px,19vw,340px);line-height:.82;letter-spacing:-.03em;
  color:rgba(16,17,20,var(--showcase-ghost-opacity))}

/* the closing statement, centred in the cleared middle */
.showcase__finale{position:absolute;left:50%;top:50%;z-index:16;
  transform:translate3d(-50%,0,0);opacity:0;text-align:center;width:min(78vw,560px);
  margin-top:-2vh;will-change:transform,opacity,filter}
.showcase__statement{font-family:var(--serif);font-weight:500;
  font-size:clamp(30px,4.6vw,68px);line-height:1.04;letter-spacing:-.012em;
  color:var(--showcase-foreground)}
.showcase__cta{display:inline-block;margin-top:clamp(20px,2.6vw,34px);
  font-family:var(--sans);font-size:10px;font-weight:400;letter-spacing:.32em;text-transform:uppercase;
  font-weight:500;color:var(--showcase-foreground);padding-bottom:6px;position:relative}
.showcase__cta::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:currentColor;transform:scaleX(1);transform-origin:0 50%;
  transition:transform .5s cubic-bezier(.16,1,.3,1)}
.showcase__cta:hover::after{transform:scaleX(.34)}
.showcase__cta:focus-visible{outline:1px solid var(--showcase-foreground);outline-offset:6px}

@media (max-width:1024px){#menuWrap{--showcase-track:450vh}}
/* ---- §1.4 · below 768 the hand is not dealt ----
   Four cards at 48vw have nowhere to fan to, and the pinned scatter left all
   four stacked at the stage origin, on top of the heading, for 350vh of scroll.
   The swipe rail is the composition that works at this width: one snapping
   horizontal row, all four disciplines named and legible, no pin, no added
   page height, and the closing statement below it as ordinary copy.

   sera-showcase.js holds its static state at this tier and writes no transforms
   at all, which is why none of this needs !important. Two systems must never
   write the same property — that was the whole bug, in both directions. */
@media (max-width:767px){
  #menuWrap{--showcase-track:auto;height:auto}
  .menu{position:relative;height:auto;min-height:0;padding:clamp(88px,17vw,120px) 0 clamp(52px,9vw,72px)}
  .menu__head{position:static;padding:0 var(--gutter);margin-bottom:26px;display:block;opacity:1;transform:none}
  .menu__head .eyebrow{margin-bottom:14px}
  .menu__stage{position:relative;inset:auto;transform:none;height:auto;
    display:flex;gap:16px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;padding:6px var(--gutter) 26px}
  .card{position:relative;left:auto;top:auto;transform:none;opacity:1;
    flex:0 0 74vw;width:auto;scroll-snap-align:center;will-change:auto}
  /* The finale exists because on desktop the headline LIFTS AWAY as the cards
     separate, and something has to hold the cleared centre. Nothing lifts away
     here — the headline is still on screen — and its statement is the headline's
     second line word for word. Shown together it reads as a stutter, so on the
     rail it goes. It is aria-hidden decoration; the four cards each carry their
     own EXPLORE, so nothing becomes unreachable. */
  .showcase__word,.showcase__ghost,.showcase__finale{display:none}
}

/* Reduced motion and the no-JS baseline: no pinned track, no scatter — the
   section reads as an ordinary headline, a row of cards and the statement. */
@media (prefers-reduced-motion:reduce){
  #menuWrap{--showcase-track:auto;height:auto}
  .menu{position:relative;height:auto;min-height:0;padding:clamp(90px,12vw,150px) 0}
  .menu__head{position:static;padding:0 var(--gutter);margin-bottom:44px}
  .menu__stage{position:relative;top:auto;transform:none;display:flex;flex-wrap:wrap;
    justify-content:center;gap:22px;padding:0 var(--gutter)}
  .card{position:relative;left:auto;top:auto;transform:none;
    opacity:1;width:min(300px,42vw)}
  .showcase__word,.showcase__ghost{display:none}
  .showcase__finale{position:relative;left:auto;top:auto;transform:none;opacity:1;
    filter:none;margin:clamp(50px,7vw,90px) auto 0}
}
.showcase--static .showcase__word,.showcase--static .showcase__ghost{display:none}

/* The four `opacity:1 !important` overrides that stood here are gone, together
   with the dead `.is-front` rules they were fighting. Nothing hides a card
   footer any more, so nothing has to force one visible. `.showcase--parted`
   survives as a hook for anything that wants to know the hand has separated;
   it no longer has to undo anything. */

/* ============================================================
   §3 · THE LABELS THE TYPE PASS MISSED
   The type prompt's §1 set one law for small caps labels — 11px / 500 / .24em,
   off --steel — and it was applied to `.eyebrow` and its chapter variants. It
   did not reach these, because every one of them declares its own size, weight
   and tracking inside a scoped or shorthand rule, which is invisible to a
   `font-weight` grep. They are the four things §3 names, and they are the same
   defect: 8.5–10px at weight 400 with .32–.40em of tracking, in ink so pale it
   is below AA.

   Measured against their real rendered backdrop at 390px, before:
     plate caption rows  3.94:1     plate cap        2.71:1
     practitioner role   3.36:1     founder role     3.36:1
     card line           4.20:1     menu counter     3.54:1
   Every one of those is under 4.5:1.

   The ink alpha is .62 — the SAME number the eyebrow pass arrived at, and for
   the same reason: obsidian on ivory is the weaker pairing, so it needs more
   than the .55 that works for porcelain on obsidian. .62 measures 4.87:1 on
   ivory and 5.33:1 on white card stock. One number for the whole system rather
   than a value per label.
   Porcelain labels on dark grounds keep .55/.66 — they already measure 5.4–7.5.
============================================================ */
.plate__list div{font-size:10.5px;font-weight:500;letter-spacing:.2em;color:rgba(16,17,20,.62)}
/* .68, not .62 — this one sits on the plate media column's radial, which is
   lighter at its centre than flat ivory, so the shared alpha lands at 4.36:1
   here. The number is the target, not the alpha. */
.plate__cap{font-size:10px;font-weight:500;letter-spacing:.3em;color:rgba(16,17,20,.68)}
.person__role{font-size:10.5px;font-weight:500;letter-spacing:.24em;color:rgba(16,17,20,.62)}
.doctrine__credit .role{font-size:10.5px;font-weight:500;letter-spacing:.24em;color:rgba(16,17,20,.62)}
.card__line{font-size:10.5px;font-weight:500;letter-spacing:.16em;color:rgba(16,17,20,.62)}
.house__label{font-size:10.5px;font-weight:500;letter-spacing:.26em;color:rgba(16,17,20,.62)}
.trow__role{font-size:10.5px;font-weight:500;letter-spacing:.2em;color:rgba(16,17,20,.62)}
.trow__figrole{font-size:10px;font-weight:500;letter-spacing:.22em;color:rgba(16,17,20,.62)}
.trow__more{font-size:10px;font-weight:500;letter-spacing:.26em;color:rgba(16,17,20,.62)}
.begin__stackcap{font-size:10.5px;font-weight:500;letter-spacing:.3em}
/* This is the page that takes the booking. A label you have to hunt for is not
   a small design flaw here, it is the form failing. */
.f__label{font-size:11px;font-weight:500;letter-spacing:.24em;color:rgba(233,236,238,.72)}
.f__note{font-size:10px;font-weight:500;letter-spacing:.22em}
.form__head .s{font-size:11px;font-weight:500;letter-spacing:.24em}
.fchip span{font-size:10.5px;font-weight:500;letter-spacing:.18em;color:rgba(233,236,238,.82)}
.begin__meta{font-size:10.5px;font-weight:500;letter-spacing:.24em}
/* over a moving film, tracked apart, small: it needs the weight */
.voice .a{font-size:11px;font-weight:500;letter-spacing:.26em}

/* ============================================================
   §2 · THE RUNWAYS DO NOT MOVE WHEN A TOOLBAR DOES
   The three vh runways on home are what turn an 88px toolbar transition into
   an 862px jump: 1260vh of reserved scroll means the document is 12.6x the
   viewport, and #house sits 980vh down. Below 900px they are expressed against
   --vpx — a pixel height measured once by the nav partial and re-measured only
   on a change of WIDTH — so a collapsing URL bar changes nothing about the
   document's geometry.
   The multipliers are the originals: 4.4 / 6.6 / -1.2 / 2.8 / 0.52. Desktop
   keeps vh, where a resize is deliberate and re-laying-out is correct.
   `.flat` (the reduced-motion baseline) is (1,1,0) and still wins over both.
============================================================ */
@media (max-width:900px){
  #heroWrap{height:calc(var(--vpx,100vh) * 4.4)}
  #measureWrap{height:calc(var(--vpx,100vh) * 6.6);margin-top:calc(var(--vpx,100vh) * -1.2)}
  #voicesWrap{height:calc(var(--vpx,100vh) * 2.8)}
}
@media (max-width:767px){
  .meeting__media{height:calc(var(--vpx,100vh) * .52)}
}

/* ============================================================
   §5 · FULL-BLEED CROPS AT 9:19.5
   A 16:9 film in a 390x848 box shows 100% of its height and only ~26% of its
   width, so `center` is not a neutral choice — it is a decision to show the
   middle quarter, and on these frames the middle quarter is the part without
   the subject in it. Every value below was chosen by rendering the candidates
   side by side (scratchpad/shots/op-sheet.png), not computed: a luminance
   centroid put "Beneath the surface" at 52% because the bright expanse of skin
   outweighs the small teal glow that is actually the subject.

     beat 0  Placement   32%   the closed eye, the cheek and THE DROP. At 50%
                               the drop is at the frame edge; past 58% it is
                               gone, and the drop is the whole point of the beat.
     beat 1  Beneath     58%   the glow centred under the shoulder's sweep.
                               At 32% there is no glow in frame at all.
     beat 2  Wave        32%   the vortex, with the ribbon running out of frame.
                               At 50%+ it is a diagonal band under empty black.
     Meeting             68%   the practitioner, attentive, with the other chair
                               still in frame so it reads as a conversation.
                               "The first treatment is listening" — she is the
                               listener, and at 32% she is not in the picture.

   Desktop keeps `center` everywhere: at 16:9-ish it shows 85-90% of the frame
   and the approved composition is the whole composition.

   VOICES IS DELIBERATELY UNTOUCHED. It is abstract skin with no subject to cut,
   the founder did not name it, and its three veil tiers were measured against
   this exact crop — moving it would invalidate 5.0-6.0:1 readings taken at six
   widths for nothing.
============================================================ */
@media (max-width:900px){
  .m-beat[data-b="0"]{background-position:32% 50%}
  .m-beat[data-b="0"] img,.m-beat[data-b="0"] video{object-position:32% 50%}
  /* 68%, not 58%. Both frame the glow, but at 58% it lands under the caption
     and drops "Beneath the surface." to 5.31:1 mean and 1.22:1 against its
     brightest pixel; at 68% the glow moves clear and the same words read
     5.98:1 / 2.24:1. Composition and legibility agreed here — both measured. */
  .m-beat[data-b="1"]{background-position:68% 50%}
  .m-beat[data-b="1"] img,.m-beat[data-b="1"] video{object-position:68% 50%}
  .m-beat[data-b="2"]{background-position:32% 50%}
  .m-beat[data-b="2"] img,.m-beat[data-b="2"] video{object-position:32% 50%}
  /* beat 3 is the reveal portrait and keeps its founder-set `center 22%` */
  .m-beat[data-b="3"]{background-position:50% 22%}
  .meeting__media img{object-position:68% 30%}
}

/* The reveal beats' captions sit on a lit neck and shoulder — "The measure."
   reads 3.89:1 mean and 1.89:1 against its brightest pixel at 390px. That is
   the founder-set `center 22%` crop and it is not mine to move, so the veil
   does the work instead: the same corner wash, deeper, on phones only, where
   the frame is a quarter as wide and the lit area fills far more of it.
   No new colour — the veil is already black. */
@media (max-width:900px){
  .measure__veil{width:100%;height:46%;
    background:radial-gradient(150% 130% at 0% 100%,rgba(0,0,0,.86),rgba(0,0,0,.5) 45%,rgba(0,0,0,0) 78%)}
}

/* ============================================================
   §1 RULE B · THE MEETING PHOTOGRAPH IS BOXED, NOT CROPPED
   Founder ruling: the practitioner and the client sit side by side, so NO
   portrait crop can contain both — and a crop that keeps one of them is a
   photograph of the wrong thing. It stops being full-bleed on a phone and
   becomes what print editorial would do with it: the whole frame, at its own
   1440x810, inside the gutters, with air around it.
   The box IS the source ratio, so cover and contain are the same thing here
   and no letterboxing is possible — which matters, because a band of empty
   space above and below is the "letterboxed hero" defect already rejected.
   The parallax comes off with the bleed: a 0.6% drift inside a 0.6% overscale
   is a full-bleed window's idiom, and on a boxed plate it would show its edge.
   Desktop is untouched — it keeps the full-height media column at 76svh.
============================================================ */
@media (max-width:1024px){
  /* it is the first thing on /path, and a plate that starts at y=0 slides
     under the fixed nav — a full-bleed image can survive that, a framed
     photograph cannot */
  .meeting__media{height:auto;align-self:start;overflow:visible;
    padding:calc(var(--navH) + clamp(22px,6vw,42px)) var(--gutter) 0}
  .meeting__media img{width:100%;height:auto;aspect-ratio:1440/810;object-fit:cover;
    object-position:center;transform:none;will-change:auto;border-radius:14px;
    box-shadow:0 26px 56px -28px rgba(10,11,13,.7)}
}

/* ============================================================
   UPDATE 5 §2 · THE RELEASE IS A CLOSE-UP FILM ON A PHONE
   Same box and stacking as the canvas it stands in for; opacity is driven by
   setHero with the canvas's own envelope. Desktop never shows or arms it.
============================================================ */
.hero__fall{position:absolute;inset:0;z-index:5;width:100%;height:100%;
  object-fit:cover;opacity:0;visibility:hidden;pointer-events:none}
@media (min-width:768px){.hero__fall{display:none}}
