html.static{scroll-behavior:auto!important;scroll-snap-type:none!important}
html.static .reveal{opacity:1!important;transform:none!important;transition:none!important}
:root{
  --sienna:#92492F;--sienna-dark:#7A3A24;--ivory:#F7F4ED;--ivory-2:#EFEBE1;--gold:#B99A60;--ink:#20231F;--ink-2:#5C5A53;--deep:#171715;--deep-2:#232320;
  --line:rgba(32,35,31,.12);--line-strong:rgba(32,35,31,.3);
  --r-btn:10px;--r-card:12px;--r-media:12px;
  --pad:48px;--sec:80px;--maxw:none;--nav-h:76px;
  --h1:64px;--h2:36px;--h3:18px;--lede:17px;--body:16px;--hw:500;
}
/* Subpages get a capped, centered content width and fluid side padding so they
   scale gracefully from phones to ultrawide (the landing page keeps its full-bleed layout). */
html.subpage{--maxw:1280px;--pad:clamp(20px,4vw,48px)}

*{box-sizing:border-box}
html{scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:none}
/* native scrollbar hidden — the page is one section per screen, so a section guide (right edge) does the wayfinding instead */
::-webkit-scrollbar{display:none}
.guide{position:fixed;right:22px;top:50%;transform:translateY(-50%);z-index:19;display:flex;flex-direction:column;gap:10px;margin:0;padding:0;list-style:none}
.guide a{display:block;width:16px;height:16px;position:relative}
.guide a::before{content:"";position:absolute;left:50%;top:50%;width:6px;height:6px;border-radius:50%;background:rgba(32,35,31,.55);box-shadow:0 0 0 1.5px rgba(247,244,237,.8);transform:translate(-50%,-50%);transition:height .25s var(--ease-out,ease),background .2s,border-radius .25s}
.guide a:hover::before{background:rgba(32,35,31,.85)}
.guide a.on::before{height:24px;border-radius:3px;background:var(--sienna)}
.guide.dark a::before{background:rgba(247,244,237,.7);box-shadow:0 0 0 1.5px rgba(23,23,21,.5)}
.guide.dark a.on::before{background:var(--gold)}
body{margin:0;background:var(--ivory);color:var(--ink);font-family:Manrope,system-ui,sans-serif;font-size:var(--body);-webkit-font-smoothing:antialiased;line-height:1.5}
h1,h2,h3,p{margin:0}
a{color:inherit;text-decoration:none}
.wrap{padding-left:var(--pad);padding-right:var(--pad)}
.inner{max-width:var(--maxw);margin:0 auto}
.eyebrow{font-size:12px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--sienna)}
.eyebrow.gold{color:var(--gold)}
h2{font-size:var(--h2);font-weight:var(--hw);letter-spacing:-.03em;line-height:1.1;text-wrap:balance}
h3{font-size:var(--h3);font-weight:600;letter-spacing:-.01em}
.sub{color:var(--ink-2);font-size:calc(var(--body) + 1px);max-width:520px;text-wrap:pretty}
.sec{padding-top:var(--sec)}
.sechead{display:flex;flex-direction:column;gap:16px;margin-bottom:48px}

