:root{
  --ink:#17181a;--paper:#f6f4f1;--paper-2:#ebe7e1;--paper-3:#ded8cf;
  --dark:#191817;--dark-2:#221f1c;
  --bronze:#7a5c38;--bronze-lt:#c9a877;--muted:#5e5852;
  --rule:rgba(23,24,26,.16);--rule-dk:rgba(255,255,255,.17);
  --display:'Spectral',Georgia,serif;--body:'Inter',system-ui,sans-serif;
}
/* ---- motion. everything is gated behind .js so a script failure can never leave the
       page invisible, and behind prefers-reduced-motion for anyone who asks. ---- */
html{scroll-behavior:smooth;scroll-padding-top:104px}
.js .rv{opacity:0;transform:translateY(20px);
  transition:opacity .8s cubic-bezier(.22,.7,.3,1),transform .8s cubic-bezier(.22,.7,.3,1)}
.js .rv.in{opacity:1;transform:none}
/* photographs settle rather than pop: they come in a touch oversized and come to rest */
.js .rv-img{opacity:0;transform:scale(1.05);
  transition:opacity .95s ease,transform 1.15s cubic-bezier(.22,.7,.3,1)}
.js .rv-img.in{opacity:1;transform:none}
.js .hero-full .wrap > *{opacity:0;transform:translateY(24px);
  animation:heroIn .95s cubic-bezier(.22,.7,.3,1) .1s forwards}
.js .hero-full h1{animation-delay:.16s}
.js .hero-full .lede{animation-delay:.30s}
.js .hero-full .acts{animation-delay:.42s}
.js .hero-full .hero-quote{animation-delay:.62s}
@keyframes heroIn{to{opacity:1;transform:none}}
.cl{transition:transform .5s cubic-bezier(.22,.7,.3,1),box-shadow .5s}
.cl:hover{transform:translateY(-5px);box-shadow:0 18px 44px rgba(23,24,26,.09)}
.btn,.ghost{transition:background .3s,border-color .3s,color .3s,transform .3s}
.btn:hover,.ghost:hover{transform:translateY(-2px)}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js .rv,.js .rv-img,.js .hero-full .wrap > *{
    opacity:1 !important;transform:none !important;animation:none !important;transition:none !important}
  .cl:hover,.btn:hover,.ghost:hover{transform:none}
}

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--body);font-weight:300;
  font-size:16.5px;line-height:1.75;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{max-width:100%;display:block}
a{color:inherit}
.wrap{width:min(1320px,92vw);margin:0 auto;position:relative;z-index:1}
h1,h2,h3{font-family:var(--display);font-weight:600;letter-spacing:-.025em;margin:0;line-height:1.08}
h2{font-size:clamp(29px,4vw,58px);max-width:17ch}
h2 .lt{font-weight:300;font-style:italic;color:var(--muted)}
.dark h2 .lt{color:var(--bronze-lt)}
h2 em{font-style:normal;color:var(--bronze)}
.dark h2 em{color:var(--bronze-lt)}
.lede{font-size:clamp(15.5px,1.25vw,18px);color:var(--muted);max-width:52ch;margin:0}
.dark .lede{color:rgba(255,255,255,.72)}
.eyebrow{font-family:var(--display);font-weight:400;font-style:italic;font-size:15.5px;
  letter-spacing:0;text-transform:none;color:var(--muted);margin:0 0 15px}
.dark .eyebrow{color:var(--bronze-lt)}
section{padding:clamp(72px,8.2vw,124px) 0;position:relative}
.dark{background:var(--dark);color:#fff}
.sec-head{display:flex;align-items:flex-end;gap:44px;flex-wrap:wrap;margin-bottom:50px}
.sec-head .lede{margin:0 0 7px auto}
figcaption{font-family:var(--body);font-weight:500;font-size:11.5px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--muted);margin-top:12px}
.dark figcaption{color:rgba(255,255,255,.56)}

/* his only logo file is a 216x54 gif with white inside the mark, so it sits on a plate
   rather than being knocked out, which would delete half the wordmark */
