/* ==========================================================================
   Pam Hassler Interiors
   Direction A — Quiet Evergreen
   One stylesheet, no build step. Tokens, primitives, then page furniture.

   Two motifs carry the design:
   1. The brand mark is a rectangle enclosing initials. That frame is echoed
      as a hairline matte inset into the photographs.
   2. The brand came off letterpress stationery, so paper grounds carry a
      fine grain and section breaks use a rule-and-diamond ornament.
   ========================================================================== */

:root{
  /* --- palette ------------------------------------------------------- */
  --paper:      #F5F3EF;
  --paper-2:    #EDEAE4;
  --ink:        #33302E;
  --ink-2:      #4A4441;
  --pine-rgb:   46, 61, 52;
  --pine:       #2E3D34;
  --pine-deep:  #26332B;
  --mute:       #6E6864;   /* smallest text that must read — 4.7:1 on paper */
  --stone:      #8A8480;   /* rules and hairlines only, never text          */
  --line:       #DDD8D1;
  --red:        #BF2025;   /* exactly once per page                        */

  /* --- type ---------------------------------------------------------- */
  --sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;

  --fs-hero:  clamp(33px, 4.1vw, 58px);
  --fs-h2:    clamp(28px, 3.6vw, 44px);
  --fs-h3:    clamp(21px, 2.3vw, 27px);
  --fs-quote: clamp(26px, 3.9vw, 46px);
  --fs-num:   clamp(38px, 4.6vw, 60px);

  /* --- rhythm -------------------------------------------------------- */
  --gutter: 28px;
  --measure: 1240px;
  --section: clamp(72px, 10vw, 132px);
  --bleed-pad: max(var(--gutter), calc((100vw - var(--measure)) / 2 + var(--gutter)));
  --overlap: clamp(0px, 3.4vw, 56px);

  /* --- paper grain ---------------------------------------------------- */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)'/%3E%3C/svg%3E");
}

*, *::before, *::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-padding-top:96px; }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-weight:400;
  font-size:17px;
  line-height:1.68;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ max-width:100%; height:auto; display:block; }
a{ color:var(--pine); }
a:focus-visible, button:focus-visible{ outline:2px solid var(--red); outline-offset:3px; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--pine); color:var(--paper); padding:12px 20px;
  font-family:var(--sans); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
}
.skip:focus{ left:0; }

.shell{ width:100%; max-width:var(--measure); margin:0 auto; padding:0 var(--gutter); }

/* grain sits on paper grounds only — never over photography */
.grain{ position:relative; isolation:isolate; }
.grain::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background-image:var(--grain);
  opacity:.055; mix-blend-mode:multiply; pointer-events:none;
}
.grain--dark::before{ opacity:.09; mix-blend-mode:overlay; }

/* ==========================================================================
   Type primitives
   ========================================================================== */

.eyebrow{
  margin:0; font-family:var(--sans); font-weight:500;
  font-size:11px; letter-spacing:.26em; text-transform:uppercase; color:var(--pine);
}

.display{
  margin:0; font-family:var(--serif); font-weight:400;
  line-height:1.12; text-wrap:balance; color:var(--ink);
  font-size:var(--fs-h2); letter-spacing:-.011em;
}
.display--hero{ font-size:var(--fs-hero); line-height:1.08; letter-spacing:-.015em; }
.display--sm{ font-size:var(--fs-h3); line-height:1.2; letter-spacing:-.006em; }

.prose{ margin:0; max-width:44ch; color:var(--ink-2); font-weight:400; }
.prose--wide{ max-width:58ch; }
.prose--lead{ font-size:clamp(18px,1.5vw,21px); line-height:1.66; }

.caption{
  margin:0; font-family:var(--sans); font-size:12.5px; line-height:1.6;
  letter-spacing:.14em; text-transform:uppercase; color:var(--mute);
}

/* Rule and diamond. Holiday territory only as of 6 Sep — the diamond is a
   seasonal mark, so the design pages use .rule--plain below and the only
   red left on them is the nav underline and focus rings. */
.rule{ display:flex; align-items:center; gap:16px; width:100%; }
.rule::before, .rule::after{ content:""; height:1px; background:var(--stone); opacity:.5; flex:1 1 auto; }
.rule i{ flex:none; width:7px; height:7px; background:var(--red); transform:rotate(45deg); }


/* A plain hairline for pages outside holiday territory — the diamond is a
   seasonal mark and does not belong on the design pages. */
.rule--plain i{ display:none; }
.rule--plain::before{ flex:0 0 auto; width:100%; }
.rule--plain::after{ display:none; }