/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;font-weight:600;font-size:16px;padding:16px 24px;border-radius:var(--r-btn);min-height:52px;transition:background .18s,transform .12s,border-color .18s,color .18s;cursor:pointer;white-space:nowrap;border:1px solid transparent}
.btn:active{transform:scale(.985)}
.btn.primary{background:var(--sienna);color:var(--ivory);border-color:var(--sienna)}
.btn.primary:hover{background:var(--sienna-dark);border-color:var(--sienna-dark)}
.btn.secondary{border-color:var(--ink);color:var(--ink)}
.btn.secondary:hover{background:rgba(32,35,31,.05)}
.btn.small{font-size:15px;padding:12px 20px;min-height:44px}
.btn svg{width:16px;height:16px}
.mono{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;letter-spacing:.02em}
.media{background:repeating-linear-gradient(135deg,#DDD6C7 0 10px,#E6E0D3 10px 20px);border-radius:var(--r-media);position:relative;overflow:hidden}
.media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.media .cap{position:absolute;left:16px;bottom:16px;background:var(--ivory);color:var(--ink-2);padding:6px 10px;border-radius:calc(var(--r-btn) / 2);z-index:1}
.media.dark{background:repeating-linear-gradient(135deg,#232320 0 10px,#2A2A26 10px 20px)}
.panel{background:var(--ivory-2);border:1px solid transparent;border-radius:var(--r-card)}

/* header */
/* The hero is light-topped (bare wall), so the header runs in ink over it — same palette as the glass state, no scrim needed. */
header{height:var(--nav-h);display:flex;align-items:center;justify-content:space-between;gap:32px;position:fixed;left:0;right:0;top:0;z-index:20;color:var(--ink);transition:background .25s,box-shadow .25s,border-color .25s,color .25s;border-bottom:1px solid transparent}
header .in{display:flex;align-items:center;justify-content:space-between;gap:32px;width:100%;max-width:var(--maxw);margin:0 auto}
header.scrolled{background:rgba(247,244,237,.88);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-bottom:1px solid var(--line);color:var(--ink)}
nav{display:flex;gap:36px;font-size:15px;font-weight:500}
nav a:hover{color:var(--sienna)}
.menu{display:none;width:44px;height:44px;align-items:center;justify-content:center;background:none;border:0;color:inherit;cursor:pointer}
.menu svg{width:24px;height:24px}
/* mobile dropdown menu */
.sheet{display:none;position:fixed;inset:auto 0 auto 0;top:var(--nav-h);z-index:30;background:var(--ivory);padding:8px 20px 20px;flex-direction:column;gap:8px;border-bottom:1px solid var(--line);box-shadow:0 24px 48px rgba(32,35,31,.12)}
.sheet.open{display:flex}
.sheet a.link{font-size:18px;font-weight:600;letter-spacing:-.02em;padding:12px 0;border-bottom:1px solid var(--line)}
.sheet .btn{margin-top:12px}

/* wordmark — 3a stack, sienna tomorrow 700 / ink homes 400, gold on dark */
.brand{display:inline-flex;flex-direction:column;line-height:.92;letter-spacing:-.035em;font-size:22px}
.brand .t{font-weight:700;color:var(--sienna)}
.brand .h{font-weight:400;color:var(--ink)}
.immersion .brand .t{color:var(--gold)}
.immersion .brand .h{color:var(--ivory)}

/* hero — the virtual screen IS the hero. Image renders true; one line of copy, top-left, in the free wall above her head. */
.hero{position:relative;height:100vh;height:100dvh;min-height:640px;scroll-snap-align:start;scroll-snap-stop:always;overflow:hidden}
.hero-media{position:absolute;inset:0;border-radius:0}
/* anchor the crop to the TOP: the screen's top-right corner sits ~10% down the picture, so any top crop pushes it under the header CTA. Wide viewports crop the rug/table at the bottom instead. */
/* 15% keeps the screen's top-right corner clear of the header CTA at 16:9 and 2:1 windows; the remaining crop comes off the rug so she stays in frame head-to-lap. */
.hero-media img{object-position:50% 15%}
/* Art direction by aspect ratio — a plain cover crop with a per-ratio anchor, never synthetic fill. The hero master is a
   3:2 photo art-directed with expendable margins (see HANDOFF "Hero safe zones"): wide windows crop the top/bottom bands,
   squarer ones crop the side bands, portrait keeps her hand + the screen's left half (a phone-specific master is the
   proper fix and belongs to the mobile pass). */
@media (min-aspect-ratio:16/9){ .hero-media img{object-position:50% 7%} }   /* wide: centre-ish, biased up for the header */
@media (max-aspect-ratio:1/1){ .hero-media img{object-position:49% 50%} }    /* portrait: her + hand + screen left half */
/* Local light wash behind the text column only — the wall there carries hard sun streaks that break type up.
   Fades out horizontally before the screen's left edge and vertically before her head; the rest of the picture is untouched. */
.hero-media::after{content:"";position:absolute;left:0;top:0;width:30vw;height:50vh;pointer-events:none;
  background:linear-gradient(90deg,rgba(247,244,237,.74) 0%,rgba(247,244,237,.66) 52%,rgba(247,244,237,0) 100%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%);mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%)}
/* Hero copy: a plain hierarchy — eyebrow, two-line h1 at one size, short lede, one button — in the free column
   above her head and left of the screen (≈445×445 at 1920×1080). Width caps the h1's long line ("experienced today.")
   against the screen's left edge; height caps the whole block against her head on short windows. */
/* Spacing scales with vw, not vh: the image is width-bound, so her head's y position tracks viewport width. */
/* Block sits optically centred in the free zone (header bottom → her head), clear of the wordmark so the two don't read as one stack. */
.hero-copy{position:absolute;left:var(--pad);top:calc(var(--nav-h) + 8.5vw);z-index:1;display:flex;flex-direction:column;align-items:flex-start;gap:0;
  max-width:min(800px,calc(var(--screen-left,40vw) - var(--pad) - 28px))} /* --screen-left is set by hero-pano.js from the fitted screen */
/* Two lines, one size; the accent word is an italic serif in rust — the emphasis comes from the contrast of form, not just colour. */
.hero-copy h1{font-size:clamp(28px,min(2.75vw,5.4vh),58px);line-height:1.08;font-weight:var(--hw);letter-spacing:-.03em;color:var(--ink);text-wrap:balance}
/* Serif sized to Manrope's x-height (not its cap height) so the two share a visual baseline and waistline; line-height 1 so it never lifts the line box. */
.hero-copy h1 em{font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-style:italic;font-weight:400;font-size:1.06em;line-height:1;letter-spacing:0;color:var(--sienna)}
.hero-copy .lede{font-size:clamp(15px,.9vw,17px);line-height:1.5;color:var(--ink-2);margin-top:clamp(10px,1.1vw,20px);text-wrap:pretty}
/* hero panorama — the curved screen shows a 360° still the visitor can drag around (assets/hero-pano.js).
   .hero-stage is sized by script to the cover-fitted photo, so every % below is a coordinate in the 2400×1600 picture;
   its font-size is 1% of the photo's width, so the controls scale with it. Panel + hint appear only once the pano is live. */
.hero{--screen-ar:1.5270;} /* the screen box's aspect (generated by tools/fit_hero_screen.py); the band's shape in squarish mode */
.hero-stage{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
.hero-stage[hidden]{display:none}
.hero-pano{position:absolute;left:34.4401%;top:8.1019%;width:53.3854%;height:62.1528%;display:block;pointer-events:auto;touch-action:pan-y}
/* hero controls — one glass family (finish pill, light pill, expand button); a sibling of the media and the copy.
   DESKTOP / landscape: a vertical column at the screen's right edge, at the spot the calibrated layout put it in
   the photo (81.103% / 14.361% of the 1536×864 master). hero-pano.js publishes the fitted photo's box on .hero as
   --stage-left/top/w/h and --stage-em (1% of its width), so the column tracks the photo at any viewport. The
   squarish and portrait blocks further down lay the same markup out as a row in normal flow. */
.vs-panel{position:absolute;left:calc(var(--stage-left,0px) + var(--stage-w,100%) * .81103);top:calc(var(--stage-top,0px) + var(--stage-h,100%) * .14361);
  width:auto;font-size:var(--stage-em,1vw);display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1.2em;pointer-events:auto;z-index:3}
/* each pill hugs its two radios: the gap and the bottom padding leave exactly the room for the label under each radio
   (from its aria-label, desktop only). Column height ≈ 2 × 10.9em + gaps + expand ≈ 28em, inside the screen's 31em. */
.vs-group{display:flex;flex-direction:column;align-items:center;box-sizing:border-box;width:5.2em;padding:.7em 0 2.1em;gap:2.1em;border-radius:999px;pointer-events:auto;
  border:.08em solid rgba(255,255,255,.42);background:rgba(28,20,14,.42);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 .3em 1.2em rgba(40,25,15,.18)}
.vs-radio::after{content:attr(aria-label);position:absolute;left:50%;top:100%;transform:translateX(-50%);margin-top:.4em;white-space:nowrap;pointer-events:none;
  font-family:Manrope,system-ui,sans-serif;font-size:.89em;font-weight:500;letter-spacing:.01em;color:rgba(255,255,255,.94);filter:drop-shadow(0 2px 6px rgba(40,25,15,.35))}
.vs-radio{position:relative;margin:0;padding:0;box-sizing:border-box;width:3.01em;height:3.01em;flex:none;pointer-events:auto;cursor:pointer;
  display:flex;align-items:center;justify-content:center;border-radius:50%;
  background:rgba(255,255,255,.12);border:.09em solid rgba(255,255,255,.55);color:rgba(255,255,255,.94);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);box-shadow:0 .2em .8em rgba(40,25,15,.18)}
.vs-radio:hover{background:rgba(255,255,255,.22)}
.vs-radio[aria-checked="true"]{border-color:#fff;box-shadow:0 0 0 2px #fff,0 0 0 6px var(--sienna),0 .2em .9em rgba(40,25,15,.3)}
.vs-radio svg{width:52%;height:52%;stroke-width:1.5}
.vs-radio .swatch{width:62%;height:62%;border-radius:50%;box-shadow:inset 0 .1em .3em rgba(0,0,0,.25)}
.vs-oak .swatch{background:linear-gradient(135deg,#D9A868,#B9803F)}
.vs-walnut .swatch{background:linear-gradient(135deg,#6B4A32,#3B2618)}
.vs-radio[data-missing]{opacity:.45;cursor:not-allowed}
.vs-hint{position:absolute;left:57.75%;top:57.34%;transform:translateX(-50%);white-space:nowrap;pointer-events:none;opacity:0;font-size:.6em;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.92);background:rgba(40,30,25,.4);padding:.6em 1em;border-radius:2em;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:opacity .4s}
/* controls + hint appear once hero-pano.js has the screen live; no WebGL → .nopano hides the controls (the baked photo stands) */
.hero .vs-panel{opacity:0;transition:opacity .4s}
.hero.live .vs-panel,.hero-stage.live .vs-hint{opacity:1}
.hero.nopano .vs-panel{display:none}
.hero-stage.held .vs-hint{opacity:0}
h1{font-size:var(--h1);line-height:1;font-weight:var(--hw);letter-spacing:-.035em;text-wrap:balance}
.lede{font-size:var(--lede);color:var(--ink-2);max-width:520px;text-wrap:pretty}
.ctas{display:flex;gap:12px;flex-wrap:wrap}

/* benefits — one idea per viewport as a FULL-BLEED still, copy overlaid bottom-left (numeral, sentence headline in the hero voice, one paragraph).
   Legibility comes from a soft local wash behind the copy corner only — same device as the hero — so the still renders true everywhere else.
   Author stills with a calmer bottom-left third. */
.benefit{position:relative;height:100vh;height:100dvh;min-height:640px;overflow:hidden;scroll-snap-align:start;scroll-snap-stop:always}
.b-media{position:absolute;inset:0;border-radius:0}
/* panel 01 still was rendered with generous room around the subject; tighten ~10% toward the wardrobe (there is spare wall/floor on every side) */
.b-media img.tight{transform:scale(1.1);transform-origin:66% 56%;object-position:50% 58%}
/* finish comparison: two identical stills, the dark one clipped by a draggable divider. Range is clamped to the cabinet run in JS (the left third is the open wall the copy sits on). */
.compare{--p:62%}
.compare .cmp-top{clip-path:inset(0 0 0 var(--p))}
.cmp-bar{position:absolute;top:0;bottom:0;left:var(--p);width:2px;margin-left:-1px;background:rgba(247,244,237,.96);box-shadow:0 0 0 1px rgba(32,35,31,.06),0 0 28px rgba(32,35,31,.22);z-index:2}
.cmp-handle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:52px;height:52px;border-radius:50%;background:rgba(247,244,237,.92);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid rgba(32,35,31,.12);display:flex;align-items:center;justify-content:center;cursor:ew-resize;touch-action:pan-y;color:var(--ink);padding:0}
.cmp-handle svg{width:22px;height:22px;stroke-width:1.5}
.cmp-handle:active{transform:translate(-50%,-50%) scale(.96)}
/* parts overlay (panel 03): tags positioned in % of the IMAGE, on a box that JS keeps aligned with the object-fit:cover rect, so they track the crop */
.tags{position:absolute;z-index:1;pointer-events:none}
.callouts{display:block;width:100%;height:100%}
#b5 .b-media img{object-position:50% 0} /* short windows crop the sofa at the bottom, not the TV */
.callouts .lead polyline{fill:none;stroke:rgba(32,35,31,.5);stroke-width:1;vector-effect:non-scaling-stroke}
.callouts .dots circle{fill:none;stroke:var(--ink);stroke-width:1.5;vector-effect:non-scaling-stroke}
.callouts .name text{font-family:Manrope,system-ui,sans-serif;font-weight:600;font-size:14.5px;letter-spacing:0;fill:var(--ink)}
.callouts .spec text{font-family:Manrope,system-ui,sans-serif;font-weight:400;font-size:12px;letter-spacing:0;fill:var(--ink-2)}
/* panel 03 MOBILE callouts: same leader style as desktop, on the full-bleed tall portrait master. Type is scaled
   up (viewBox 1080 → phone width) and carries a soft ivory halo so it stays crisp over the image. Desktop keeps
   its own landscape callouts (.cLand). */
.cPort{display:none}
.cPort .name text{font-size:34px}
.cPort .spec text{font-size:27px}
.cPort .name text,.cPort .spec text{paint-order:stroke;stroke:rgba(247,244,237,.72);stroke-width:4px;stroke-linejoin:round}
.cPort .lead polyline{stroke:rgba(32,35,31,.62)}
.cPort .dots circle{stroke:var(--ink);stroke-width:2}
.b-media::after{content:"";position:absolute;left:0;bottom:0;width:38vw;height:52vh;pointer-events:none;
  background:linear-gradient(90deg,rgba(247,244,237,.8) 0%,rgba(247,244,237,.7) 50%,rgba(247,244,237,0) 100%);
  -webkit-mask-image:linear-gradient(0deg,#000 0%,#000 58%,transparent 100%);mask-image:linear-gradient(0deg,#000 0%,#000 58%,transparent 100%)}
.benefit.copy-mid .b-copy{bottom:auto;top:22vh;max-width:min(500px,24vw - 48px)}
.benefit.copy-mid .b-copy p{max-width:100%}
.benefit.copy-mid .b-media::after{bottom:auto;top:12vh;height:60vh;-webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 22%,#000 78%,transparent 100%);mask-image:linear-gradient(180deg,transparent 0%,#000 22%,#000 78%,transparent 100%)}
.b-copy{position:absolute;left:var(--pad);right:var(--pad);bottom:9vh;z-index:1;display:flex;flex-direction:column;align-items:flex-start;max-width:560px}
.b-copy h2{font-size:clamp(36px,2.9vw,58px);line-height:1.06;font-weight:var(--hw);letter-spacing:-.03em;color:var(--ink);text-wrap:balance}
.b-copy h2 em{font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-style:italic;font-weight:400;font-size:1.06em;line-height:1;letter-spacing:0;color:var(--sienna)}
.b-copy p{font-size:17px;line-height:1.55;color:var(--ink-2);margin-top:20px;max-width:500px;text-wrap:pretty}

/* deliverables */
.deliv-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:start}
.deliv-list{display:flex;flex-direction:column;border-top:1px solid var(--ink)}
.deliv{display:grid;grid-template-columns:28px 1fr auto;gap:20px;align-items:start;padding:24px 0;border-bottom:1px solid var(--line)}
.deliv svg{width:22px;height:22px;stroke-width:1.5;margin-top:2px}
.deliv .t{font-weight:600;font-size:17px}
.deliv .d{font-size:15px;color:var(--ink-2);margin-top:4px}
.deliv .n{font-size:13px;color:var(--gold);font-weight:700;letter-spacing:.1em}
.deliv-media{height:520px}
/* how-it-works media = an inline-SVG kitchen elevation (a real contractor-ready drawing, static + agent-readable) */
.deliv-media.sheet{background:var(--ivory-2)}
/* elevation drawing slot: definite aspect so the SVG always has a height in normal flow */
.elev-slot{aspect-ratio:1000/650;background:var(--ivory-2);border-radius:var(--r-media);overflow:hidden}
.elev-slot .elev{display:block;width:100%;height:100%}
.elev .frame{fill:none;stroke:var(--line);stroke-width:1}
.elev .grid{stroke:rgba(32,35,31,.05);stroke-width:1}
.elev .cab{fill:none;stroke:var(--ink);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.elev .cabx{fill:none;stroke:var(--ink);stroke-width:1.1}
.elev .appl{fill:none;stroke:var(--ink);stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}
.elev .worktop{fill:rgba(32,35,31,.09);stroke:var(--ink);stroke-width:1.6}
.elev .floor{stroke:var(--ink);stroke-width:2.4;stroke-linecap:round}
.elev .hatch{stroke:var(--ink-2);stroke-width:1}
.elev .hw{fill:var(--gold)}
.elev .dim{stroke:var(--ink-2);stroke-width:1}
.elev text{font-family:ui-monospace,Menlo,Consolas,monospace}
.elev .dt{font-size:12px;fill:var(--ink-2)}
.elev .lbl{font-size:12px;fill:var(--ink);letter-spacing:.02em}
.elev .lead{stroke:var(--ink-2);stroke-width:1;fill:none}
.elev .tt{font-size:12px;fill:var(--ink);letter-spacing:.16em}
.elev .tt.gold{fill:var(--gold)}

/* pricing */
.pricing{padding:64px;display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.price{font-size:var(--h2);font-weight:var(--hw);letter-spacing:-.03em;line-height:1.1}
.pricing p{font-size:17px;color:var(--ink-2);max-width:420px}
.rows{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--ink)}
.row{display:flex;justify-content:space-between;padding:20px 0;border-bottom:1px solid var(--line);font-size:18px}
.row b{font-weight:600}

/* proof / projects */
.proof{display:grid;grid-template-columns:2fr 1fr;gap:24px}
.proof .big{height:560px}
.proof .stack{display:flex;flex-direction:column;gap:24px}
.proof .stack .media{flex:1}
.proof-note{display:flex;gap:16px;align-items:baseline;margin-top:24px;color:var(--ink-2);font-size:15px}
.proof-note b{color:var(--ink);font-weight:600}

/* immersion */
.imm-band{position:relative}
.immersion{background:var(--deep);color:var(--ivory);padding:64px var(--pad);display:flex;flex-direction:column;gap:32px;--line:rgba(247,244,237,.12);scroll-snap-align:start;scroll-snap-stop:always;height:100vh;height:100dvh;justify-content:center;overflow-y:auto}
.immersion .in{max-width:var(--maxw);margin:0 auto;width:100%;height:100%;display:flex;flex-direction:column;gap:32px;justify-content:center}
.immersion .head{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;flex:none}
.immersion h2{font-size:28px}
.immersion .head p{color:rgba(247,244,237,.7);font-size:15px;margin-top:8px;max-width:420px}
.immersion .mono{color:var(--gold);letter-spacing:.08em}
.player.media.dark{flex:1 1 0;min-height:360px;transition:background .5s;background:radial-gradient(120% 80% at 50% 30%,#3A342C 0%,#26231F 45%,#171715 100%)}
.player.day{background:radial-gradient(120% 80% at 50% 30%,#8C7B66 0%,#5A5148 45%,#2E2B27 100%)}
.player .cap{background:rgba(247,244,237,.08);color:var(--ivory);left:auto;right:16px;bottom:auto;top:16px}
/* dark controls */
.controls{position:absolute;left:24px;right:24px;bottom:24px;display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap}
.chrome{display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(247,244,237,.1);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid rgba(247,244,237,.22);border-radius:var(--r-btn)}
.sw{width:36px;height:36px;border-radius:calc(var(--r-btn) / 2);cursor:pointer;transition:transform .15s}
.sw:hover{transform:translateY(-2px)}
.sw.on{outline:2px solid var(--ivory);outline-offset:2px}
.chrome .lbl{font-size:13px;margin-left:8px;color:rgba(247,244,237,.85)}
.rooms{display:flex;gap:8px;position:absolute;left:24px;top:24px}
.room{font-size:13px;font-weight:600;padding:9px 14px;border-radius:var(--r-btn);border:1px solid rgba(247,244,237,.2);color:rgba(247,244,237,.8);cursor:pointer;min-height:36px;display:inline-flex;align-items:center}
.room.on{background:var(--ivory);color:var(--deep);border-color:var(--ivory)}
.dn{display:inline-flex;border:1px solid rgba(247,244,237,.2);border-radius:var(--r-btn);overflow:hidden}
.dn button{background:transparent;border:0;color:rgba(247,244,237,.7);font:inherit;font-size:13px;font-weight:600;padding:9px 14px;cursor:pointer;display:inline-flex;gap:6px;align-items:center;min-height:36px}
.dn button svg{width:14px;height:14px}
.dn button.on{background:var(--ivory);color:var(--deep)}
.imm-cta{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;color:rgba(247,244,237,.7);font-size:15px;flex:none}
.immersion .btn.primary{background:var(--gold);color:var(--deep);border-color:var(--gold)}
.immersion .btn.primary:hover{background:#CBAF78;border-color:#CBAF78}
.immersion .btn.primary svg{stroke:var(--deep)}

/* form */
.form-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:64px;align-items:start}
.form{display:flex;flex-direction:column;gap:20px;padding:40px}
.field{display:flex;flex-direction:column;gap:8px}
.field label{font-size:13px;font-weight:600;color:var(--ink-2)}
.field input,.field select{font:inherit;font-size:16px;padding:0 16px;height:52px;border:1px solid var(--line-strong);border-radius:var(--r-btn);background:var(--ivory);color:var(--ink);outline:0;width:100%}
.field input:focus,.field select:focus{border-color:var(--sienna);box-shadow:0 0 0 3px rgba(146,73,47,.2)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.seg{display:flex;gap:8px;flex-wrap:wrap}
.seg span{padding:12px 16px;border:1px solid var(--line-strong);border-radius:var(--r-btn);font-size:15px;font-weight:500;cursor:pointer;min-height:44px;display:inline-flex;align-items:center}
.seg span.on{background:var(--ink);color:var(--ivory);border-color:var(--ink)}
.form .fine{font-size:13px;color:var(--ink-2)}
.form-copy{display:flex;flex-direction:column;gap:20px}
.form-copy .pt{display:flex;gap:14px;font-size:16px;color:var(--ink-2)}
.form-copy .pt svg{width:20px;height:20px;flex:none;stroke-width:1.5;color:var(--gold)}
/* booking form: success confirmation replaces the form — green, centered, icon and text aligned */
.form.done{background:#2f7d54;border-color:transparent;align-items:center;justify-content:center;text-align:center;min-height:150px}
.form-done{display:flex;align-items:center;justify-content:center;gap:12px;color:#fff;font-size:17px;font-weight:600;line-height:1.45}
.form-done svg{width:24px;height:24px;flex:none;stroke-width:2.2;color:#fff}

/* footer */
footer{margin-top:auto;border-top:1px solid var(--line);padding:48px 0 0;color:var(--ink-2);font-size:14px}
footer .in{max-width:var(--maxw);margin:0 auto;display:flex;flex-direction:column;align-items:stretch;gap:48px}
footer .brand{font-size:18px}
footer .cols{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px}
footer .col{display:flex;flex-direction:column;gap:12px}
footer .col b{color:var(--ink);font-weight:600;margin-bottom:4px}
footer .col a:hover{color:var(--sienna)}
footer .bottom{display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:24px}

/* scroll snap — one section per viewport */
.snap{scroll-snap-align:start;scroll-snap-stop:always;height:100vh;height:100dvh;overflow:hidden;display:flex;flex-direction:column;justify-content:center;padding-bottom:var(--sec)}
.snap > .inner{width:100%} /* flex-column child with auto margins would otherwise shrink-wrap */
#book{justify-content:flex-start;padding-bottom:32px}
#book .inner{margin:auto 0;width:100%}
.deliv-media{align-self:stretch;min-height:360px;height:auto}
.proof .big{height:52vh}

/* reveal motion (subtle, respects reduced-motion) */
/* fail-open: only hide reveal content when JS is confirmed (html.js set by a head bootstrap).
   Without JS the content shows normally — a CDN/script failure or no-JS agent never gets a blank page. */
.js .reveal{opacity:0;transform:translateY(12px);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;scroll-snap-type:none}
  .reveal{opacity:1!important;transform:none!important;transition:none!important}
  *{transition:none!important;animation:none!important}
}

@media (max-width:1100px){nav{gap:24px;font-size:14px}}
@media (max-width:960px){
  nav,.desktop-cta{display:none}.menu{display:inline-flex}
  .deliv-grid,.form-grid{grid-template-columns:minmax(0,1fr);gap:40px}.deliv-media{display:none}
  footer .cols{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
  :root{--pad:20px;--sec:56px;--h2:32px;--h1:38px;--nav-h:64px}
  .brand{font-size:18px}
  .hero{height:100vh;height:100dvh;min-height:0}
  .benefit{height:100vh;height:100dvh;min-height:0}
  .tags{display:none}  /* panel 03 callouts have no room beside the copy on a phone */
  /* portrait crop anchor lives in the aspect-ratio rules above (generated by tools/fit_hero_screen.py) */
  .hero-tag{top:calc(var(--nav-h) + 10px);font-size:clamp(19px,5.4vw,24px)} /* the wall strip between header and screen edge */
  h1{font-size:var(--h1)}
  .lede{font-size:16px}
  .ctas{flex-direction:column}.btn{width:100%}
  .snap{height:100vh;height:100dvh;padding-bottom:32px;overflow-y:auto}
  .pillars{grid-template-columns:1fr;gap:12px}.pillar{padding:24px}
  .pricing{grid-template-columns:1fr;padding:32px 24px;gap:28px}.row{font-size:16px}
  .proof{grid-template-columns:1fr}.proof .big{height:34svh}.proof .stack{flex-direction:row;height:110px}
  .immersion{padding:40px var(--pad);height:100dvh}.player{min-height:0}
  .controls{left:16px;right:16px;bottom:16px}.chrome .lbl{display:none}.sw{width:30px;height:30px}
  .form{padding:24px}.two{grid-template-columns:1fr}
  footer .cols{grid-template-columns:1fr 1fr}
}


/* ---- SQUARISH & PORTRAIT (windows narrower than 4:3: phones, tablets either way, a narrowed desktop window) ----
   Benefit panels: nothing is cropped — every picture becomes a full-width BAND in normal flow with the copy beneath.
   HERO: ONE screen-forward design for the whole range (so there is no odd third look between portrait and desktop):
   a flex column, top to bottom — the screen band, the control row, the copy (pushed to the bottom by an auto margin).
   hero-pano.js places the photo so its screen fills the band exactly (--fit:screen); the photo spills out of the band
   and is the backdrop for the rest of the hero, with a legibility wash under the copy. The band is as tall as the
   larger of "screen at full viewport width" and "photo reaching the hero's bottom edge" (--cover-frac, a ratio of the
   served master's geometry); when a viewport is too short for band + row + copy, the band shrinks (flex) — never the
   row or the copy — so nothing overlaps on any device or browser chrome. The ≤ 1:1 block below only swaps in the
   portrait master's ratios and compacts the type. */
@media (max-aspect-ratio:4/3){
  .benefit{height:auto;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;
    padding:calc(var(--nav-h) + 12px) var(--pad) 28px}
  /* every dvh declaration has a vh twin first: Safari < 15.4 has no dvh, and a custom property holding dvh would
     invalidate its consumer rather than fall back — so --wash-solid is upgraded under @supports instead */
  .hero{--screen-ar:1.5270;--cover-frac:.6763;   /* landscape master (GEOMETRY['hero.jpg']): screen box 820×537; 537 / (864 − 70) */
    --band-top:calc(var(--nav-h) + 8px);--wash-solid:12vh;
    display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;height:100vh;height:100dvh;min-height:560px;
    padding:var(--band-top) 0 max(5vh,26px);padding:var(--band-top) 0 max(5dvh,26px);overflow:hidden}
  @supports (height:1dvh){ .hero{--wash-solid:12dvh} }
  .hero-media{--fit:screen;position:relative;inset:auto;order:1;flex:0 1 auto;min-height:0;align-self:center;
    height:max(calc(100vw / var(--screen-ar)),calc((100vh - var(--band-top)) * var(--cover-frac)));
    height:max(calc(100vw / var(--screen-ar)),calc((100dvh - var(--band-top)) * var(--cover-frac)));
    width:auto;max-width:none;aspect-ratio:var(--screen-ar);background:none;overflow:visible;border-radius:0}
  .hero-media::after{display:none}
  .hero-stage{z-index:2}
  /* legibility wash over the lower backdrop. The photo reaches the hero's bottom edge in the normal case (the band's
     cover term above); the wash's solid foot only matters when a short viewport shrank the band and the photo ends early */
  .hero::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:1;height:34vh;height:34dvh;pointer-events:none;
    background:linear-gradient(0deg,var(--ivory) 0,var(--ivory) calc(var(--wash-solid) * .5),rgba(247,244,237,.86) var(--wash-solid),rgba(247,244,237,.7) 40%,rgba(247,244,237,.26) 70%,rgba(247,244,237,0) 100%)}
  .guide.at-hero{opacity:0;pointer-events:none;transition:opacity .3s}   /* section pills hide over the hero here; they show on the other panels */
  /* the drag hint shows — over the screen's lower centre (screen box published by hero-pano.js) */
  .vs-hint{display:block;left:calc(var(--scr-ls,50%) + var(--scr-ws,0px) / 2);top:calc(var(--scr-bs,60%) - var(--scr-hs,0px) / 2);
    transform:translate(-50%,-50%);font-size:10px;letter-spacing:.14em;padding:.5em .9em}
  /* the desktop column becomes a clean LEFT-aligned row under the band (clears the person on the right);
     touch-target sizes in px here (the photo em is too small on phones), single-sourced in --ctl* */
  .vs-panel{--ctl:44px;--ctl-pad:6px;
    order:2;position:relative;inset:auto;z-index:3;flex:none;width:auto;margin:12px var(--pad) 0;font-size:14px;
    display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;gap:10px;pointer-events:auto}
  .vs-group{width:auto;height:auto;flex-direction:row;gap:var(--ctl-pad);padding:var(--ctl-pad)}
  .vs-radio{width:var(--ctl);height:var(--ctl)}
  .vs-radio::after{content:none}   /* no labels in the row layouts */
  .hero .pano-fs{width:calc(var(--ctl) + 2 * var(--ctl-pad) - 2px);height:calc(var(--ctl) + 2 * var(--ctl-pad) - 2px)}   /* matches the pills' height */
  .hero .pano-fs svg{width:22px;height:22px}
  /* copy at the bottom, left part of the band; the person (baked into the master) sits on the right */
  .hero-copy{order:3;position:relative;inset:auto;z-index:3;flex:none;margin:auto var(--pad) 0;padding-top:16px;max-width:min(72%,460px)}
  .hero-copy h1{font-size:clamp(25px,4.6vw,46px)}
  .hero-copy .lede{font-size:clamp(13px,1.7vw,17px);margin-top:9px}
  .b-media{position:relative;inset:auto;width:min(100%,calc(58svh * 16 / 9));aspect-ratio:16/9;border-radius:0}
  .b-media img.tight{transform:none;object-position:50% 50%}
  .b-media::after{display:none}
  .b-copy,.benefit.copy-mid .b-copy{position:static;max-width:none;margin-top:22px;z-index:auto;top:auto;bottom:auto}
  .b-copy h2{font-size:clamp(28px,6.6vw,44px)}
  .b-copy p{font-size:clamp(15px,3.8vw,17px);margin-top:12px;max-width:60ch}
}
@media (max-aspect-ratio:4/3) and (max-width:760px){ .benefit{padding-top:calc(var(--nav-h) + 12px)} }
/* PORTRAIT (≤ 1:1 — phones and tablets held upright): the <picture> serves the 4:5 portrait master, so the hero's
   band takes that master's screen ratios; the layout itself is the screen-forward column from the block above. */
@media (max-aspect-ratio:1/1){
  .hero{--screen-ar:1.1379;--cover-frac:.5516}   /* portrait master (GEOMETRY['hero-portrait.jpg']): screen box 858×754; 754 / (1672 − 305) */
  .hero-copy{max-width:min(72%,350px)}
  .hero-copy h1{font-size:clamp(25px,6.6vw,38px)}
  .hero-copy .lede{font-size:clamp(13px,3.4vw,15px)}
  .b-media{aspect-ratio:4/5;width:min(100%,calc(62svh * 4 / 5))}
  .tags{display:none}
  /* panel 03: full-bleed TALL portrait master + its own portrait-placed callouts, which cover-fit with the image
     (slice) so every dot tracks its part. Shorter wash keeps the floor-row labels clear. Only enabled here, where
     the portrait master is actually served — the squarish range shows the landscape image with no callouts. */
  #b3 .b-media img{object-fit:cover;object-position:50% 50%}
  #b3 .b-media::after{height:38dvh}
  #b3 .tags{display:block;position:absolute;inset:0;z-index:1}
  #b3 .cLand{display:none}
  #b3 .cPort{display:block}
}
/* Narrow/portrait: benefit panels stay FULL-BLEED with the copy overlaid at the bottom over a
   full-width wash for legibility (only the hero uses the stacked layout above; booking panel untouched). */
@media (max-aspect-ratio:4/3){
  .benefit{display:block;height:100vh;height:100dvh;min-height:560px;padding:0;justify-content:initial;align-items:initial}
  .benefit .b-media{position:absolute;inset:0;width:auto;height:auto;aspect-ratio:auto;border-radius:0}
  .benefit .b-media::after{content:"";display:block;left:0;right:0;top:auto;bottom:0;width:100%;height:58dvh;
    background:linear-gradient(0deg,rgba(247,244,237,.97) 0%,rgba(247,244,237,.92) 24%,rgba(247,244,237,.55) 56%,rgba(247,244,237,0) 100%);
    -webkit-mask-image:none;mask-image:none}
  .benefit .b-copy,.benefit.copy-mid .b-copy{position:absolute;left:var(--pad);right:var(--pad);top:auto;bottom:max(6dvh,34px);max-width:none;margin-top:0;z-index:1}
  .benefit .b-copy p{max-width:none}
  /* compare panel: keep the finish divider within the cabinet band, clear of the copy at the bottom */
  .compare .cmp-bar{top:26dvh;bottom:24dvh}
  /* full-bleed panels show no leader callouts (they're placed for the desktop landscape frame). Panel 03's
     portrait callouts are enabled only in the PORTRAIT block below, where its tall portrait master is served. */
  .tags{display:none}
}
/* touch devices: the thumb scrolls, the section dots only collide with content */
/* touch devices keep the scroll pills now (hidden only over the hero in portrait, via .at-hero above) */
/* mobile keeps the firm `y mandatory` snap (from the base html rule) — proximity felt non-existent */
/* very short landscape windows (a phone on its side): stop snapping, let sections take the height they need */
@media (max-height:640px){
  html{scroll-snap-type:none}
  .hero,.benefit,.snap{height:auto;min-height:100vh;min-height:100dvh}
}

/* ---- inner pages (about / how-it-works / pricing / projects / faq) ---- */
/* Document-style pages: normal scroll (no mandatory snap), content clears the fixed header. */
html.subpage{scroll-snap-type:none}
html.subpage body{padding-top:var(--nav-h)}
.page{padding-top:56px;padding-bottom:104px}
.page-head{display:flex;flex-direction:column;gap:18px;max-width:720px;margin-bottom:56px}
.page-head h1{font-size:clamp(40px,5vw,64px);line-height:1.02;font-weight:var(--hw);letter-spacing:-.035em}
.page-head h1 em{font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-style:italic;font-weight:400;font-size:1.04em;letter-spacing:0;color:var(--sienna)}
.page-head .sub{font-size:var(--lede);max-width:640px}
nav a.on{color:var(--sienna)}
@media (max-width:760px){ html.subpage body{padding-top:var(--nav-h)} .page{padding-top:32px;padding-bottom:72px} .page-head{margin-bottom:36px} }

/* image loading indicator: a small spinner shows until an image has painted (helps slow connections) */
.media.loading::before,.pano360.loading::before{content:"";position:absolute;top:50%;left:50%;width:26px;height:26px;margin:-13px 0 0 -13px;border-radius:50%;border:2.5px solid rgba(150,150,150,.35);border-top-color:var(--gold);animation:img-spin .7s linear infinite;pointer-events:none}
@keyframes img-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.media.loading::before,.pano360.loading::before{animation:none;opacity:.7}}
/* honeypot: off-screen anti-spam field on the booking form; never shown to real users */
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;opacity:0;pointer-events:none}
/* hero panorama: expand-to-fullscreen button — last member of the .vs-panel glass family (desktop: under the
   lighting pill in the column, em-sized like the radios; squarish/portrait: px-sized in the row, see the media
   blocks above) + the immersive fullscreen overlay */
.pano-fs{flex:none;width:3.4em;height:3.4em;border-radius:50%;border:.08em solid rgba(255,255,255,.42);padding:0;cursor:pointer;pointer-events:auto;color:#fff;
  display:flex;align-items:center;justify-content:center;background:rgba(28,20,14,.42);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.pano-fs:hover{background:rgba(28,20,14,.6)}
.pano-fs svg{width:42%;height:42%}
/* hero expand -> immersive full-viewport overlay (Pannellum mounts into .pano-ov-mount) */
.pano-ov{position:fixed;inset:0;z-index:400;background:#0f0f0e}
.pano-ov-mount{position:absolute;inset:0}
.pano-close{position:absolute;top:16px;right:16px;z-index:5;width:46px;height:46px;border-radius:50%;border:0;cursor:pointer;color:#fff;
  display:flex;align-items:center;justify-content:center;background:rgba(15,15,14,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.pano-close svg{width:24px;height:24px}
/* projects-page inline viewer: Pannellum mounts into .pano-embed, over the static <img> fallback */
.pano-embed{position:absolute;inset:0;z-index:1}
.pano360 .pano-fallback{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.pnlm-container{background:transparent!important}
/* keep the projects-page time controls + hint above the mounted viewer */
.pano360 .pano-ctl,.pano360 .pano-hint{z-index:2}
/* its glass expand button (added by pano.js) sits bottom-right; the time-of-day row stops short of it */
.pano360 .pano-fs{position:absolute;right:16px;bottom:16px;z-index:3;width:48px;height:48px}
.pano360 .pano-fs svg{width:22px;height:22px}
.pano360 .pano-ctl{right:76px}
/* narrow viewers: the time-of-day row needs the full width, so the expand button moves to the top-right corner
   (the drag hint is top-left) instead of colliding with the last pill */
@media (max-width:640px){
  .pano360 .pano-fs{top:16px;bottom:auto}
  .pano360 .pano-ctl{right:16px}
}
/* native fullscreen of the whole block (pills + expand button stay usable) */
.pano360:fullscreen{width:100vw;height:100vh;border-radius:0}
.pano360:-webkit-full-screen{width:100vw;height:100vh;border-radius:0}