.plate{background:#fff;padding:9px 13px;border-radius:2px;display:inline-flex;line-height:0}
.plate img{height:30px;width:auto}

.hdr{position:sticky;top:0;z-index:70;background:rgba(246,244,241,.95);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--rule)}
.hdr-in{display:flex;align-items:center;gap:26px;height:84px}
.hdr nav{display:flex;gap:24px;margin-left:auto;font-weight:500;font-size:13.5px}
.hdr nav a{color:var(--muted);text-decoration:none;white-space:nowrap;cursor:pointer}
.hdr nav a:hover{color:var(--bronze)}
.btn{display:inline-flex;align-items:center;gap:10px;background:var(--bronze);color:#fff;
  font-family:var(--body);font-weight:600;font-size:14.5px;padding:15px 27px;border-radius:2px;
  text-decoration:none;white-space:nowrap;border:0;cursor:pointer}
.btn:hover{background:#8b6a41}
.dark .btn{background:var(--bronze-lt);color:var(--ink)}
.dark .btn:hover{background:#d8bd93}
.ghost{display:inline-flex;align-items:center;gap:9px;border:1px solid var(--rule);
  color:var(--ink);font-family:var(--body);font-weight:600;font-size:14.5px;padding:15px 27px;
  border-radius:2px;text-decoration:none;cursor:pointer;background:none}
.ghost:hover{border-color:var(--bronze);color:var(--bronze)}
.dark .ghost{border-color:rgba(255,255,255,.44);color:#fff}
.dark .ghost:hover{border-color:var(--bronze-lt);color:var(--bronze-lt)}

/* ---- hero: full bleed photograph, type over it ---- */
.bleed{width:100vw;margin-left:calc(50% - 50vw)}
.hero{padding:0}
.hero-full{position:relative;height:calc(100vh - 84px);min-height:540px;max-height:860px;
  overflow:hidden}
.hero-full > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 54%}
/* steep falloff rather than a blanket dim: the type side is solidly dark by 22%, and the
   right 40% of the photograph is left alone. a flat overlay muddies a phone shot. */
.hero-full:after{content:"";position:absolute;inset:0;background:linear-gradient(98deg,
  rgba(14,12,11,.93) 0%,rgba(14,12,11,.82) 22%,rgba(14,12,11,.36) 46%,rgba(14,12,11,0) 66%)}
.hero-full .wrap{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;
  justify-content:center}
.hero-full h1{color:#fff;font-size:clamp(40px,5.6vw,92px);letter-spacing:-.04em;max-width:12ch}
.hero-full h1 .lt{font-weight:300;font-style:italic;color:rgba(255,255,255,.74)}
.hero-full .lede{color:rgba(255,255,255,.85);margin-top:24px;max-width:44ch}
.hero-full .acts{margin-top:30px;display:flex;gap:12px;flex-wrap:wrap}
.hero-full .ghost{border-color:rgba(255,255,255,.52);color:#fff}
.hero-full .ghost:hover{border-color:#fff;background:rgba(255,255,255,.1)}
.hero-quote{position:absolute;right:0;bottom:clamp(26px,3.4vw,52px);z-index:3;
  max-width:27ch;text-align:right;color:#fff;margin:0}
.hero-quote q{font-family:var(--display);font-weight:400;font-style:italic;
  font-size:clamp(15px,1.3vw,19px);line-height:1.38;letter-spacing:-.012em;
  quotes:'\201C' '\201D';text-shadow:0 1px 18px rgba(14,12,11,.9)}
.hero-quote .who{display:block;margin-top:10px;font-family:var(--body);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.72);font-weight:500;
  text-shadow:0 1px 14px rgba(14,12,11,.9)}

/* ---- credentials ---- */
.cred{background:var(--paper-2);padding:clamp(42px,4.4vw,62px) 0}
.cred-in{display:flex;gap:clamp(26px,3.4vw,60px);align-items:center;flex-wrap:wrap}
.cr{flex:1 1 150px}
.cr .star{display:inline;color:var(--ink);margin-right:.16em;font-size:.66em;vertical-align:.1em;font-family:var(--body)}
.cr b{display:block;white-space:nowrap;font-family:var(--display);font-weight:600;font-size:clamp(27px,3vw,42px);
  letter-spacing:-.035em;line-height:1}
.cr span{display:block;font-size:13.5px;color:var(--muted);margin-top:7px}
.cred .badge{flex:0 0 auto;margin-left:auto}
.cred .badge img{height:64px;width:auto}

/* ---- the frame. a hairline offset behind every main photograph, so the page has
       edges and depth rather than flat rectangles sitting in a grid ---- */
.fr-wrap{position:relative;display:block}
.fr-wrap:before{content:"";position:absolute;top:clamp(10px,1.2vw,18px);left:clamp(10px,1.2vw,18px);
  right:calc(-1 * clamp(10px,1.2vw,18px));bottom:calc(-1 * clamp(10px,1.2vw,18px));
  border:1px solid var(--bronze);opacity:.5;border-radius:2px}
.dark .fr-wrap:before{border-color:var(--bronze-lt);opacity:.42}
.fr-wrap > *{position:relative}

/* ---- feature rows ---- */
.feat{display:grid;grid-template-columns:1fr 1fr;gap:clamp(26px,3.4vw,58px);align-items:center}
.feat.flip .fc{order:2}
.feat .fi{position:relative;border-radius:2px;overflow:hidden}
.feat .fi img{width:100%;height:clamp(360px,44vw,600px);object-fit:cover}
.feat .sub{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:28px}
.feat .sub figure{margin:0}
.feat .sub img{width:100%;height:clamp(160px,17vw,215px);object-fit:cover;border-radius:2px}
.feat ul{list-style:none;padding:0;margin:28px 0 0}
.feat li{padding:13px 0;border-top:1px solid var(--rule);font-size:15px;display:flex;gap:14px;
  align-items:baseline}
.feat li:before{content:"";width:14px;height:1px;flex:0 0 auto;background:var(--bronze);
  transform:translateY(-5px)}
.dark .feat li{border-top-color:var(--rule-dk)}
.dark .feat li:before{background:var(--bronze-lt)}

/* ---- signature: unabridged. his site truncates every testimonial to one line behind a
       read more link. this does the opposite and prints one entire, at reading size ---- */
.unab{background:var(--dark);color:#fff}
.unab-body{position:relative}
.unab-body q{max-width:60ch}
.rv-nav{margin-left:auto;display:flex;align-items:center;gap:14px}
.rv-nav .nav-b{width:40px;height:40px;border-radius:50%;cursor:pointer;background:none;
  border:1px solid var(--rule-dk);color:#fff;font-size:19px;line-height:1;
  display:flex;align-items:center;justify-content:center;
  transition:border-color .3s,background .3s,transform .3s}
.rv-nav .nav-b:hover{border-color:var(--bronze-lt);background:rgba(201,168,119,.12);
  transform:translateY(-2px)}
.rv-count{font-family:var(--body);font-size:11.5px;letter-spacing:.14em;
  color:rgba(255,255,255,.52);font-weight:500;white-space:nowrap}
/* the quote is clipped to a share of its own height, set per breakpoint in JS, so a
   212 word review and a 156 word one both show the same proportion rather than the
   same number of pixels */
.unab-q{position:relative;overflow:hidden;transition:max-height .55s cubic-bezier(.22,.7,.3,1)}
.unab-q .rd-fade{position:absolute;left:0;right:0;bottom:0;
  height:var(--fadeH,130px);pointer-events:none;opacity:1;transition:opacity .35s;
  background:linear-gradient(to bottom,
    rgba(25,24,23,0) 0%,rgba(25,24,23,.16) 20%,rgba(25,24,23,.44) 42%,
    rgba(25,24,23,.74) 63%,rgba(25,24,23,.93) 81%,var(--dark) 93%)}
/* the blur is a separate layer so it can feather at the sides without letting the colour
   fade feather too, which would leak text out of the left and right edges */
/* Vertical ramp only. A horizontal feather leaves the first and last word of every line
   unblurred, which reads as the blur stopping short rather than as a soft edge. The blur
   spans the whole container, so there is no side edge to soften in the first place. */
.unab-q .rd-fade:before{content:"";position:absolute;inset:0;
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.35) 32%,#000 62%);
  mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.35) 32%,#000 62%)}
.unab-q.open .rd-fade{opacity:0}
.rd-more{margin-top:20px;background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--body);font-weight:600;font-size:13.5px;color:var(--bronze-lt);
  display:inline-flex;align-items:center;gap:9px;transition:color .3s}
.rd-more:hover{color:#fff}
.rd-more .chev{display:inline-block;transition:transform .4s cubic-bezier(.22,.7,.3,1);
  font-size:15px;line-height:1}
.rd-more[aria-expanded="true"] .chev{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){
  .unab-q,.rd-more .chev,.unab-q .rd-fade{transition:none}
}
.unab-body article{display:none}
.unab-body article.on{display:block;animation:fade .45s ease}
@keyframes fade{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.unab-body q{font-family:var(--display);font-weight:300;font-size:clamp(17px,1.55vw,22px);
  line-height:1.62;letter-spacing:-.012em;quotes:'\201C' '\201D';display:block;
  color:rgba(255,255,255,.93)}
.unab-body .meta{margin-top:24px;width:100%;padding-top:20px;border-top:1px solid var(--rule-dk);
  display:flex;gap:20px;flex-wrap:wrap;align-items:baseline;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.52);font-weight:500}
.unab-body .meta b{font-family:var(--display);font-weight:600;font-size:16px;letter-spacing:-.02em;
  text-transform:none;color:#fff}
.unab-body .meta .sp{margin-left:auto;color:var(--bronze-lt)}

/* ---- detail strip ---- */
.det{display:grid;grid-template-columns:repeat(4,1fr);gap:2px}
.det figure{margin:0;overflow:hidden}
.det img{width:100%;height:clamp(250px,29vw,400px);object-fit:cover;
  transition:transform .9s cubic-bezier(.2,.7,.3,1)}
.det figure:hover img{transform:scale(1.05)}

/* ---- a full width pause, so the container rhythm breaks instead of repeating ---- */
.pull{position:relative;height:clamp(300px,38vw,520px);display:flex;align-items:center;
  justify-content:center;text-align:center;overflow:hidden}
.pull img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 46%}
.pull:after{content:"";position:absolute;inset:0;background:rgba(18,16,15,.72)}
.pull .wrap{position:relative;z-index:2}
.pull q{font-family:var(--display);font-weight:300;font-style:italic;color:#fff;
  font-size:clamp(25px,3.5vw,52px);line-height:1.22;letter-spacing:-.025em;
  quotes:'\201C' '\201D';display:block;max-width:19ch;margin:0 auto}
.pull .who{display:block;margin-top:22px;font-family:var(--display);font-style:italic;
  font-size:16px;letter-spacing:0;color:rgba(255,255,255,.72);font-weight:400}

/* ---- the crew ---- */
.crew{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,4.2vw,72px);align-items:center}
.crew .im{border-radius:2px;overflow:hidden}
.crew .im img{width:100%;height:clamp(320px,38vw,500px);object-fit:cover}
.sig{margin-top:30px;font-family:var(--display);font-style:italic;font-weight:400;
  font-size:clamp(18px,1.8vw,25px);letter-spacing:-.02em;color:var(--ink)}
.dark .sig{color:#fff}

/* ---- his three claims, each with a customer saying the same thing ---- */
.claims{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,36px)}
.cl{background:var(--paper);border-radius:2px;padding:clamp(26px,2.8vw,40px);
  display:flex;flex-direction:column;border-top:3px solid var(--bronze)}
.cl h3{font-size:clamp(20px,2vw,27px);letter-spacing:-.03em;margin-bottom:14px}
.cl .his{font-size:14.5px;color:var(--muted);line-height:1.66;margin:0 0 26px}
.cl .proof{margin-top:auto;padding-top:22px;border-top:1px solid var(--rule)}
.cl .proof q{font-family:var(--display);font-weight:400;font-style:italic;font-size:15.5px;
  line-height:1.5;quotes:'\201C' '\201D';color:var(--ink)}
.cl .proof .who{display:block;margin-top:11px;font-size:11px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--muted);font-weight:500;font-style:normal}

/* ---- projects: masonry, because almost every photograph he has is portrait ---- */
.gal-filter{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:clamp(24px,2.8vw,38px)}
.gal-filter button{font-family:var(--body);font-weight:600;font-size:12.5px;letter-spacing:.06em;
  padding:10px 20px;border-radius:2px;border:1px solid var(--rule);background:none;
  color:var(--muted);cursor:pointer;transition:all .25s}
.gal-filter button:hover{border-color:var(--bronze);color:var(--bronze)}
.gal-filter button.on{background:var(--ink);border-color:var(--ink);color:#fff}
.gal{column-count:4;column-gap:clamp(12px,1.4vw,18px)}
.gal-i{break-inside:avoid;display:block;width:100%;margin:0 0 clamp(12px,1.4vw,18px);
  padding:0;border:0;background:none;cursor:pointer;position:relative;overflow:hidden;
  border-radius:2px;line-height:0}
.gal-i img{width:100%;height:auto;display:block;
  transition:transform .9s cubic-bezier(.2,.7,.3,1)}
.gal-i:after{content:"";position:absolute;inset:0;background:rgba(23,24,26,0);
  transition:background .45s}
.gal-i:hover img{transform:scale(1.055)}
.gal-i:hover:after{background:rgba(23,24,26,.22)}
.gal-i:focus-visible{outline:2px solid var(--bronze);outline-offset:3px}
.gal-tag{position:absolute;left:13px;bottom:12px;z-index:2;font-family:var(--body);
  font-weight:600;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:#fff;
  opacity:0;transform:translateY(6px);transition:opacity .35s,transform .35s;
  text-shadow:0 1px 12px rgba(20,18,16,.9);line-height:1}
.gal-i:hover .gal-tag{opacity:1;transform:none}

.lb{position:fixed;inset:0;z-index:200;background:rgba(18,17,16,.97);display:none;
  align-items:center;justify-content:center;padding:clamp(20px,4vw,56px)}
.lb.on{display:flex}
.lb-stage{display:flex;align-items:center;justify-content:center;max-width:100%;max-height:100%}
.lb img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
  border-radius:2px;box-shadow:0 30px 90px rgba(0,0,0,.5)}
.lb-btn{position:absolute;background:none;border:1px solid rgba(255,255,255,.3);
  color:#fff;width:48px;height:48px;border-radius:50%;cursor:pointer;font-size:19px;
  line-height:1;display:flex;align-items:center;justify-content:center;transition:all .25s}
.lb-btn:hover{border-color:#fff;background:rgba(255,255,255,.1)}
.lb-prev{left:clamp(12px,2.4vw,34px);top:50%;transform:translateY(-50%)}
.lb-next{right:clamp(12px,2.4vw,34px);top:50%;transform:translateY(-50%)}
.lb-close{right:clamp(12px,2.4vw,34px);top:clamp(12px,2.4vw,30px)}
.lb-count{position:absolute;left:50%;bottom:clamp(14px,2.4vw,28px);transform:translateX(-50%);
  font-family:var(--body);font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;
  color:rgba(255,255,255,.62);font-weight:500}

/* ---- service area ---- */
.cities{display:flex;flex-wrap:wrap;gap:0 0;margin-top:8px}
.cities span{font-family:var(--display);font-weight:400;font-size:clamp(26px,3.6vw,54px);
  letter-spacing:-.03em;padding:9px 0}
.cities span:after{content:"\00b7";color:var(--bronze-lt);margin:0 18px;font-weight:300}
.cities span:last-child:after{content:""}

/* ---- contact + form ---- */
.c-in{display:grid;grid-template-columns:1fr 1fr;gap:clamp(34px,4.6vw,76px);align-items:start}
.form{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.form .full{grid-column:1 / -1}
.form label{display:block;font-size:11px;letter-spacing:.15em;text-transform:uppercase;
  font-weight:600;color:var(--muted);margin-bottom:7px}
.form input,.form select,.form textarea{width:100%;background:var(--paper);
  border:1px solid var(--rule);border-radius:2px;padding:13px 14px;font-family:var(--body);
  font-size:15px;font-weight:300;color:var(--ink)}
.form textarea{min-height:118px;resize:vertical}
.form input:focus,.form select:focus,.form textarea:focus{outline:0;border-color:var(--bronze)}
.c-call{margin-top:38px}
.c-call .lbl{display:block;font-size:11px;letter-spacing:.15em;text-transform:uppercase;
  font-weight:600;color:var(--muted);margin-bottom:10px}
.c-call a{font-family:var(--display);font-weight:600;font-size:clamp(30px,3.4vw,46px);
  letter-spacing:-.035em;text-decoration:none;color:var(--ink);line-height:1}
.c-call a:hover{color:var(--bronze)}

footer{background:var(--ink);color:#fff;padding:clamp(58px,6.6vw,90px) 0 32px}
.f-top{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:clamp(30px,4vw,64px);
  padding-bottom:42px;border-bottom:1px solid var(--rule-dk)}
.f-top p{color:rgba(255,255,255,.62);font-size:14.5px;margin:18px 0 0}
.f-top .f-h{font-family:var(--body);font-weight:600;font-size:11px;letter-spacing:.28em;
  text-transform:uppercase;color:var(--bronze-lt);margin:0 0 18px}
.f-top ul{list-style:none;padding:0;margin:0}
.f-top li{padding:7px 0;font-size:14.5px;color:rgba(255,255,255,.74)}
.f-top a{text-decoration:none;cursor:pointer}
.f-top a:hover{color:var(--bronze-lt)}
.f-bot{display:flex;gap:26px;flex-wrap:wrap;padding-top:24px;font-size:12.5px;
  color:rgba(255,255,255,.5)}
.f-bot .sp{margin-left:auto}

dialog{border:0;padding:0;background:transparent;max-width:min(620px,92vw)}
dialog::backdrop{background:rgba(20,18,16,.88);backdrop-filter:blur(4px)}
.md{background:var(--paper);border-radius:3px;padding:44px 42px}
.md h3{font-size:29px;margin:0 0 14px}
.md p{margin:0 0 22px;color:var(--muted);font-size:15.5px}
.md .row2{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.md .close{background:none;border:1px solid var(--rule);border-radius:2px;padding:15px 27px;
  font-family:var(--body);font-weight:600;font-size:14.5px;cursor:pointer}

@media (max-width:1040px){
  .hdr nav{display:none}
  .feat,.crew,.c-in{grid-template-columns:1fr}
  .hero-quote{display:none}
  .feat.flip .fc{order:0}
  .det,.claims{grid-template-columns:repeat(2,1fr)}
  .gal{column-count:2}
}
@media (max-width:620px){
  .det,.claims,.form{grid-template-columns:1fr}
  .gal{column-count:1}
  .f-top{grid-template-columns:1fr}
  .f-bot .sp{margin-left:0}
}

/* ---- photo uploads on the quote form ---------------------------------------
   The native input is hidden and its label is the control, so it can carry the
   page's own type. Thumbnails are built from the chosen files and each can be
   removed, because input.files is read only and there is otherwise no way to
   drop one photo out of five. */
.opt{font-weight:400;text-transform:none;letter-spacing:0;color:var(--muted);opacity:.75}
.file-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.file-drop{display:inline-flex;align-items:center;gap:10px;cursor:pointer;padding:13px 20px;
  border:1px dashed var(--rule);border-radius:2px;color:var(--muted);font-family:var(--body);
  font-weight:500;font-size:14px;transition:border-color .3s,color .3s}
.file-drop:hover{border-color:var(--bronze);color:var(--bronze)}
.file-input:focus-visible+.file-drop{outline:2px solid var(--bronze);outline-offset:2px}
.file-tray{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px}
.file-chip{position:relative;width:76px;height:76px;border-radius:2px;overflow:hidden}
.file-chip img{width:100%;height:100%;object-fit:cover;display:block}
.file-x{position:absolute;top:4px;right:4px;width:22px;height:22px;border:0;border-radius:50%;
  cursor:pointer;background:rgba(23,24,26,.78);color:#fff;font-size:14px;line-height:1;
  display:flex;align-items:center;justify-content:center;padding:0}
.file-x:hover{background:rgba(23,24,26,.96)}
.file-note{margin:11px 0 0;font-size:12.5px;color:var(--muted)}
.file-note.is-bad{color:#b1452f}
.form-status{margin:14px 0 0;font-size:14px;color:var(--muted);grid-column:1 / -1}
.form-status.is-bad{color:#b1452f}
.cred .badge a{display:inline-block;line-height:0;border-radius:2px;
  transition:opacity .3s,transform .3s}
.cred .badge a:hover{opacity:.78;transform:translateY(-2px)}
.cred .badge a:focus-visible{outline:2px solid var(--bronze);outline-offset:3px}

/* ---- the property type note ------------------------------------------------
   A scope statement, not a rejection. The neutral line is always there so the
   boundary is set for everyone; the fuller note only appears for the one answer
   it applies to, which is far kinder than a "no condos" banner at the top of
   the page that every visitor reads. */
.field-note{margin:9px 0 0;font-size:12.5px;line-height:1.6;color:var(--muted)}
.field-note.is-flag{color:var(--ink);border-left:2px solid var(--bronze);padding-left:11px}
.c-sec{padding:clamp(72px,8.2vw,124px) 0;background:var(--paper)}
.c-call .c-mail{display:block;margin-top:10px;font-family:var(--body);font-weight:500;
  font-size:16px;letter-spacing:0;color:var(--bronze);text-decoration:none}
.c-call .c-mail:hover{text-decoration:underline}

/* ---- phones and tablets ----------------------------------------------------
   Nothing may widen the page sideways. Photos used to arrive at 105% and settle,
   and the full-bleed strips are exactly screen width, so mid-animation they hung
   9px past each edge and the whole page could be dragged left and right. Below
   1040px they fade only. overflow-x:clip is the backstop; unlike hidden it does
   not create a scroll container, so the sticky header keeps working. */
html,body{overflow-x:clip}
@media (max-width:1040px){
  .js .rv-img,.js .rv-img.in{transform:none}
}

/* ---- header: phone as plain text and the menu behind a button on small screens */
.hdr-call svg{width:16px;height:16px;flex:none}
.hdr-menu,.nav-m,.hdr-menu .i-close{display:none}
@media (max-width:1040px){
  .hdr-in{gap:12px;height:68px}
  .plate{padding:7px 10px}
  .plate img{height:26px}
  .hdr .hdr-call{margin-left:auto;background:none;color:var(--ink);padding:8px 2px;
    font-size:15px;font-weight:600;gap:7px}
  .hdr .hdr-call:hover{background:none;color:var(--bronze);transform:none}
  .hdr .hdr-call svg{color:var(--bronze)}
  .hdr-menu{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;
    margin-right:-10px;padding:0;background:none;border:0;cursor:pointer;color:var(--ink)}
  .hdr-menu svg{width:24px;height:24px}
  .hdr-menu:focus-visible{outline:2px solid var(--bronze);outline-offset:2px}
  .hdr.open .hdr-menu .i-open{display:none}
  .hdr.open .hdr-menu .i-close{display:block}
  .hdr .hdr-in{position:static}   /* so the panel spans the full header, not the padded wrap */
  .hdr nav{display:none;position:absolute;left:0;right:0;top:100%;flex-direction:column;gap:0;
    margin:0;padding:6px 0 12px;background:var(--paper);border-bottom:1px solid var(--rule);
    box-shadow:0 18px 30px rgba(23,24,26,.08)}
  .hdr.open nav{display:flex}
  .hdr nav a{padding:15px 24px;font-size:16px;color:var(--ink)}
  .hdr nav a + a{border-top:1px solid var(--rule)}
  .nav-m{display:block}
}
@media (max-width:360px){
  .hdr .hdr-call span{display:none}
}

/* ---- home gallery on phones -------------------------------------------------
   Fifteen full-width photographs was a long scroll before reaching the contact
   form. On phones the home page shows a short selection as even square tiles,
   two to a row; the full set is one tap away on the projects page. The cap is
   applied in site.js so it respects the Bathrooms and Kitchens filters. */
@media (max-width:620px){
  #library .gal{column-count:auto;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
  #library .gal-i{margin:0;aspect-ratio:1/1}
  #library .gal-i img{height:100%;object-fit:cover}
}