/* ==========================================================================
   Buttons and links
   ========================================================================== */

.btn{
  display:inline-block; align-self:flex-start;
  font-family:var(--sans); font-size:11.5px; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase;
  padding:17px 34px; text-decoration:none;
  background:var(--pine); color:var(--paper); border:1px solid var(--pine);
  transition:background .18s ease, color .18s ease;
}
.btn:hover{ background:transparent; color:var(--pine); }
.btn--ghost{ background:transparent; color:var(--pine); }
.btn--ghost:hover{ background:var(--pine); color:var(--paper); }
.btn--onPine{ background:var(--paper); color:var(--pine); border-color:var(--paper); }
.btn--onPine:hover{ background:transparent; color:var(--paper); }

.textlink{
  align-self:flex-start;
  font-family:var(--sans); font-size:12px; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--pine); text-decoration:none;
  border-bottom:1px solid var(--stone); padding-bottom:5px;
}
.textlink:hover{ border-bottom-color:var(--pine); }
/* Sections read headline, copy, link. The link used to float right of the
   heading, which read as navigation chrome rather than part of the thought. */
.section-link{ display:inline-block; margin-top:clamp(18px,2vw,26px); margin-bottom:clamp(30px,4vw,52px); }

/* ==========================================================================
   Header — Pam's original logo, used whole
   ========================================================================== */

.site-head{
  position:sticky; top:0; z-index:50;
  border-bottom:1px solid var(--line); background:var(--paper);
}
.site-head .shell{
  display:flex; align-items:center; justify-content:space-between;
  gap:24px; padding-top:clamp(15px,1.7vw,22px); padding-bottom:clamp(15px,1.7vw,22px);
}
/* The header used to assemble a lockup out of three pieces: the monogram
   cropped from the artwork, a hairline, and the name typeset in Archivo.
   That was our reconstruction, not Pam's logo. img/logo.svg is the original
   mark, monogram and stacked type together, so it is used whole and sized
   by width — it is 4.3:1, not the near-square monogram it replaces. */
.brand{ display:block; flex:0 1 auto; min-width:0; text-decoration:none; }
.brand img{ display:block; width:clamp(238px,24vw,336px); height:auto; }
.nav-toggle{ margin-left:auto; }

.nav-toggle{ display:none; flex:none; background:none; border:1px solid var(--line); padding:12px 13px; cursor:pointer; }
.nav-toggle i{ display:block; width:20px; height:1px; background:var(--ink); }
.nav-toggle i + i{ margin-top:5px; }

.nav ul{ display:flex; flex-wrap:nowrap; gap:0 22px; margin:0; padding:0; list-style:none; }
.nav li{ flex:none; }
.nav a{
  font-family:var(--sans); font-size:11px; font-weight:400;
  letter-spacing:.16em; text-transform:uppercase; white-space:nowrap;
  color:var(--ink); text-decoration:none;
  padding-bottom:4px; border-bottom:1px solid transparent;
}
.nav a:hover{ border-bottom-color:var(--stone); }
.nav a[aria-current="page"]{ color:var(--pine); border-bottom-color:var(--red); }

@media (max-width:1080px){
  .nav-toggle{ display:block; }
  .nav{ display:none; width:100%; border-top:1px solid var(--line); }
  .nav.is-open{ display:block; }
  .site-head .shell{ flex-wrap:wrap; row-gap:0; }
  .nav ul{ flex-direction:column; flex-wrap:wrap; gap:0; padding:8px 0 14px; }
  .nav li + li{ border-top:1px solid var(--line); }
  .nav a{ display:block; padding:16px 0; border-bottom:none; font-size:13px; }
  .nav a[aria-current="page"]{ border-bottom:none; }
}
/* On a phone the logo and the menu button share one line. The mark is a
   single image now, so it scales rather than reflowing — 56vw leaves room
   for the button and the gutters at 360px with pixels to spare. */
@media (max-width:600px){
  .brand img{ width:min(62vw,232px); }
}

/* ==========================================================================
   Hero — paper panel cutting across the photograph
   ========================================================================== */

