/* One continuous warm ground. Sections separate by rhythm, rule and photography,
   not by alternating fills. Two exceptions: the teal facts strip and the footer. */
:root{
  --base:#FFFFFF; --surface:#FFFFFF; --soft:#F5F3EE; --sunk:#EAE7E0;
  --line:#E3DED5; --line-2:#CFC9BE;
  --scrim:255,255,255;              /* hero wash, flips with the theme */
  --stamp-bg:rgba(255,255,255,.88);
  --btn-bg:#343835; --btn-fg:#FFFFFF;
  --facts-bg:#0C7373; --facts-fg:#FFFFFF; --facts-sub:#BFE2E2;
  --ink:#343835; --muted:#5E6361; --char:#474D49;
  --teal:#159E9E; --teal-ink:#0C7373; --teal-lift:#4FC9C9; --teal-soft:#E2F1F1;
  --wood:#A97C4E;
  --util-bg:rgba(21,158,158,.07); --util-rule:rgba(21,158,158,.35);    /* teal, very dilute */
  --disp:'Fjalla One',Impact,'Arial Narrow',sans-serif;
  --body:'Lato',system-ui,-apple-system,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --gut:clamp(16px,4vw,56px); --max:1400px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --base:#171918; --surface:#1F2221; --soft:#1C1F1E; --sunk:#262a29; --line:#323736; --line-2:#434947;
  --ink:#EAE7E1; --muted:#9DA29F; --char:#101211; --teal-ink:#4FC9C9; --teal-soft:#13302F; --wood:#C79A6B;
  --util-bg:rgba(79,201,201,.09); --util-rule:rgba(79,201,201,.32);
  --scrim:20,22,21;
  --stamp-bg:rgba(20,22,21,.84);
  --btn-bg:#EAE7E1; --btn-fg:#171918;
  --facts-bg:#0B5F5F; --facts-fg:#FFFFFF; --facts-sub:#A9D6D6;
  color-scheme:dark;
}}
:root[data-theme="dark"]{
  --base:#171918; --surface:#1F2221; --soft:#1C1F1E; --sunk:#262a29; --line:#323736; --line-2:#434947;
  --ink:#EAE7E1; --muted:#9DA29F; --char:#101211; --teal-ink:#4FC9C9; --teal-soft:#13302F; --wood:#C79A6B;
  --util-bg:rgba(79,201,201,.09); --util-rule:rgba(79,201,201,.32);
  --scrim:20,22,21;
  --stamp-bg:rgba(20,22,21,.84);
  --btn-bg:#EAE7E1; --btn-fg:#171918;
  --facts-bg:#0B5F5F; --facts-fg:#FFFFFF; --facts-sub:#A9D6D6;
  color-scheme:dark;
}
*{box-sizing:border-box}
/* overflow-x:hidden on html or body turns it into a scroll container, which
   silently kills position:sticky on every descendant. That is why the sticky
   header was not sticking. `clip` does the same job without creating the
   scroll container; `hidden` stays first as the fallback for older Safari. */
html,body{max-width:100%;overflow-x:hidden;overflow-x:clip}
body{margin:0;background:var(--base);color:var(--ink);font-family:var(--body);line-height:1.6;-webkit-text-size-adjust:100%}
h1,h2,h3{margin:0;font-family:var(--disp);font-weight:400;line-height:1.04;text-wrap:balance;text-transform:uppercase;letter-spacing:.005em}
p{margin:0}
img{max-width:100%}
.band{width:100%}
.in{width:100%;max-width:var(--max);margin:0 auto;
  padding-left:max(var(--gut),env(safe-area-inset-left,0px));
  padding-right:max(var(--gut),env(safe-area-inset-right,0px))}
.sec>.in{padding-block:clamp(48px,6.5vw,88px)}
.sec--tight>.in{padding-block:clamp(36px,4.5vw,60px)}
/* The header band already carries 48px of its own bottom padding. Stacking a
   full section's top padding under it put 154px of nothing between the lede
   and the first line of content. */
.pagehead+.sec>.in{padding-top:clamp(30px,3.2vw,46px)}
.ruled{border-top:1px solid var(--line)}
/* The header is sticky, so an in-page anchor used to land with its target
   hidden underneath it. Applies to every id, which is what the footer's
   room links, #quote and /finishes/#samples all need. */
[id]{scroll-margin-top:clamp(74px,9vw,100px)}
/* <picture> wraps the images so a webp can be offered with a jpg fallback.
   display:contents takes the wrapper out of layout entirely, so every grid,
   flex and aspect-ratio rule written against the img keeps working exactly as
   it did when the img was a direct child. */
picture{display:contents}
.eyebrow{font-family:var(--body);font-size:.72rem;font-weight:900;letter-spacing:.15em;text-transform:uppercase;color:var(--teal-ink)}
h2.big{font-size:clamp(1.9rem,4vw,2.9rem);margin-top:10px}
.lede{color:var(--muted);max-width:58ch;margin-top:12px}
.card{background:var(--surface);border:1px solid var(--line-2);padding:clamp(20px,2.6vw,30px);min-width:0}