.hero{
  display:grid; grid-template-columns:minmax(0,1.14fr) minmax(0,1fr);
  align-items:stretch; border-bottom:1px solid var(--line);
}
.hero__text{
  position:relative; z-index:2; min-width:0;
  background:var(--paper);
  margin-right:calc(var(--overlap) * -1);
  display:flex; flex-direction:column; gap:26px; justify-content:center;
  padding:clamp(56px,7vw,104px) 0 clamp(56px,7vw,104px) var(--bleed-pad);
  padding-right:calc(clamp(32px,4.4vw,64px) + var(--overlap));
}
.hero__text .prose{ max-width:34ch; }
.hero__figure{
  margin:0; position:relative;
  /* The hero is a single 4:3 landscape photograph again (IMG_0720), not the
     3:4 portraits the carousel used, so the tall panel that suited those now
     crops it hard. Back down to something nearer the source shape. */
  min-height:min(74vh, 700px);
}
.hero__figure img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.hero__actions{ display:flex; flex-wrap:wrap; gap:12px; }
.hero__meta{
  display:flex; align-items:center; gap:14px;
  font-family:var(--sans); font-size:11px; letter-spacing:.24em;
  text-transform:uppercase; color:var(--mute);
}
.hero__meta::before{ content:""; width:38px; height:1px; background:var(--stone); flex:none; }

/* --- hero carousel: crossfade, with a progress hairline on the bottom edge.
   The rail sits on the photograph, so it carries its own scrim and shadow —
   it has to stay visible on the brightest frame in the set, not the average
   one. Tested against the marble frame, which is the worst case. ---------- */
.hero__figure{ overflow:hidden; }
.hero__slide{ position:absolute; inset:0; opacity:0; transition:opacity 1.15s ease; }
.hero__slide.is-on{ opacity:1; }

.hero__rail{
  position:absolute; bottom:0; right:0; height:44px; z-index:3;
  /* The paper panel cuts across this figure and sits at z-index 2, so a rail
     starting at the figure's edge paints its gradient over the paper. Start
     where the panel ends. This also keeps the three segments equal. */
  left:var(--overlap);
  display:flex; gap:2px; align-items:flex-end;
  background:linear-gradient(to top, rgba(51,48,46,.52), rgba(51,48,46,0));
}
.hero__rail button{
  flex:1 1 0; height:3px; margin:0 0 14px; padding:0; border:0; cursor:pointer;
  position:relative; overflow:hidden; background:rgba(245,243,239,.30);
  box-shadow:0 1px 3px rgba(30,28,26,.5);
}
/* the track of the segment you are on is brighter, so there is an indicator
   even at the instant the fill restarts from zero */
.hero__rail button[aria-current="true"]{ background:rgba(245,243,239,.55); }
.hero__rail button:first-child{ margin-left:24px; }
.hero__rail button:last-child{ margin-right:24px; }
.hero__rail button span{
  position:absolute; inset:0; display:block; background:var(--paper);
  transform:scaleX(0); transform-origin:left center;
}
/* Driven by an animation rather than a transition. A transition has to be
   restarted from script, which meant setting an inline width — and an inline
   width outranks the stylesheet, so the fill was pinned at zero and never
   ran. The animation restarts by itself each time the attribute flips. */
.hero__rail button[aria-current="true"] span{
  animation:railFill var(--dwell, 6s) linear forwards;
}
@keyframes railFill{ from{ transform:scaleX(0); } to{ transform:scaleX(1); } }
.hero__rail button:focus-visible{ outline:2px solid var(--paper); outline-offset:5px; }
/* once someone takes control the fill stops counting down and just marks
   where you are, so it never implies the carousel is still running */
.hero__figure.is-manual .hero__rail button[aria-current="true"] span{
  animation:none; transform:scaleX(1);
}

@media (prefers-reduced-motion:reduce){
  .hero__slide{ transition:none; }
  .hero__rail button[aria-current="true"] span{ animation:none; transform:scaleX(1); }
}

/* --- hero variant for the sub-pages ---------------------------------------
   Interior Design and Holiday use the Home split — copy left on paper, image
   right — without the carousel. The single figure is a plain <picture>, so it
   needs the absolute fill the carousel slides were providing. The panel is a
   little shorter than Home's since there is no rail to clear. ------------- */
.hero--page .hero__figure{ min-height:min(62vh, 580px); }
.hero--page .hero__figure > picture{ position:absolute; inset:0; display:block; }
.hero--page .hero__figure img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.hero--page .hero__text .rule{ max-width:220px; }

/* Holiday's hero panel: the photograph printed in the campaign red, with the
   Santa's Design Helpers mark as white line art over it. The room stays sharp
   and readable, the whole panel reads red, and the mark loses the red block
   that made it look like a logo pasted onto a coloured rectangle.

   How the wash works: the photograph is desaturated and composited in
   `luminosity` so it contributes tone only, then a flat red multiplies over
   it. Both sit on a red ground so the blend has something to resolve against. */