/* header */
/* utility bar: see the block at the end of this file */
.hdr{background:var(--surface);border-bottom:1px solid var(--line-2);position:sticky;top:env(safe-area-inset-top,0px);z-index:20}
.hdr .in{display:flex;gap:clamp(16px,2.6vw,40px);align-items:center;padding-block:clamp(12px,1.6vw,18px)}
.logo{display:flex;align-items:center;gap:11px;text-decoration:none;flex:none}
.logo svg{width:38px;height:38px;flex:none}
.logo__wm{display:flex;flex-direction:column;line-height:.92}
.logo__a{font-family:var(--disp);font-size:clamp(1.1rem,1.7vw,1.38rem);color:var(--ink)}
.logo__b{font-family:var(--body);font-size:.6rem;font-weight:700;letter-spacing:.19em;color:var(--muted);text-transform:uppercase;margin-top:4px}
.nav{display:flex;gap:clamp(14px,1.9vw,28px);font-size:.92rem;font-weight:700;margin-left:clamp(8px,2vw,28px)}
.nav a{text-decoration:none;color:var(--ink);padding-block:5px;border-bottom:2px solid transparent}
.nav a:hover{border-bottom-color:var(--teal)}
.hdr .sp{margin-left:auto;display:flex;gap:clamp(10px,1.6vw,20px);align-items:center}
.tel{text-decoration:none;display:flex;flex-direction:column;line-height:1;text-align:right}
.tel small{font-size:.65rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.tel b{font-family:var(--disp);font-size:clamp(1.05rem,1.6vw,1.3rem);color:var(--ink);margin-top:3px}
.tel:hover b{color:var(--teal-ink)}
.btn{display:inline-block;font-weight:700;font-size:.88rem;padding:11px 18px;border-radius:4px;text-decoration:none;
  border:2px solid transparent;white-space:nowrap;cursor:pointer;font-family:var(--body);
  transition:background-color .13s,border-color .13s,color .13s}
.btn--ink{background:var(--btn-bg);color:var(--btn-fg);border-color:var(--btn-bg)}
.btn--ink:hover{background:var(--teal-ink);border-color:var(--teal-ink);color:var(--base)}
.btn--teal{background:transparent;color:var(--teal-ink);border-color:var(--teal)}
.btn--teal:hover{background:var(--teal-soft)}
.navlink{font-weight:700;font-size:.88rem;text-decoration:none;color:var(--ink);border-bottom:2px solid var(--teal);padding-bottom:2px;white-space:nowrap}
@media(max-width:1000px){.nav{display:none}}
@media(max-width:620px){.tel{display:none}.logo__b{display:none}}

/* hero */
.hero{position:relative;background:var(--soft);isolation:isolate}
.hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:68% 48%;z-index:-2}
/* Shaped wash: hugs the copy column hard, then releases fast so the room still reads.
   Paired with the text halo below, which does the rest of the contrast work. */
.hero::after{content:"";position:absolute;inset:0;z-index:-1;background:
  radial-gradient(72% 85% at 14% 50%,
    rgba(var(--scrim),.95) 0%,rgba(var(--scrim),.90) 34%,rgba(var(--scrim),.62) 50%,
    rgba(var(--scrim),.20) 66%,rgba(var(--scrim),0) 80%),
  linear-gradient(180deg,rgba(var(--scrim),.20) 0%,rgba(var(--scrim),0) 28%)}
.hero .in{padding-block:clamp(60px,9.5vw,136px)}
.hero__copy{max-width:min(540px,46%)}
@media(max-width:900px){
  .hero::after{background:linear-gradient(180deg,rgba(var(--scrim),0) 0%,rgba(var(--scrim),.30) 26%,rgba(var(--scrim),.90) 52%,rgba(var(--scrim),.99) 66%)}
  .hero .in{padding-block:clamp(190px,44vw,300px) clamp(30px,6vw,44px)}
  .hero__copy{max-width:none}
}
.stamp{display:inline-flex;align-items:center;gap:8px;border:2px solid var(--teal);color:var(--teal-ink);
  font-family:var(--disp);font-size:.82rem;letter-spacing:.05em;text-transform:uppercase;padding:5px 12px;background:var(--stamp-bg)}
.hero h1{font-size:clamp(2.5rem,6.2vw,5rem);margin:18px 0 0;max-width:13ch}
.hero h1 em{font-style:normal;color:var(--teal-ink)}
.hero__sub{margin-top:16px;max-width:44ch;font-size:clamp(1rem,1.3vw,1.12rem);color:var(--muted)}
.hero__cta{display:flex;gap:10px;margin-top:28px;flex-wrap:wrap}

/* the one accent band */
.facts{background:var(--facts-bg);color:var(--facts-sub)}
.facts .in{display:flex;gap:clamp(20px,4vw,64px);padding-block:clamp(16px,2vw,22px);flex-wrap:wrap;align-items:baseline}
.fact{display:flex;align-items:baseline;gap:9px;min-width:0}
.fact b{font-family:var(--disp);font-size:clamp(1.35rem,2.3vw,1.9rem);color:var(--facts-fg);line-height:1}
.fact span{font-size:.84rem;color:var(--facts-sub)}

/* why */
.why{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:clamp(20px,3vw,40px);margin-top:30px}
.why b{display:block;font-family:var(--disp);font-size:1.18rem}
.why b i{font-style:normal;color:var(--teal-ink)}
.why p{margin-top:6px;font-size:.93rem;color:var(--muted)}

/* rooms */
.rooms{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:14px;margin-top:30px;list-style:none;padding:0}
.rooms li{min-width:0;border-top:3px solid var(--teal);padding-top:14px}
.rooms b{display:block;font-family:var(--disp);font-size:1.22rem}
.rooms span{display:block;margin-top:6px;font-size:.9rem;color:var(--muted)}
.rooms em{display:block;margin-top:8px;font-style:normal;font-size:.78rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}

/* finish picker */
.pickrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,440px);gap:clamp(24px,3.4vw,52px);margin-top:30px;align-items:start}
@media(max-width:900px){.pickrow{grid-template-columns:1fr}}
.doors{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:10px;list-style:none;padding:0;margin:0}
/* On a phone the swatches were 420px tall each, so the preview they control
   sat about a thousand pixels further down the page. You tapped a finish and
   nothing appeared to happen. Short, wide chips keep the swatch and the room
   it produces on the same screen. */
@media(max-width:700px){
  .doors{grid-template-columns:repeat(auto-fit,minmax(94px,1fr));gap:8px}
  .doors button{display:flex;align-items:center;gap:0;flex-direction:column}
  .doors img{aspect-ratio:3/2;height:52px;width:100%}
  .doors .lbl{padding:6px 7px;width:100%}
  .doors .lbl b{font-size:.8rem}
  .doors .lbl span{font-size:.58rem;white-space:nowrap}
}
.doors button{display:block;width:100%;padding:0;border:2px solid var(--line-2);background:var(--surface);cursor:pointer;
  font:inherit;color:inherit;text-align:left;transition:border-color .13s}
.doors button:hover{border-color:var(--line-2)}
.doors button[aria-pressed="true"]{border-color:var(--teal);box-shadow:inset 0 0 0 1px var(--teal)}
.doors img{display:block;width:100%;aspect-ratio:1;object-fit:cover}
.doors .lbl{display:block;padding:8px 9px}
.doors .lbl b{display:block;font-family:var(--disp);font-size:.92rem;line-height:1.1}
.doors .lbl span{font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.preview{background:var(--surface);border:1px solid var(--line-2);overflow:hidden}
.preview img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--soft)}
.preview .pv{padding:clamp(16px,2vw,22px)}
.preview h3{font-size:1.5rem}
.preview .tier{display:inline-block;margin-top:8px;font-size:.72rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;
  color:var(--teal-ink);border:1px solid var(--teal);padding:3px 9px}