.hero__figure--wash{ background:#8E1A1F; overflow:hidden; }
.wash__shot{ position:absolute; inset:0; }
.hero--page .wash__shot img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:grayscale(1) contrast(1.06) brightness(.92); mix-blend-mode:luminosity;
}
.wash__ink{ position:absolute; inset:0; background:#BE2026; mix-blend-mode:multiply; opacity:.86; }
.hero__figure--wash::after{
  content:""; position:absolute; inset:clamp(20px,2.4vw,34px);
  border:1px solid rgba(255,255,255,.28); pointer-events:none;
}
/* The mark is laid inside this box with object-fit, not sized by percentage
   height. `.wash__mark` was a flex box whose item is the <picture>, not the
   <img> — so `height:100%` on the image resolved against a picture of auto
   height, the inset was ignored, and the mark overflowed the panel and got
   clipped. Both boxes now take a definite size from inset:0 instead. */
.wash__mark{ position:absolute; inset:clamp(56px,7vw,104px); }
.hero--page .wash__mark picture{ position:absolute; inset:0; display:block; }
.hero--page .wash__mark img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:contain;
  filter:drop-shadow(0 6px 22px rgba(0,0,0,.34));
}

/* No blend modes, no wash: show the mark on flat red rather than a muddy
   grey-red composite. */
@media (forced-colors:active), (prefers-contrast:more){
  .hero--page .wash__shot{ display:none; }
  .wash__ink{ mix-blend-mode:normal; opacity:1; }
}

@media (max-width:860px){
  .hero{ grid-template-columns:1fr; }

  /* Every child of the hero figure is absolutely positioned — the carousel
     slides, the page-hero picture, the red wash and its mark — so the figure
     has no content height of its own. Sizing it with `aspect-ratio` works in
     Chrome, which resolves the ratio against the definite column width. iOS
     Safari does not: it sizes the grid row from content (zero), stretches the
     item into it, and the hero image vanishes completely. It looked fine in
     every desktop browser and was invisible only on a real phone.

     So the height is stated outright here. No aspect-ratio to resolve, and
     `align-self:start` so stretch cannot flatten it either. The vh cap keeps
     the image from eating a whole screen on a tall phone; object-fit handles
     the crop when the cap bites. */
  .hero__figure{
    order:1; align-self:start;
    aspect-ratio:auto;
    height:min(125vw, 66vh);
    min-height:280px;   /* a floor, so no future change can flatten it again */
  }
  .hero--page .hero__figure{
    height:min(75vw, 56vh);
    min-height:220px;
  }
  .hero--page .wash__mark{ inset:clamp(34px,9vw,60px); }
  .hero__text{
    order:2; margin-right:0; gap:20px;
    padding:40px var(--gutter) 48px;
  }
}

/* ==========================================================================
   Sections
   ========================================================================== */

.band{ padding:var(--section) 0; }
.band--sunk{ background:var(--paper-2); border-block:1px solid var(--line); }
.band--pine{ background:var(--pine); color:var(--paper); }

.stack{ display:flex; flex-direction:column; gap:24px; }
.stack--tight{ gap:16px; }

.section-head{ display:flex; flex-direction:column; gap:16px; margin-bottom:clamp(22px,2.8vw,34px); }
.section-head--split{
  flex-direction:row; flex-wrap:wrap; align-items:flex-end;
  justify-content:space-between; gap:22px 48px;
}

/* --- the service, as a numbered sequence --------------------------------- */
.steps{
  margin:0; padding:0; list-style:none;
  display:grid; grid-template-columns:repeat(auto-fit, minmax(240px,1fr));
  gap:2px; align-items:stretch;
}
.steps li{
  position:relative;
  padding:clamp(80px,6.6vw,96px) clamp(28px,3.2vw,42px) clamp(30px,3.2vw,42px);
  display:flex; flex-direction:column; gap:14px;
  background:var(--pine);
}

/* An ornament hung from the top edge of each card. The three shapes are the
   ones that actually recur in her photographs — a mercury sphere, a teardrop
   finial, a star topper — rather than icons standing in for the step. The
   thread is what keeps it reading as decoration and not as an icon set. */
.steps .ornament{
  position:absolute; top:0; left:clamp(28px,3.2vw,42px);
  width:31px; height:67px; display:block; pointer-events:none;
}
.steps .ornament svg{ display:block; width:100%; height:100%; overflow:visible; }
.steps .ornament [stroke]{
  stroke:#C6D4C9; stroke-width:1; fill:none;
  stroke-linecap:round; stroke-linejoin:round; opacity:.85;
}

.steps .num{
  font-family:var(--sans); font-weight:300; font-size:var(--fs-num);
  line-height:1; letter-spacing:.02em; color:var(--paper);
  font-variant-numeric:tabular-nums;
}
.steps h3{
  margin:0; font-family:var(--sans); font-weight:500; font-size:12px;
  letter-spacing:.24em; text-transform:uppercase; color:#C6D4C9;
}
.steps p{ margin:0; font-size:16px; line-height:1.7; color:#D7DED8; }

/* --- interiors: the work that now leads the page ------------------------- */
.work{
  display:grid; gap:2px;
  grid-template-columns:repeat(3, minmax(0,1fr));
}
.work figure{ margin:0; position:relative; overflow:hidden; aspect-ratio:3/2; background:var(--paper-2); }
.work img{ width:100%; height:100%; object-fit:cover; }
.work figure::after{
  content:""; position:absolute; inset:14px;
  border:1px solid rgba(245,243,239,.34); pointer-events:none;
}
@media (max-width:760px){
  .work{ grid-template-columns:1fr; }
  .work figure{ aspect-ratio:16/10; }
  .work figure::after{ inset:11px; }
}

/* --- gallery teaser, asymmetric ------------------------------------------ */
.teaser-body{ max-width:62ch; margin:0 0 22px; }
.plates{
  display:grid; gap:2px;
  grid-template-columns:minmax(0,1.34fr) minmax(0,1fr);
  grid-template-rows:repeat(2, minmax(0,1fr));
  /* explicit height so the two rows resolve and the tall plate can span them */
  height:clamp(440px, 48vw, 680px);
}
.plate{ margin:0; position:relative; overflow:hidden; background:var(--paper-2); }
.plate img{ width:100%; height:100%; object-fit:cover; }
/* the mark's rectangle, echoed as a matte inside the photograph */
.plate::after{
  content:""; position:absolute; inset:16px;
  border:1px solid rgba(245,243,239,.42); pointer-events:none;
}
.plate--tall{ grid-row:1 / span 2; }

@media (max-width:760px){
  .plates{ grid-template-columns:1fr; grid-template-rows:none; height:auto; }
  .plate{ aspect-ratio:16/11; }
  .plate--tall{ grid-row:auto; aspect-ratio:4/5; }
  .plate::after{ inset:12px; }
}

/* --- full-bleed photograph as a section break ---------------------------- */
.figure-band{ margin:0; position:relative; height:clamp(300px, 50vw, 600px); }
.figure-band img{ width:100%; height:100%; object-fit:cover; }

/* --- testimonial ---------------------------------------------------------- */
.quote-row{
  display:grid; grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:clamp(32px,5vw,80px); align-items:start;
}
@media (max-width:800px){ .quote-row{ grid-template-columns:1fr; gap:30px; } }
.quote{ margin:0; position:relative; }
.quote .openmark{
  display:block; font-family:var(--serif); font-size:clamp(64px,9vw,132px);
  line-height:.72; color:var(--stone); opacity:.4; margin-bottom:6px;
  user-select:none;
}
.quote blockquote{
  margin:0; font-family:var(--serif); font-weight:400;
  font-size:var(--fs-quote); line-height:1.42; color:var(--ink); text-wrap:balance;
}
.quote figcaption{
  margin-top:30px; font-family:var(--sans); font-size:11.5px; font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; color:var(--mute);
}

/* --- closing call to action ----------------------------------------------- */
.band--pine .eyebrow{ color:#A9BEB0; }
.band--pine .display{ color:var(--paper); }
.band--pine .prose{ color:#D7DED8; }
.band--pine .rule::before, .band--pine .rule::after{ background:rgba(245,243,239,.22); }
/* This is a banner, not a section: one shallow horizontal strip, the copy on
   the left and the button on the right, both centred on the same axis. The
   band gets its own reduced padding — the standard section rhythm made it
   twice as tall as it needed to be and left the button floating. */
.band--banner{ padding:clamp(38px,4.2vw,58px) 0; }
.cta-row{
  display:flex; flex-wrap:wrap; gap:24px 56px;
  align-items:center; justify-content:space-between;
}
.cta-row .stack{ gap:10px; }
.cta-row .display{ font-size:clamp(26px,3vw,38px); }
.cta-row .prose{ max-width:58ch; }
.cta-row .btn{ flex:none; align-self:center; }
@media (max-width:700px){
  .cta-row{ align-items:flex-start; }
  .cta-row .btn{ align-self:flex-start; }
}

/* --- the holiday teaser on Home: one panoramic photograph, contained rather
   than full bleed, with the copy beneath it. It replaces the three pine cards,
   which put a third slab of green on a page that already ends in two. The
   three-step cards still live on the Holiday page, where they belong. ----- */
/* The image inside is in normal flow, so this is not exposed to the WebKit
   collapse that killed the hero figures — but the floor costs nothing and
   means a ratio that fails to resolve can never leave an empty band. */
.pano{ margin:0; position:relative; overflow:hidden; aspect-ratio:11/5; min-height:160px; background:var(--paper); }
.pano img{ width:100%; height:100%; object-fit:cover; display:block; }
.pano::after{ content:""; position:absolute; inset:16px; border:1px solid rgba(245,243,239,.34); pointer-events:none; }
@media (max-width:700px){ .pano{ aspect-ratio:16/10; } .pano::after{ inset:11px; } }

/* A lede strip: the same contained panoramic, used directly under a text-only
   page hero. Those pages opened with a whole phone screen of nothing but a
   headline, which reads as a page that has not loaded. Shallower than a normal
   .pano so it sits under the headline rather than replacing it, and shallower
   again on a phone where vertical space is the scarce thing. */
.shell--strip{ padding-top:0; }
.pano--lede{ aspect-ratio:24/7; min-height:140px; margin-top:clamp(-8px,-0.6vw,0px); }
@media (max-width:700px){ .pano--lede{ aspect-ratio:3/2; } }

/* Contact opens on this kitchen rather than the aerial — an aerial reads as a
   real-estate listing, not design work. Cropped to 24:7 the frame's own centre
   cuts the pendant through the middle of its shade; biasing up to 36% keeps
   the pendant, the backsplash and the island, and still shows the chair backs. */
.pano--kitchen img{ object-position:center 36%; }
@media (max-width:700px){ .pano--kitchen img{ object-position:center 45%; } }

.pano-note{
  display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between;
  gap:18px 48px; margin-top:clamp(22px,2.6vw,34px);
}
.pano-note .prose{ max-width:62ch; }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-foot{ background:var(--pine-deep); color:var(--paper); padding:64px 0 46px; }
.site-foot .shell{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:36px 48px; align-items:start; }
@media (max-width:700px){ .site-foot .shell{ grid-template-columns:1fr; } }
.site-foot .wordmark{ font-family:var(--sans); font-weight:300; line-height:1.3; }
.site-foot .wordmark b{ display:block; font-weight:400; font-size:15px; letter-spacing:.3em; text-transform:uppercase; }
.site-foot .wordmark span{ display:block; font-size:11px; letter-spacing:.34em; text-transform:uppercase; color:#A9BEB0; }
.site-foot .wordmark em{ display:block; margin-top:14px; font-style:normal; font-size:13.5px; letter-spacing:.02em; color:#D7DED8; max-width:30ch; line-height:1.5; }
.foot-detail{ display:flex; flex-direction:column; gap:8px; font-family:var(--sans); font-size:15px; color:#D7DED8; }
.foot-detail a{ align-self:flex-start; color:var(--paper); text-decoration:none; border-bottom:1px solid rgba(245,243,239,.32); }
.foot-detail a:hover{ border-bottom-color:var(--paper); }
.foot-nav ul{ display:flex; flex-wrap:wrap; gap:10px 26px; margin:0; padding:0; list-style:none; }
.foot-nav a{ font-family:var(--sans); font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:#D7DED8; text-decoration:none; }
.foot-nav a:hover{ color:var(--paper); }
.colophon{
  grid-column:1 / -1; margin:16px 0 0; padding-top:24px;
  border-top:1px solid rgba(245,243,239,.16);
  font-family:var(--sans); font-size:12px; letter-spacing:.05em; color:#A9BEB0;
}

/* ==========================================================================
   Stub pages
   ========================================================================== */

.stub{ padding:var(--section) 0; }
.stub .shell{ display:flex; flex-direction:column; gap:26px; max-width:820px; }
.stub .prose{ max-width:60ch; }
.stub-note{
  margin:6px 0 0; padding:22px 26px;
  border:1px solid var(--line); background:var(--paper-2);
  font-family:var(--sans); font-size:14.5px; line-height:1.66; color:var(--ink-2);
}
.stub-note b{ font-weight:500; color:var(--pine); }

/* ==========================================================================
   Phones — body copy sizes up, never down
   ========================================================================== */

@media (max-width:640px){
  :root{ --gutter:20px; }
  body{ font-size:18px; }
  .prose, .steps p{ font-size:18px; line-height:1.7; }
  .caption, .stub-note{ font-size:15px; }
  .quote blockquote{ line-height:1.36; }
}

@media (prefers-reduced-motion:reduce){
  *{ transition:none !important; animation:none !important; }
}

/* ==========================================================================
   Sub-page furniture
   Added when the remaining six pages were built.
   ========================================================================== */

/* --- page hero: a heading block, no photograph behind the type ----------- */
.page-hero{ padding:clamp(56px,7vw,96px) 0 clamp(40px,5vw,64px); border-bottom:1px solid var(--line); }
.page-hero .shell{ display:flex; flex-direction:column; gap:20px; }
.page-hero .prose{ max-width:56ch; }
.page-hero .rule{ max-width:220px; }

/* --- a run of prose with room to breathe --------------------------------- */
.copy{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:clamp(28px,5vw,72px); align-items:start; }
@media (max-width:820px){ .copy{ grid-template-columns:1fr; gap:24px; } }
.copy p + p{ margin-top:18px; }

/* --- a two-up image pair ------------------------------------------------- */
.pair{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:2px; }
.pair figure{ margin:0; position:relative; overflow:hidden; aspect-ratio:3/2; background:var(--paper-2); }
.pair img{ width:100%; height:100%; object-fit:cover; }
.pair figure::after{ content:""; position:absolute; inset:14px; border:1px solid rgba(245,243,239,.34); pointer-events:none; }
@media (max-width:700px){ .pair{ grid-template-columns:1fr; } .pair figure::after{ inset:11px; } }

/* --- the seasonal badge, holiday pages only ------------------------------ */
.badge{ display:block; width:clamp(116px,13vw,164px); height:auto; }
.badge img{ width:100%; height:auto; display:block; }

/* --- gallery: contained, not full bleed ---------------------------------- */
.gallery{
  display:grid; gap:2px;
  grid-template-columns:repeat(auto-fill, minmax(232px, 1fr));
}
.gallery button{
  margin:0; padding:0; border:0; cursor:zoom-in; position:relative;
  overflow:hidden; aspect-ratio:1/1; background:var(--paper-2); display:block;
}
.gallery img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .5s cubic-bezier(.2,0,.2,1); }
.gallery button:hover img{ transform:scale(1.035); }
.gallery button::after{ content:""; position:absolute; inset:12px; border:1px solid rgba(245,243,239,.30); pointer-events:none; }
.gallery button:focus-visible{ outline:2px solid var(--pine); outline-offset:-4px; }
@media (max-width:520px){ .gallery{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

.gallery-head{ display:flex; flex-wrap:wrap; gap:12px 32px; align-items:baseline; justify-content:space-between; margin-bottom:26px; }
.gallery-head h2{ margin:0; }
.gallery-count{ font-family:var(--sans); font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--mute); font-variant-numeric:tabular-nums; }

/* --- lightbox ------------------------------------------------------------ */
.lightbox{
  position:fixed; inset:0; z-index:200; display:none;
  background:rgba(26,24,23,.94);
  align-items:center; justify-content:center;
}
.lightbox[open], .lightbox.is-open{ display:flex; }
.lightbox__frame{
  position:relative; width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
  padding:clamp(48px,7vw,88px) clamp(56px,9vw,120px);
}
.lightbox__frame img{
  max-width:100%; max-height:100%; width:auto; height:auto;
  object-fit:contain; display:block;
}
.lightbox__bar{
  position:absolute; left:0; right:0; bottom:clamp(16px,3vw,30px);
  display:flex; align-items:center; justify-content:center; gap:18px;
  font-family:var(--sans); font-size:11.5px; letter-spacing:.2em;
  text-transform:uppercase; color:#CFCAC5; font-variant-numeric:tabular-nums;
}
.lightbox button{
  background:none; border:1px solid rgba(245,243,239,.3); color:var(--paper);
  cursor:pointer; display:grid; place-items:center; padding:0;
  transition:border-color .18s ease, background .18s ease;
}
.lightbox button:hover{ border-color:var(--paper); background:rgba(245,243,239,.1); }
.lightbox button:focus-visible{ outline:2px solid var(--paper); outline-offset:3px; }
.lightbox svg{ width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.3; }
.lightbox__nav{ position:absolute; top:50%; transform:translateY(-50%); width:52px; height:52px; }
.lightbox__nav--prev{ left:clamp(10px,2vw,26px); }
.lightbox__nav--next{ right:clamp(10px,2vw,26px); }
.lightbox__close{ position:absolute; top:clamp(14px,2.4vw,26px); right:clamp(14px,2.4vw,26px); width:46px; height:46px; }
.lightbox__cap{
  position:absolute; left:0; right:0; top:clamp(18px,3vw,30px);
  text-align:center; font-family:var(--sans); font-size:12px; letter-spacing:.06em;
  color:#CFCAC5; padding:0 90px;
}
body.is-locked{ overflow:hidden; }
@media (max-width:640px){
  .lightbox__frame{ padding:64px 12px 84px; }
  .lightbox__nav{ width:44px; height:44px; }
  .lightbox__cap{ padding:0 64px; font-size:11.5px; }
}

/* --- about --------------------------------------------------------------- */
/* The text column is capped near its measure so the bio does not leave a dead
   third on the right of a wide screen. */
.bio{ display:grid; grid-template-columns:minmax(0,320px) minmax(0,64ch); gap:clamp(30px,5vw,72px); align-items:start; justify-content:start; }
@media (max-width:820px){ .bio{ grid-template-columns:1fr; } }
.portrait{ margin:0; position:relative; aspect-ratio:4/5; background:var(--paper-2); border:1px solid var(--line); }
.portrait img{ width:100%; height:100%; object-fit:cover; display:block; }
.bio__text p{ margin:0; max-width:none; }
.bio__text p + p{ margin-top:20px; }

/* --- testimonials --------------------------------------------------------- */
.reviews{ display:flex; flex-direction:column; gap:2px; }
/* The attribution sits in a left rail on wide screens so the quote runs the
   full width of the card instead of leaving a dead third on the right. */
.review{
  margin:0; background:var(--paper-2); padding:clamp(32px,4.4vw,60px);
  display:grid; grid-template-columns:minmax(0,190px) minmax(0,1fr);
  gap:clamp(20px,3vw,48px); align-items:start;
}
.review blockquote{
  margin:0; grid-column:2; font-family:var(--serif); font-weight:400;
  font-size:clamp(19px,2vw,24px); line-height:1.5; color:var(--ink); max-width:62ch;
}
.review figcaption{
  grid-column:1; grid-row:1; padding-top:.55em;
  font-family:var(--sans); font-size:11.5px; font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; color:var(--mute);
}
@media (max-width:820px){
  .review{ grid-template-columns:1fr; gap:0; }
  .review blockquote{ grid-column:1; grid-row:1; }
  .review figcaption{ grid-column:1; grid-row:2; padding-top:0; margin-top:24px; }
}
.review--lead{ background:var(--pine); }
.review--lead blockquote{ color:var(--paper); }
.review--lead figcaption{ color:#A9BEB0; }

/* --- contact -------------------------------------------------------------- */
.contact{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:clamp(30px,5vw,72px); align-items:start; }
@media (max-width:820px){ .contact{ grid-template-columns:1fr; } }
.contact--single{ grid-template-columns:minmax(0,520px); }
.contact-list{ display:flex; flex-direction:column; gap:2px; }
/* A drawn line icon sits in a left rail of each card, in the same one-stroke
   language as the holiday ornaments. Decorative — the dt already labels it. */
.contact-item{
  background:var(--paper-2); padding:clamp(24px,3vw,34px);
  display:grid; grid-template-columns:34px minmax(0,1fr);
  column-gap:clamp(16px,2vw,24px); row-gap:8px; align-items:center;
}
.contact-icon{
  grid-column:1; grid-row:1 / span 2; align-self:start;
  width:30px; height:30px; color:var(--pine); opacity:.72; margin-top:-2px;
}
.contact-item dt, .contact-item dd{ grid-column:2; }
@media (max-width:420px){
  .contact-item{ grid-template-columns:26px minmax(0,1fr); column-gap:14px; }
  .contact-icon{ width:24px; height:24px; }
}
.contact-item dt{
  font-family:var(--sans); font-size:11px; font-weight:500;
  letter-spacing:.24em; text-transform:uppercase; color:var(--pine);
}
.contact-item dd{ margin:0; }
.contact-item a{
  font-family:var(--sans); font-size:clamp(19px,2.2vw,25px); font-weight:300;
  letter-spacing:.01em; color:var(--ink); text-decoration:none;
  border-bottom:1px solid var(--stone); padding-bottom:3px;
}
.contact-item a:hover{ border-bottom-color:var(--pine); color:var(--pine); }
.contact-item span{ font-family:var(--sans); font-size:17px; color:var(--ink-2); }