.preview p{margin-top:12px;font-size:.93rem;color:var(--muted)}
.preview .sides{margin-top:10px;font-size:.86rem;color:var(--wood);font-weight:700}

/* full-bleed photo break */
.breakshot{position:relative}
.breakshot img{display:block;width:100%;aspect-ratio:21/9;object-fit:cover;background:var(--soft)}
@media(max-width:700px){.breakshot img{aspect-ratio:4/3}}
.breakshot figcaption{position:absolute;left:0;right:0;bottom:0;padding:clamp(14px,2vw,22px) max(var(--gut),env(safe-area-inset-left,0px));
  background:linear-gradient(0deg,rgba(26,29,27,.86),rgba(26,29,27,0));color:#F2F0EB;font-size:.9rem}
.breakshot figcaption b{font-family:var(--disp);font-size:1.1rem;display:block}

/* testimonial */
.quote-block{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,560px);gap:clamp(24px,3.4vw,52px);align-items:center}
@media(max-width:900px){.quote-block{grid-template-columns:1fr}}
.quote-block blockquote{margin:0;font-family:var(--disp);font-size:clamp(1.3rem,2.4vw,1.9rem);line-height:1.22;text-transform:none}
.quote-block cite{display:block;margin-top:14px;font-style:normal;font-size:.84rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}

/* ---- before and after -----------------------------------------------------
   The two photographs are 268x201. They came in as one 612x418 slide with the
   labels and the supplier credit typed onto the canvas, shown at 796px, so a
   small picture was being upscaled and the baked-in typography was fighting
   the page.

   Split, they are shown at their own size and never larger, which is the only
   honest option until there are higher resolution originals. The labels are
   the site's own type now and the credit is a caption. */
.ba{margin:0}
.ba__pair{display:grid;grid-template-columns:repeat(2,minmax(0,268px));gap:clamp(10px,1.4vw,18px);justify-content:start}
.ba__one{min-width:0}
.ba__one img{display:block;width:100%;height:auto;border:1px solid var(--line-2);background:var(--surface)}
.ba__one b{display:block;margin-top:8px;font-family:var(--body);font-size:.72rem;font-weight:900;
  letter-spacing:.15em;text-transform:uppercase;color:var(--muted)}
.ba figcaption{margin-top:14px;font-size:.78rem;color:var(--muted);font-style:italic}
@media(max-width:420px){
  .ba__pair{grid-template-columns:repeat(2,minmax(0,1fr))}
}
.quote-block>picture img{display:block;width:100%;border:1px solid var(--line)}

/* flat pack vs assembled */
.picks{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:16px;margin-top:28px}
.pcard{min-width:0;border:1px solid var(--line-2);background:var(--surface);padding:clamp(20px,2.5vw,28px);display:flex;flex-direction:column}
.pcard--rec{border-color:var(--teal);box-shadow:inset 0 0 0 1px var(--teal)}
.ptag{font-size:.7rem;font-weight:900;letter-spacing:.13em;text-transform:uppercase;color:var(--teal-ink)}
.pcard h3{font-size:1.4rem;margin-top:7px}
.pbest{margin-top:10px;font-size:.93rem;font-weight:700}
.plist{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:10px}
.plist li{display:grid;grid-template-columns:16px minmax(0,1fr);gap:11px;font-size:.9rem;color:var(--muted);align-items:start}
.plist svg{width:16px;height:16px;margin-top:4px;flex:none}
.plist .y{color:var(--teal-ink)} .plist .n{color:var(--wood)}
.pfoot{margin-top:auto;padding-top:18px;font-size:.84rem;color:var(--muted);border-top:1px solid var(--line)}
.tbd{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--wood);
  border:1px dashed var(--wood);border-radius:3px;padding:1px 6px;margin-left:6px;white-space:nowrap}
.pnote{margin-top:22px;font-size:.92rem;color:var(--muted);max-width:64ch}
.pnote b{color:var(--ink)}

/* two-up: quote tool + radius */
.twoup{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:clamp(20px,2.6vw,34px);margin-top:30px;
  /* Cards carry very different amounts of content: the itemised price is
     long, the ZIP checker is three lines. Stretching the short one leaves a
     tall empty box that reads as a loading error. Each sizes to itself. */
  align-items:start}
.qtog{display:flex;border:1px solid var(--line);border-radius:4px;overflow:hidden;margin-bottom:16px}
.qtog span{flex:1;text-align:center;padding:8px 6px;font-size:.82rem;font-weight:700;color:var(--muted);min-width:0}
.qtog span.on{background:var(--btn-bg);color:var(--btn-fg)}
.qsw{display:flex;gap:7px;margin-bottom:16px}
.qsw i{width:30px;height:30px;border:1px solid var(--line);border-radius:3px;flex:none}
.qsw i.on{box-shadow:0 0 0 2px var(--teal)}
.qr{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line);font-size:.9rem}
.qr:last-of-type{border-bottom:0}
.qr span:last-child{font-variant-numeric:tabular-nums;font-weight:700;white-space:nowrap}
/* The block showed a March 2025 price book to the cent, which reads as a live
   quote. The line items stay because they show the shape of what comes back;
   the figures are gone until the real calculator has a current price book.
   These two classes keep the placeholders from looking like numbers. */
.qr__p{font-weight:400!important;font-style:italic;color:var(--muted)}
.qt__ask{font-size:1.15rem!important;letter-spacing:0}
.qt{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-top:14px;padding-top:14px;border-top:2px solid var(--ink)}
.qt b{font-family:var(--disp);font-size:clamp(1.9rem,3.6vw,2.4rem);font-variant-numeric:tabular-nums;line-height:1}
.radbox label{display:block;font-size:.7rem;font-weight:900;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.radform{display:flex;gap:9px;margin-top:9px;flex-wrap:wrap}
.radform input{flex:1 1 140px;min-width:0;font:inherit;font-size:1.1rem;font-weight:700;padding:12px 13px;border:2px solid var(--line);
  border-radius:4px;background:var(--base);color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:.06em}
.radform input:focus-visible{outline:none;border-color:var(--teal)}
.radform button{font:inherit;font-weight:700;font-size:.9rem;padding:12px 18px;border:2px solid var(--ink);border-radius:4px;
  background:var(--btn-bg);color:var(--btn-fg);cursor:pointer;white-space:nowrap}
.radform button:hover{background:var(--teal-ink);border-color:var(--teal-ink);color:var(--base)}
.radout{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
.radout[hidden]{display:none}
.radhead{display:flex;align-items:center;gap:9px;font-family:var(--disp);font-size:1.2rem}
.radhead svg{width:21px;height:21px;flex:none}
.radhead.ok{color:#2F6B4F} .radhead.no{color:var(--wood)} .radhead.err{color:var(--muted)}
:root[data-theme="dark"] .radhead.ok,:root:not([data-theme="light"]) .radhead.ok{color:#7FBE9C}
.radout p{margin-top:7px;font-size:.92rem;color:var(--muted)}
.radout b{font-variant-numeric:tabular-nums;color:var(--ink)}
.radnote{margin-top:14px;font-size:.84rem;color:var(--muted)}

/* trade */
.tradegrid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:clamp(26px,4vw,60px);align-items:center;margin-top:8px}
@media(max-width:900px){.tradegrid{grid-template-columns:1fr}}
.cred{border-left:3px solid var(--teal);padding:2px 0 2px 20px;margin-top:20px}
.cred b{display:block;font-family:var(--disp);font-size:clamp(1.1rem,1.8vw,1.35rem);line-height:1.2}
.cred span{display:block;margin-top:8px;font-size:.93rem;color:var(--muted);max-width:46ch}
.cred cite{display:block;margin-top:11px;font-style:normal;font-size:.72rem;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--muted)}
.whoLbl{margin-top:22px;font-size:.7rem;font-weight:900;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.who{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px;padding:0;list-style:none}
.who li{background:var(--soft);border:1px solid var(--line);border-radius:999px;padding:6px 13px;font-size:.83rem;font-weight:700}
.tcta{display:flex;gap:12px;flex-wrap:wrap;margin-top:24px;align-items:center}

/* footer */
.ftr{background:var(--char);color:#D7DBD9}
.ftr .in{padding-block:clamp(34px,4.5vw,56px);display:grid;grid-template-columns:repeat(auto-fit,minmax(185px,1fr));gap:26px}
.ftr strong{display:block;font-family:var(--disp);color:var(--base);font-size:1rem;margin-bottom:8px;text-transform:uppercase}
.ftr a{color:var(--teal-lift);text-decoration:none;display:block;padding:2px 0}
.ftr address{font-style:normal;line-height:1.75;font-size:.92rem}
.ph{color:#A6ACA9;font-size:.86rem;line-height:1.55}
.note{font-size:.86rem;color:var(--muted)}
.note .in{padding-block:30px 64px}
.note code{font-family:var(--mono);font-size:.78rem;background:var(--soft);padding:1px 5px;border-radius:3px}
.note p+p{margin-top:10px}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
/* v13 additions */
.util{background:var(--util-bg);border-bottom:1px solid var(--util-rule)}
.hero__sub{font-size:clamp(1.08rem,1.55vw,1.3rem)!important;line-height:1.5;max-width:40ch!important;color:var(--ink)!important;font-weight:400}
.hero__sub b{font-weight:900}
.hero h1{margin-top:22px!important}
.hero__cta{margin-top:32px!important}
.heroline{margin-top:26px;padding-top:20px;border-top:2px solid var(--teal);display:flex;gap:10px;flex-wrap:wrap;align-items:baseline}
.heroline span{font-size:.92rem;font-weight:700;color:var(--muted)}
.heroline b{font-family:var(--disp);font-size:1.05rem;color:var(--ink)}
/* Local contrast lift. The halo is the scrim colour, so it flips with the theme:
   a white glow behind dark text in light mode, a dark one behind light text in dark mode. */
.hero h1,.hero__sub,.heroline b,.heroline span{
  text-shadow:0 1px 2px rgba(var(--scrim),.92),0 0 20px rgba(var(--scrim),.80),0 0 44px rgba(var(--scrim),.55)}
.hero h1{text-shadow:0 1px 2px rgba(var(--scrim),.95),0 0 24px rgba(var(--scrim),.88),0 0 56px rgba(var(--scrim),.62)}

/* room illustrations */
.roomgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px;margin-top:30px;list-style:none;padding:0}
.roomcard{min-width:0;border:1px solid var(--line-2);background:var(--surface);overflow:hidden;display:flex;flex-direction:column}
.roomcard .art{background:var(--soft);border-bottom:1px solid var(--line);aspect-ratio:4/3;overflow:hidden}
.roomcard .art img{display:block;width:100%;height:100%;object-fit:cover}
.art--pending{display:grid;place-items:center;text-align:center;
  background:repeating-linear-gradient(135deg,var(--soft),var(--soft) 11px,var(--sunk) 11px,var(--sunk) 22px)}
.art--pending span{font-family:var(--disp);font-size:1rem;color:var(--muted);background:var(--surface);
  border:1px dashed var(--line-2);padding:10px 16px;line-height:1.35}
.art--pending i{font-style:normal;font-size:.72rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
.roomcard .rb{padding:16px 18px 18px}
.roomcard b{display:block;font-family:var(--disp);font-size:1.22rem}
.roomcard span{display:block;margin-top:6px;font-size:.9rem;color:var(--muted)}
.roomcard em{display:block;margin-top:10px;font-style:normal;font-size:.74rem;font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:var(--teal-ink)}

/* premium features */
.feat{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:clamp(18px,2.4vw,30px);margin-top:30px}
.feat>div{min-width:0;display:grid;grid-template-columns:30px minmax(0,1fr);gap:14px;align-items:start}
.feat>div>div{min-width:0}
.feat svg{width:30px;height:30px;color:var(--teal-ink);margin-top:2px}
.feat b{display:block;font-family:var(--disp);font-size:1.1rem;line-height:1.15}
.feat p{margin-top:5px;font-size:.9rem;color:var(--muted)}
.addons{margin-top:34px;padding-top:24px;border-top:1px solid var(--line)}
.addons h3{font-size:1.1rem}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;padding:0;list-style:none}
.chips li{border:1px solid var(--line-2);border-radius:999px;padding:7px 14px;font-size:.86rem;font-weight:700;background:var(--surface)}

/* ---- finish colour chips --------------------------------------------------
   A chip is a sample of paint, so it has to be judged against something
   neutral and light. These were inline-styled with a themed border, which in
   dark mode put Marine Blue (#152445) and Rustic Hickory (#34201C) against a
   near-black page behind a dark grey border: effectively invisible.

   The mount stays light in both themes. That is not a theming oversight, it
   is the point: a navy door does not look navy on black, and someone choosing
   a kitchen finish from this page has to be able to trust what they see. */
.swatch__row{display:flex;align-items:center;gap:9px;margin-top:11px}
.swatch{
  width:26px;height:26px;flex:none;border-radius:2px;
  background:var(--swatch,#ccc);
  /* White ring first, then a neutral edge, so a pale finish reads against the
     mount and a dark one reads against the page. */
  box-shadow:0 0 0 2px #fff, 0 0 0 3px rgba(0,0,0,.28);
  margin:3px
}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .swatch{box-shadow:0 0 0 2px #f2f2f0, 0 0 0 3px rgba(0,0,0,.55)}
}
:root[data-theme="dark"] .swatch{box-shadow:0 0 0 2px #f2f2f0, 0 0 0 3px rgba(0,0,0,.55)}

/* Same problem, same fix, for the door photographs in the finish picker: a
   stained hickory door on a near-black card loses its edge entirely. */
/* A light mount has to carry its own text colour with it. Setting only the
   background left the finish names rendering in the dark theme's near-white
   ink on a cream label, which is invisible. If a rule flips a surface, it
   flips everything that sits on that surface. */
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .doors button,
  :root:not([data-theme="light"]) .typecard figure{background:#e9e9e6}
  :root:not([data-theme="light"]) .doors .lbl{background:#e9e9e6;color:#23282b}
  :root:not([data-theme="light"]) .doors .lbl b{color:#23282b}
  :root:not([data-theme="light"]) .doors .lbl span{color:#5c6164}
  :root:not([data-theme="light"]) .roomcard .art{background:#e9e9e6}
}
:root[data-theme="dark"] .doors button,
:root[data-theme="dark"] .typecard figure{background:#e9e9e6}
:root[data-theme="dark"] .doors .lbl{background:#e9e9e6;color:#23282b}
:root[data-theme="dark"] .doors .lbl b{color:#23282b}
:root[data-theme="dark"] .doors .lbl span{color:#5c6164}
:root[data-theme="dark"] .roomcard .art{background:#e9e9e6}

/* ---- motion ---------------------------------------------------------------
   Additive, and live only once the script adds .js-motion to <html>, which it
   does not do when the visitor has asked for reduced motion. With JS off, or
   reduced motion on, the page renders exactly as it did before. */
.js-motion .hero{overflow:hidden}
.js-motion .hero img{animation:heroSettle 2600ms cubic-bezier(.16,.84,.44,1) both}
@keyframes heroSettle{from{transform:scale(1.055)}to{transform:scale(1)}}

.js-motion .hero__copy>*{opacity:0;transform:translateY(16px);
  animation:riseIn .72s cubic-bezier(.16,.84,.44,1) both;animation-delay:var(--d,0ms)}
@keyframes riseIn{to{opacity:1;transform:none}}

.js-motion .reveal{opacity:0;transform:translateY(22px)}
.js-motion .reveal.is-in{opacity:1;transform:none;
  transition:opacity .62s ease,transform .62s cubic-bezier(.16,.84,.44,1);
  transition-delay:var(--d,0ms)}

/* hover life */
.roomcard,.picks>.card{transition:transform .22s cubic-bezier(.16,.84,.44,1),border-color .22s,box-shadow .22s}
.roomcard:hover,.picks>.card:hover{transform:translateY(-4px);border-color:var(--teal);
  box-shadow:0 14px 30px -18px rgba(12,115,115,.55)}
.roomcard .art img{transition:transform .5s cubic-bezier(.16,.84,.44,1)}
.roomcard:hover .art img{transform:scale(1.05)}
.doors button{transition:border-color .18s,transform .18s}
.doors button:hover{transform:translateY(-2px)}
.btn{transition:transform .16s,background-color .16s,border-color .16s,color .16s}
.btn:hover{transform:translateY(-1px)}
.fact b{font-variant-numeric:tabular-nums}
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ---- lead blocks ----------------------------------------------------------
   The wrapper a lead form sits in on the homepage. The form's own styling
   comes from the plugin; this only places it on the page. */
.leadblock{margin-top:clamp(34px,4.5vw,56px);padding-top:clamp(28px,3.4vw,40px);
  border-top:2px solid var(--teal)}
.lb-intro{max-width:46ch}
@media(min-width:1000px){
  /* Intro beside the form rather than stacked above it. Stacked, the block was
     900px wide in a row well over 1300px, which left a third of every lead row
     empty and made the whole section read as misaligned. */
  .leadblock{display:grid;grid-template-columns:minmax(260px,.8fr) minmax(0,1.7fr);
    gap:clamp(30px,3.6vw,64px);align-items:start}
  .lb-intro{max-width:none;position:sticky;top:96px}
  .leadblock .acq{margin-top:0}
}
.leadh{font-family:var(--disp);font-weight:400;text-transform:uppercase;
  font-size:clamp(1.45rem,2.6vw,2rem);line-height:1.08;margin:10px 0 0}
.leadblock .lede{margin-top:12px}


/* ---- WordPress wrapper reset ----------------------------------------------
   Core global styles put `margin-block-start` on every direct child of
   .wp-site-blocks, which the standalone comp never had. On this page that
   opens a gap between the hero and the header, and between every band after
   it. The bands are meant to butt up against each other, so clear it.
   On an interior page the bands sit inside .entry-content rather than being
   direct children, so that wrapper needs clearing too: it was carrying the
   32px itself and showing as a white strip under the header.
   Specificity note: core's rule is :root :where(.wp-site-blocks > *), and
   :where() contributes nothing, so a single class here is enough to win. */
.wp-site-blocks > .band,
.wp-site-blocks > .entry-content{margin-block:0}

/* ---- utility bar ----------------------------------------------------------
   Two groups rather than three loose spans. On desktop they sit at opposite
   ends; on mobile they centre and wrap together.

   The old version put margin-left:auto on the last item inside a wrapping
   flex row, so as soon as it wrapped it became an orphan line shoved against
   the right edge. That is what looked wrong on a phone. Alignment is now a
   property of the row, not of one item, so wrapping cannot strand anything. */
.util{background:var(--util-bg);border-bottom:1px solid var(--util-rule)}
.util .in{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:6px clamp(14px,2.4vw,28px);padding-block:8px;
  font-size:.8rem;color:var(--muted)}
.util__set{display:flex;flex-wrap:wrap;align-items:center;gap:6px clamp(14px,2.4vw,24px);margin:0}
.util b{color:var(--ink);font-weight:700}

.u{display:inline-flex;align-items:center;gap:7px;min-width:0}
.u svg{width:15px;height:15px;flex:0 0 auto;color:var(--teal-ink)}
.u > span{min-width:0}

/* Separator between items in the same group, drawn rather than typed so it
   never ends up orphaned at the start of a wrapped line. */
.util__set .u + .u{position:relative;padding-left:clamp(14px,2.4vw,24px)}
.util__set .u + .u::before{content:"";position:absolute;left:0;top:50%;
  transform:translateY(-50%);width:1px;height:13px;background:var(--line-2)}

@media(max-width:760px){
  .util .in{justify-content:center;gap:4px 16px;padding-block:9px}
  .util__set{justify-content:center;gap:4px 16px}
  .util__set--end{width:100%}
  /* At this width the groups stack, so the drawn divider would sit against
     the edge of a line. Space does the separating instead. */
  .util__set .u + .u{padding-left:16px}
  .util__set .u + .u::before{height:11px}
}
@media(max-width:480px){
  /* Narrow enough that the first group wraps too, which would leave the drawn
     divider stranded at the start of a line. Drop it and let each fact take
     its own centred line. */
  .util__set .u + .u{padding-left:0}
  .util__set .u + .u::before{display:none}
  .util .in{font-size:.76rem;gap:3px 14px}
  .util__set{gap:3px 14px}
  .u svg{width:14px;height:14px}
}

/* ---- accessory photographs ------------------------------------------------
   Sits above the chip list in the "things people add" block. The chips name
   everything; these four show the ones people cannot picture from the name. */
.accshots{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:14px;margin:22px 0 26px;list-style:none;padding:0}
.accshots li{min-width:0;border:1px solid var(--line-2);background:var(--surface);overflow:hidden}
.accshots img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;
  border-bottom:1px solid var(--line);transition:transform .5s cubic-bezier(.16,.84,.44,1)}
.accshots li:hover img{transform:scale(1.04)}
.accshots span{display:block;padding:11px 13px;font-size:.86rem;font-weight:700;color:var(--ink)}


/* ---- wide-screen column counts --------------------------------------------
   auto-fit decides the column count from available width, which at 1680 left
   the six feature cards as four plus two, and the six room cards as five plus
   one. Both read as a mistake. Fixed counts above 1040px instead. */
@media(min-width:1040px){
  .feat{grid-template-columns:repeat(3,minmax(0,1fr))}
  .roomgrid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .accshots{grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* Three field columns inside a lead block, not four. Four made a row of very
   short inputs and a textarea wider than any sentence anyone types into it. */
@media(min-width:1000px){
  .leadblock .acq__grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .leadblock .acq__f textarea{max-width:none}
}

/* ===========================================================================
   SITE CHROME AND INNER PAGES
   Everything above this line is the homepage. Everything below is shared, and
   this stylesheet now loads on every template rather than the front page only.
   =========================================================================== */

/* ---- mobile navigation ----------------------------------------------------
   The nav was simply display:none below 1000px. That was survivable when the
   homepage was the only page; with real pages it left a phone with no route
   anywhere except the footer. */
.navtoggle{display:none;align-items:center;gap:8px;margin-left:auto;
  background:none;border:1px solid var(--line-2);border-radius:4px;
  padding:9px 12px;font:inherit;font-size:.82rem;font-weight:700;
  color:var(--ink);cursor:pointer;text-transform:uppercase;letter-spacing:.06em}
.navtoggle svg{width:17px;height:17px}
.navtoggle:hover{border-color:var(--teal)}

@media(max-width:1000px){
  /* The header is one row: logo, then the call-to-action, then the menu
     button. It used to wrap the button onto a second line under the logo,
     which doubled the height of a sticky header on the screen that can
     least afford it. */
  .hdr .in{flex-wrap:wrap;row-gap:0;gap:10px}
  .hdr .sp{order:2;margin-left:auto;gap:10px}
  .navtoggle{display:inline-flex;order:3;margin-left:0}
  .nav{display:none;order:4;width:100%;flex-direction:column;gap:0;margin:0;
    border-top:1px solid var(--line);padding-block:6px}
  .nav.is-open{display:flex}
  .nav a{padding:13px 2px;border-bottom:1px solid var(--line);border-left:3px solid transparent;
    padding-left:10px;font-size:1rem}
  .nav a:last-child{border-bottom:0}
  .nav a:hover{border-bottom-color:var(--line);border-left-color:var(--teal);background:var(--soft)}
}
@media(max-width:560px){
  .hdr .sp .tel{display:none}
  .navtoggle span{display:none}
  .navtoggle{padding:9px 10px}
  /* Logo, call to action and menu button have to share 358px at 390px wide.
     Measured: they came to 370px and the menu button wrapped to a second row,
     which is what doubled the height of the sticky header. Every value below
     is buying back those 12px while keeping a 44px tap target. */
  .hdr .in{padding-block:10px;gap:8px}
  .hdr .sp{gap:8px}
  .hdr .sp .btn{padding:11px 13px;font-size:.82rem;white-space:nowrap}
  .logo{gap:8px}
  .logo svg{width:30px;height:30px}
  .logo__a{font-size:1rem}
}
@media(max-width:420px){
  /* Measured on a real handset at 384px: logo 165 + button 124 + menu 39 +
     gaps still overflowed and dropped the menu onto its own row. */
  .hdr .in{gap:7px}
  .hdr .sp{gap:7px}
  .hdr .sp .btn{padding:10px 11px;font-size:.78rem}
  .logo{gap:7px}
  .logo svg{width:28px;height:28px}
  .logo__a{font-size:.92rem}
  .navtoggle{padding:9px}
}
@media(max-width:340px){
  /* Nothing fits three ways at this width. The mark alone still identifies
     the site and the wordmark is repeated in the footer. */
  .logo__a{display:none}
}

/* ---- inner page header ---------------------------------------------------- */
.pagehead{border-bottom:1px solid var(--line);background:var(--soft)}
.pagehead>.in{padding-block:clamp(28px,3.4vw,48px)}
.crumbs{font-size:.8rem;color:var(--muted);margin:0 0 14px}
.crumbs a{color:var(--muted);text-decoration:none;border-bottom:1px solid var(--line-2)}
.crumbs a:hover{color:var(--teal-ink);border-bottom-color:var(--teal)}
.crumbs span{opacity:.6;padding:0 7px}
.pagehead h1{font-size:clamp(2rem,4.4vw,3.2rem);margin:0}
.pagehead .lede{margin-top:14px;font-size:clamp(1rem,1.3vw,1.14rem)}

/* ---- prose ---------------------------------------------------------------- */
.prose{max-width:74ch}
.prose>*+*{margin-top:1.05em}
.prose h2{font-family:var(--disp);font-weight:400;text-transform:uppercase;
  font-size:clamp(1.4rem,2.5vw,1.95rem);line-height:1.1;margin-top:1.8em}
.prose h3{font-family:var(--disp);font-weight:400;font-size:clamp(1.12rem,1.7vw,1.3rem);
  line-height:1.2;margin-top:1.6em}
.prose p,.prose li{color:var(--char)}
.prose ul,.prose ol{padding-left:1.15em;margin-top:.8em}
.prose li+li{margin-top:.45em}
.prose a{color:var(--teal-ink);text-underline-offset:3px}
.prose strong{color:var(--ink)}
.prose code{font-family:var(--mono);font-size:.9em;background:var(--sunk);padding:1px 5px;border-radius:3px}

/* A short run of text on its own in a wide row reads as a mistake: the line
   length is right but the page is not full. This puts the heading in a label
   column beside the text instead of above it, so the row is used. */
@media(min-width:960px){
  .prose--split{max-width:none;display:grid;
    grid-template-columns:minmax(0,300px) minmax(0,74ch);
    /* Row gap must be 0. The grid gap applies between stacked paragraphs in
       column 2 as well as between the columns, so a 49px row gap landed on
       top of the paragraph's own 1.05em margin and opened a 67px hole
       mid-sentence. The column needs the gutter; the rows already have
       prose rhythm. */
    column-gap:clamp(28px,3.4vw,60px);row-gap:0;align-items:start}
  .prose--split>h2{grid-column:1;grid-row:1;margin-top:0}
  .prose--split>*:not(h2){grid-column:2}
  .prose--split>h2+*{margin-top:0}
}

/* A pull-out for the thing people get wrong. Not a decoration: it is used
   where getting it wrong costs money. */
.warn{border-left:3px solid var(--teal);background:var(--teal-soft);
  padding:16px 18px;margin-top:1.4em;font-size:.95rem}
.warn b{display:block;font-family:var(--disp);font-weight:400;text-transform:uppercase;
  font-size:1.05rem;margin-bottom:6px;color:var(--ink)}

/* ---- spec tables ---------------------------------------------------------- */
.tablewrap{overflow-x:auto;margin-top:1.3em;border:1px solid var(--line-2)}
table.spec{width:100%;border-collapse:collapse;font-size:.9rem;min-width:420px}
table.spec th,table.spec td{text-align:left;padding:10px 13px;border-bottom:1px solid var(--line)}
table.spec thead th{background:var(--soft);font-size:.74rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap}
table.spec tbody tr:last-child td{border-bottom:0}
table.spec td.num,table.spec th.num{font-family:var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
table.spec tbody tr:hover{background:var(--soft)}

/* ---- numbered steps ------------------------------------------------------- */
.steps{list-style:none;padding:0;margin:30px 0 0;counter-reset:s}
.steps>li{counter-increment:s;display:grid;grid-template-columns:46px minmax(0,1fr);
  gap:18px;padding-block:22px;border-top:1px solid var(--line)}
/* The ::before counter occupies column 1. Without this every child after the
   first heading falls back into that 46px column, which is what squeezed the
   step text into a vertical ribbon. Same failure as the feature grid had. */
.steps>li>*{grid-column:2}
.steps>li::before{content:counter(s);font-family:var(--disp);font-size:1.5rem;
  color:var(--teal-ink);line-height:1;padding-top:3px}
.steps h3{margin:0;font-family:var(--disp);font-weight:400;font-size:1.22rem;line-height:1.15}
.steps p{margin-top:7px;color:var(--muted);font-size:.95rem;max-width:66ch}

/* ---- cabinet type cards --------------------------------------------------- */
.types{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:18px;margin-top:30px;list-style:none;padding:0}
.typecard{min-width:0;border:1px solid var(--line-2);background:var(--surface);
  display:flex;flex-direction:column;overflow:hidden}
.typecard figure{margin:0;background:var(--base);border-bottom:1px solid var(--line);
  aspect-ratio:4/3;display:grid;place-items:center;padding:14px}
.typecard img{max-width:100%;max-height:100%;object-fit:contain;mix-blend-mode:multiply}
.typecard .tb{padding:15px 17px 18px;display:flex;flex-direction:column;flex:1}
.typecard b{font-family:var(--disp);font-weight:400;font-size:1.18rem;line-height:1.15}
.typecard .code{font-family:var(--mono);font-size:.78rem;color:var(--teal-ink);margin-top:5px}
.typecard p{margin-top:9px;font-size:.9rem;color:var(--muted);flex:1}
.typecard .dims{margin-top:11px;padding-top:11px;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:.78rem;color:var(--muted)}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .typecard img{mix-blend-mode:normal;filter:invert(1) hue-rotate(180deg)}}
:root[data-theme="dark"] .typecard img{mix-blend-mode:normal;filter:invert(1) hue-rotate(180deg)}

/* ---- two column page body ------------------------------------------------- */
.pagebody{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(28px,3.4vw,56px)}
@media(min-width:1040px){
  .pagebody--aside{grid-template-columns:minmax(0,1fr) minmax(280px,.42fr)}
  .aside{position:sticky;top:104px;align-self:start}
}
.aside .card{font-size:.93rem}
/* A photograph at the top of the sidebar. The interior pages were a column of
   text against an empty right hand side; this is what fills it. */
.asidefig{margin:0 0 18px;border:1px solid var(--line-2);background:var(--surface);overflow:hidden}
.asidefig img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.asidefig figcaption{padding:11px 14px;font-size:.84rem;color:var(--muted);border-top:1px solid var(--line)}
.asidefig figcaption b{display:block;color:var(--ink);font-weight:700;margin-bottom:3px}
/* Below the two column breakpoint the sidebar stacks under the text, where a
   full width 4:3 photograph would be a 750px wall. */
@media(max-width:1039px){
  .asidefig{max-width:460px}
  .asidefig img{aspect-ratio:16/10}
}
.aside .card h3{font-family:var(--disp);font-weight:400;font-size:1.2rem;margin:0 0 10px}
.aside .card p{color:var(--muted)}
.aside .card .btn{margin-top:14px}

/* ---- next steps strip ----------------------------------------------------- */
.nextup{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:16px;margin-top:34px;list-style:none;padding:0}
.nextup a{display:block;height:100%;border:1px solid var(--line-2);background:var(--surface);
  padding:18px 20px;text-decoration:none;transition:border-color .2s,transform .2s}
.nextup a:hover{border-color:var(--teal);transform:translateY(-3px)}
/* When the strip is the whole section it does not also need a 34px lead-in on
   top of the section's own padding. */
.sec>.in>.nextup:only-child{margin-top:0}
.nextup b{display:block;font-family:var(--disp);font-weight:400;font-size:1.12rem;color:var(--ink)}
.nextup span{display:block;margin-top:6px;font-size:.88rem;color:var(--muted)}

/* ---- interior page measure -------------------------------------------------
   The 1680 container is right for the homepage, where every row is a grid of
   cards. It is wrong for a text page: it left the prose column capped at 68ch
   with a 394px hole beside it, an oversized aside, and a page header that was
   1011px of empty space to the right of the lede.

   One wrapper redefines the container for interior pages, so the header, the
   body and the next-step strip all share a left edge. */
/* One measure for the whole site. The interior pages used to redefine this
   to 1240 on body.page, which moved the logo, the nav and the footer 220px
   inward the moment you left the homepage. Reading width is controlled on
   .prose and on the body grid below, not by moving the frame. */

/* Page header carries an image where there is a relevant one, which fills the
   right hand side with something useful rather than nothing. */
@media(min-width:1000px){
  .pagehead__grid{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr);
    gap:clamp(30px,3.6vw,64px);align-items:center}
}
.pagehead__art{margin:0;overflow:hidden;border:1px solid var(--line-2);background:var(--surface)}
.pagehead__art img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover}
/* The photograph is the full height of the band rather than a fixed 16:10
   block centred inside it. Centred, the band took its height from the picture
   and left a dead strip of about 140px under the lede on every interior page. */
@media(min-width:1000px){
  .pagehead__grid{align-items:stretch}
  .pagehead__grid>:first-child{display:flex;flex-direction:column;justify-content:center}
  .pagehead__art{position:relative;min-height:clamp(250px,21vw,320px)}
  .pagehead__art img{position:absolute;inset:0;width:100%;height:100%;aspect-ratio:auto}
}
@media(max-width:999px){
  .pagehead__art{margin-top:26px}
  .pagehead__art img{aspect-ratio:16/9}
}
.pagehead .lede{max-width:54ch}

/* Aside was 447px, which is a panel rather than a sidebar. */
@media(min-width:1040px){
  .pagebody--aside{grid-template-columns:minmax(0,1fr) minmax(290px,360px)}
}

/* ---- inline figures --------------------------------------------------------
   For dropping a photograph into the middle of a prose page. */
.figrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin:30px 0}
.figrow figure{margin:0;border:1px solid var(--line-2);background:var(--surface);overflow:hidden}
.figrow img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.figrow figcaption{padding:11px 13px;font-size:.85rem;color:var(--muted)}
.figrow figcaption b{display:block;color:var(--ink);font-weight:700;margin-bottom:3px}
.prose .figwide{margin:30px 0}
.prose .figwide img{display:block;width:100%;border:1px solid var(--line-2)}
.prose .figwide figcaption{margin-top:9px;font-size:.85rem;color:var(--muted)}

/* ---- file input ------------------------------------------------------------
   Only the measuring form uses this. Browser file inputs are unstyleable in
   their internals, so this styles the box around one rather than fighting it. */
.acq__files input[type=file]{font:inherit;font-size:.92rem;color:var(--ink);
  background:var(--surface);border:1px dashed var(--line-2);border-radius:2px;
  padding:14px;width:100%;cursor:pointer}
.acq__files input[type=file]:hover{border-color:var(--teal)}
.acq__files input[type=file]:focus-visible{outline:2px solid var(--teal-ink);outline-offset:1px}
.acq__files input[type=file]::file-selector-button{font:inherit;font-weight:700;font-size:.84rem;
  background:var(--sunk);color:var(--ink);border:1px solid var(--line-2);border-radius:2px;
  padding:7px 13px;margin-right:12px;cursor:pointer}
.acq__files input[type=file]::file-selector-button:hover{border-color:var(--teal)}
.acq__hint{display:block;margin-top:7px;font-size:.82rem;color:var(--muted)}

/* ---- measuring diagrams ---------------------------------------------------- */
.diagram{margin:0;border:1px solid var(--line-2);background:var(--surface);padding:18px}
.diagram svg{display:block;width:100%;height:auto}
.diagram figcaption{margin-top:12px;font-size:.86rem;color:var(--muted);border-top:1px solid var(--line);padding-top:11px}
.diagram figcaption b{display:block;color:var(--ink);margin-bottom:3px}
.dg-line{stroke:var(--teal-ink);stroke-width:1.6;fill:none}
.dg-wall{stroke:var(--ink);stroke-width:3;fill:none;stroke-linecap:square}
.dg-faint{stroke:var(--line-2);stroke-width:1.2;fill:none}
.dg-fill{fill:var(--soft)}
.dg-txt{fill:var(--teal-ink);font-family:var(--mono);font-size:12px}
.dg-lbl{fill:var(--muted);font-family:var(--body);font-size:12px;font-weight:700}
.steps .diagram{margin-top:16px;max-width:720px}
