/* ==========================================================================
   BRYDGEWOOD STAIR & RAIL — Design System
   Concept & build for pitch. Hand-coded, framework-free.
   --------------------------------------------------------------------------
   PORTABILITY: All brand decisions live in the :root token block below.
   Drop this file into a WordPress child theme, a Squarespace/Wix custom-CSS
   panel, or keep it as-is for a static site. Blocks are namespaced by
   component (.site-header, .hero, .band, .card, …) and never depend on
   platform markup beyond their own classes.
   ========================================================================== */

/* ---------- 1. DESIGN TOKENS ---------- */
:root{
  /* Brand color — sampled from the approved concept */
  --cream:        #F2EDE2;   /* page ground */
  --cream-soft:   #F7F3EA;   /* raised panels / cards */
  --cream-deep:   #EAE3D3;   /* alternate band */
  --green:        #1E3A2A;   /* deep forest — hero & bands */
  --green-deep:   #162C20;   /* footer bar / hover */
  --green-line:   #2C4A37;   /* hairlines on green */
  --gold:         #C29A45;   /* primary accent, buttons */
  --gold-soft:    #D9B662;   /* gold type on green */
  --gold-pale:    #E7D3A2;   /* subtle gold hairlines */
  --terracotta:   #B34A26;   /* signature accent — steps, labels, CTA */
  --terracotta-deep:#96391B;
  --ink:          #26201A;   /* display headings on cream */
  --body:         #4C4237;   /* body copy on cream */
  --body-soft:    #6B5F51;
  --on-green:     #F4EFE3;   /* copy on green */
  --on-green-soft:#C9C4B4;

  /* Type */
  --font-display: "Playfair Display", "Georgia", "Times New Roman", serif;
  --font-body:    "Inter", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --fs-hero:      clamp(2.9rem, 6.4vw, 4.9rem);
  --fs-h2:        clamp(1.9rem, 3.4vw, 2.7rem);
  --fs-h3:        clamp(1.35rem, 2.2vw, 1.7rem);
  --fs-body:      1.0rem;
  --fs-small:     .875rem;
  --track-caps:   .22em;

  /* Rhythm */
  --space-band:   clamp(4rem, 9vw, 7.5rem);
  --space-gut:    clamp(1.25rem, 3vw, 2.5rem);
  --wrap:         1180px;
  --radius:       2px;

  --shadow-card:  0 18px 50px -18px rgba(38, 32, 26, .28);
  --shadow-img:   0 14px 34px -16px rgba(38, 32, 26, .38);

  /* Subtle topographic texture (matches concept contour lines) */
  --topo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420' viewBox='0 0 420 420'%3E%3Cg fill='none' stroke='%23806a45' stroke-width='1' opacity='.35'%3E%3Cpath d='M-20 330c70-58 150-42 205-78s52-96 132-118 105 10 125-6'/%3E%3Cpath d='M-20 360c80-62 168-44 224-84s58-100 138-120 98 6 118-10'/%3E%3Cpath d='M-20 390c88-64 184-48 240-88s66-104 146-124'/%3E%3Cpath d='M60 430c60-50 128-40 180-76s60-92 136-112'/%3E%3C/g%3E%3C/svg%3E");
}

/* ---------- 2. RESET / BASE ---------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation:none!important; transition:none!important; }
}
body{
  margin:0;
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:1.7;
  color:var(--body);
  background:var(--cream);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img{ max-width:100%; display:block; height:auto; }
a{ color:var(--terracotta); text-decoration:none; }
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible{
  outline:2px solid var(--terracotta); outline-offset:3px;
}
h1,h2,h3,h4{ font-family:var(--font-display); color:var(--ink); line-height:1.15; margin:0 0 .6em; font-weight:600; }
p{ margin:0 0 1.1em; }
.wrap{ width:min(var(--wrap), calc(100% - 2*var(--space-gut))); margin-inline:auto; }

.skip-link{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--green); color:var(--on-green); padding:.7rem 1.2rem;
}
.skip-link:focus{ left:0; }
.visually-hidden{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }

/* ---------- 3. TYPE HELPERS ---------- */
.kicker{
  font-family:var(--font-body); font-size:.78rem; font-weight:600;
  letter-spacing:var(--track-caps); text-transform:uppercase;
  color:var(--terracotta); margin:0 0 1rem;
}
.kicker--gold{ color:var(--gold); }
.rule-above::before{
  content:""; display:block; width:52px; height:2px;
  background:var(--gold); margin-bottom:1.6rem;
}
.h-display{ font-size:var(--fs-h2); }
.lede{ font-size:1.06rem; color:var(--body-soft); }

/* ---------- 4. BUTTONS ---------- */
.btn{
  display:inline-block; font-family:var(--font-body);
  font-size:.8rem; font-weight:600; letter-spacing:.18em; text-transform:uppercase;
  padding:.95rem 1.7rem; border-radius:var(--radius);
  border:1px solid transparent; cursor:pointer;
  transition:background-color .22s ease, color .22s ease, border-color .22s ease, transform .22s ease;
}
.btn:hover{ transform:translateY(-1px); }
.btn--gold{ background:var(--gold); color:#231B10; border-color:var(--gold); }
.btn--gold:hover{ background:#B08A38; }
.btn--terra{ background:var(--terracotta); color:#FBF3E9; border-color:var(--terracotta); }
.btn--terra:hover{ background:var(--terracotta-deep); }
.btn--ghost{ background:transparent; color:var(--on-green); border-color:rgba(244,239,227,.55); }
.btn--ghost:hover{ border-color:var(--on-green); }
.btn--ghost-dark{ background:transparent; color:var(--ink); border-color:rgba(38,32,26,.35); }
.btn--ghost-dark:hover{ border-color:var(--ink); }

.link-more{
  font-size:.8rem; font-weight:600; letter-spacing:.18em; text-transform:uppercase;
  color:var(--terracotta); display:inline-flex; align-items:center; gap:.55rem;
}
.link-more .arrow{ transition:transform .22s ease; }
.link-more:hover .arrow{ transform:translateX(5px); }

/* ---------- 5. HEADER ---------- */
.site-header{
  position:sticky; top:0; z-index:100;
  background:var(--cream);
  border-bottom:1px solid rgba(38,32,26,.08);
  transition:box-shadow .25s ease;
}
.site-header.is-scrolled{ box-shadow:0 10px 30px -18px rgba(38,32,26,.35); }
.site-header__inner{
  display:flex; align-items:center; gap:1.6rem;
  padding:.9rem 0;
  position:relative;
}
.brand{ display:flex; align-items:center; gap:.85rem; color:var(--ink); }
.brand__mark{ width:56px; height:56px; flex:none; display:block; object-fit:contain; }
.brand__name{
  font-family:var(--font-display); font-weight:600;
  font-size:1.06rem; letter-spacing:.12em; line-height:1.25;
}
.brand__sub{
  display:block; font-family:var(--font-body); font-weight:600;
  font-size:.58rem; letter-spacing:.34em; color:var(--body-soft); margin-top:.25rem;
}
.site-nav{ margin-left:auto; }
.site-nav ul{ display:flex; gap:2rem; list-style:none; margin:0; padding:0; }
.site-nav a{
  font-size:.76rem; font-weight:600; letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink); padding:.4rem 0; position:relative;
}
.site-nav a::after{
  content:""; position:absolute; left:0; right:100%; bottom:0;
  height:2px; background:var(--gold); transition:right .22s ease;
}
.site-nav a:hover::after, .site-nav a[aria-current="page"]::after{ right:0; }
.header-cta{ display:flex; align-items:center; gap:1.4rem; }
.header-cta__phone{
  font-family:var(--font-display); font-size:1.02rem; font-weight:600;
  color:var(--terracotta); letter-spacing:.04em; white-space:nowrap;
}
.header-cta .btn{ padding:.75rem 1.25rem; font-size:.72rem; }
.nav-toggle{
  display:none; margin-left:auto;
  background:none; border:0; padding:.5rem; cursor:pointer;
}
.nav-toggle__bar{
  display:block; width:26px; height:2px; background:var(--ink); margin:6px 0;
  transition:transform .25s ease, opacity .25s ease;
}

/* ---------- 6. HERO ---------- */
.hero{ position:relative; background:var(--green); color:var(--on-green); overflow:hidden; }
.hero__media{ position:absolute; inset:0; }
.hero__kb{ position:absolute; inset:0; }
.hero__media img{ display:block; width:100%; height:100%; object-fit:cover; object-position:64% 42%; }
/* Ken Burns — the still breathes so the hero reads as footage without ever
   moving fast enough to look like a loop. It runs on the <img>; the scroll
   parallax below drives .hero__kb, so the two never fight over `transform`.
   All three knobs live here:
   --kb-zoom:  how far it zooms in over one pass (1 = no zoom).
   --kb-drift: how far it slides. Keep it under half the scale overshoot
               (--kb-in minus 1) or an edge shows on mobile, where the
               parallax scale isn't there to hide it.
   --kb-in:    the scale it starts at, i.e. the resting crop.
   --kb-time:  one pass end to end; it alternates, so a full cycle is 2x. */
.hero{ --kb-in:1.02; --kb-zoom:1.10; --kb-drift:0.9%; --kb-time:32s; }
@media (prefers-reduced-motion: no-preference){
  .hero__media img{ animation:hero-kenburns var(--kb-time) ease-in-out infinite alternate; will-change:transform; }
}
@keyframes hero-kenburns{
  from{ transform:scale(var(--kb-in))   translate3d(var(--kb-drift), calc(var(--kb-drift) * .55), 0); }
  to  { transform:scale(var(--kb-zoom)) translate3d(calc(var(--kb-drift) * -1), calc(var(--kb-drift) * -.55), 0); }
}
.hero__scrim{ position:absolute; inset:0;
  background:linear-gradient(100deg, rgba(22,44,32,.55) 0%, rgba(22,44,32,.12) 46%, rgba(22,44,32,0) 62%);
}
.hero__panel{
  position:relative; z-index:2;
  width:min(560px, 92%);
  background:var(--green);
  background-image:var(--topo);
  color:var(--on-green);
  padding:clamp(2.6rem,5vw,4.6rem) clamp(1.6rem,4vw,3.6rem) clamp(4.5rem,7vw,6.5rem);
  min-height:clamp(430px, 58vw, 640px);
  display:flex; flex-direction:column; justify-content:flex-start;
  padding-top:clamp(3.6rem,7vw,6rem);
  clip-path:polygon(0 0, 100% 0, 100% 30%, 90% 30%, 90% 44%, 80% 44%, 80% 58%, 70% 58%, 70% 72%, 60% 72%, 60% 86%, 50% 86%, 50% 100%, 0 100%);
}
.hero__steps{
  position:absolute; z-index:1; pointer-events:none;
  top:0; bottom:0; left:0; width:min(600px, 96%);
}
.hero__steps svg{ width:100%; height:100%; display:block; }
.hero__steps path{ fill:none; stroke:var(--terracotta); stroke-width:2px; vector-effect:non-scaling-stroke; }
/* Both variant rules are written at the same weight as `.hero__steps svg`
   above, or that rule's `display:block` wins and draws both lines at once. */
.hero__steps .hero__steps-v{ animation:steps-climb 2.1s steps(7) .55s both; }
.hero__steps .hero__steps-h{ display:none; }   /* mobile-only — see section 13 */
.hero h1{
  font-size:var(--fs-hero); color:var(--on-green);
  font-weight:500; margin-bottom:1.2rem;
}
.hero h1 em{
  display:block; font-style:italic; color:var(--gold-soft); font-weight:500;
}
.hero__lede{
  max-width:26ch; font-size:1.05rem; color:var(--on-green-soft); margin-bottom:2.2rem;
}
.hero__actions{ display:flex; flex-wrap:wrap; gap:.9rem; }
.hero__actions .btn{ padding:.74rem 1.05rem; font-size:.66rem; letter-spacing:.15em; }

/* ---------- 7. BANDS / SECTIONS ---------- */
.band{ padding-block:var(--space-band); position:relative; }
.band--soft{ background:var(--cream-soft); }
.band--deep{ background:var(--cream-deep); }
.band--green{ background:var(--green); background-image:var(--topo); color:var(--on-green); }
.band--green h2, .band--green h3{ color:var(--on-green); }
.band--green p{ color:var(--on-green-soft); }

.split{ display:grid; grid-template-columns:minmax(300px,5fr) 7fr; gap:clamp(2rem,5vw,4.5rem); align-items:center; }
.split--rev{ grid-template-columns:7fr minmax(300px,5fr); }

/* Our-work mosaic (tall left, wide top-right, two squares) */
.mosaic{ display:grid; gap:clamp(.8rem,1.6vw,1.25rem);
  grid-template-columns:5fr 4fr 4fr; grid-template-rows:auto auto; }
.mosaic__item{ overflow:hidden; box-shadow:var(--shadow-img); height:100%; }
.mosaic__item img{ width:100%; height:100%; object-fit:cover; transition:transform .6s ease; }
.mosaic__item--tall{ align-self:stretch; }
.mosaic__item:hover img{ transform:scale(1.04); }
.mosaic__item--tall{ grid-row:1 / span 2; }
.mosaic__item--wide{ grid-column:2 / span 2; aspect-ratio:16/8.4; }
.mosaic__item--sq{ aspect-ratio:1/1; }

/* Vertical strips (Wood + Metal) */
.strips{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(.8rem,1.6vw,1.25rem); align-items:start; }
.strips figure{ margin:0; overflow:hidden; box-shadow:var(--shadow-img); }
.strips img{ width:100%; aspect-ratio:3/4.6; object-fit:cover; transition:transform .6s ease; }
.strips figure:hover img{ transform:scale(1.04); }
.strips figure:nth-child(2){ margin-top:2.2rem; }
.strips figure:nth-child(4){ margin-top:2.2rem; }

/* Craftsmanship mosaic */
.craft-grid{ display:grid; grid-template-columns:4fr 5fr; gap:clamp(.8rem,1.6vw,1.25rem); }
.craft-grid figure{ margin:0; overflow:hidden; box-shadow:var(--shadow-img); }
.craft-grid img{ width:100%; height:100%; object-fit:cover; }
.craft-grid__a{ aspect-ratio:1/1.35; }
.craft-grid__b{ aspect-ratio:16/9; }
.craft-grid__c{ aspect-ratio:16/10.6; }
.craft-grid__col{ display:flex; flex-direction:column; gap:clamp(.8rem,1.6vw,1.25rem); }

/* Valley band — full-bleed photo on the left, copy on the green */
.valley{ display:grid; grid-template-columns:minmax(260px, 40%) 1fr; align-items:stretch; }
.valley__media{ position:relative; min-height:340px; }
.valley__media img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  clip-path:polygon(0 0, 100% 0, 100% 18%, 90% 18%, 90% 38%, 80% 38%, 80% 58%, 90% 58%, 90% 78%, 100% 78%, 100% 100%, 0 100%); }
.valley__body{ padding-block:var(--space-band);
  padding-left:clamp(2rem,5vw,4.5rem);
  padding-right:max(var(--space-gut), calc((100% - var(--wrap)) / 2));
  display:grid; grid-template-columns:auto minmax(0, 640px); gap:clamp(1.6rem,3vw,3rem); align-items:center; }
.valley__tree{ width:clamp(74px,8vw,108px); color:var(--gold); flex:none; }
.valley__title{ font-size:var(--fs-h2); margin-bottom:1rem; }

/* ---------- 8. CONTACT / FORM ---------- */
.contact-grid{ display:grid; grid-template-columns:5fr 6fr 5fr; gap:clamp(2rem,4vw,3.5rem); align-items:center; }
.contact-sketch{ mix-blend-mode:multiply; } /* on the wrapper: .reveal-img's clip-path isolates the group, so a blend on the img alone can't reach the cream */
.contact-sketch img{ opacity:.92; filter:contrast(1.12); }
.contact-info{ list-style:none; margin:1.6rem 0 0; padding:0; }
.contact-info li{ display:flex; align-items:center; gap:.9rem; margin-bottom:.9rem; font-size:.98rem; }
.contact-info .icon{ width:22px; height:22px; color:var(--gold); flex:none; }
.contact-info a{ color:var(--body); }
.contact-info a:hover{ color:var(--terracotta); }

.form-card{ display:grid; gap:.9rem; }
.form-card .row{ display:grid; grid-template-columns:1fr 1fr; gap:.9rem; }
.form-card label{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
.form-card input, .form-card textarea{
  width:100%; font:inherit; color:var(--ink);
  background:#FDFBF5; border:1px solid rgba(38,32,26,.22); border-radius:var(--radius);
  padding:.85rem 1rem;
}
.form-card input::placeholder, .form-card textarea::placeholder{ color:var(--body-soft); }
.form-card textarea{ min-height:120px; resize:vertical; }
.form-card .btn{ justify-self:start; }
.form-note{ font-size:.8rem; color:var(--body-soft); margin:0; }
.form-status{ font-size:.9rem; font-weight:600; color:var(--green); margin:0; }

/* ---------- 9. FOOTER ---------- */
.site-footer{ background:var(--green-deep); color:var(--on-green); padding:1.4rem 0; }
.site-footer__inner{ display:flex; align-items:center; gap:2rem; flex-wrap:wrap; }
.site-footer .brand{ color:var(--on-green); }
.site-footer .brand__mark{ width:44px; height:44px; }
.site-footer .brand__name{ font-size:.92rem; }
.site-footer .brand__sub{ color:var(--on-green-soft); }
.footer-nav ul{ display:flex; gap:1.7rem; list-style:none; margin:0; padding:0; flex-wrap:wrap; }
.footer-nav a{ font-size:.72rem; font-weight:600; letter-spacing:.2em; text-transform:uppercase; color:var(--on-green); }
.footer-nav a:hover{ color:var(--gold-soft); }
.site-footer__phone{
  margin-left:auto; font-family:var(--font-display); font-size:1.05rem;
  color:var(--gold-soft); border-bottom:1px solid var(--gold-soft); padding-bottom:.2rem; white-space:nowrap;
}
.site-footer__legal{
  width:100%; display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  border-top:1px solid var(--green-line); margin-top:1.1rem; padding-top:1rem;
  font-size:.74rem; color:var(--on-green-soft);
}
.site-footer__legal a{ color:var(--on-green-soft); text-decoration:underline; }

/* ---------- 10. SUBPAGE HERO ---------- */
.page-hero{ background:var(--green); background-image:var(--topo); color:var(--on-green);
  padding:clamp(3rem,7vw,5rem) 0 clamp(3.4rem,7vw,5.4rem); position:relative; overflow:hidden; }
.page-hero h1{ color:var(--on-green); font-size:clamp(2.2rem,4.6vw,3.4rem); font-weight:500; margin-bottom:.6rem; }
.page-hero .kicker{ color:var(--gold-soft); }
.page-hero__lede{ max-width:56ch; color:var(--on-green-soft); font-size:1.05rem; margin:0; }
.page-hero__steps{ position:absolute; right:-2px; top:0; bottom:0; width:min(340px,30vw); pointer-events:none; opacity:.9; }
.page-hero__steps svg{ width:100%; height:100%; display:block; }
.page-hero__steps path{ fill:none; stroke:var(--terracotta); stroke-width:2px; vector-effect:non-scaling-stroke; }
.page-hero__steps svg{ animation:steps-climb 1.7s steps(8) .35s both; }

.band--head{ padding-block:clamp(2.6rem,6vw,4rem); }

/* ---------- 11. GALLERY ---------- */
.filter-bar{ display:flex; flex-wrap:wrap; gap:.6rem; margin:0 0 2.2rem; }
.filter-bar button{
  font:inherit; font-size:.74rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase;
  background:transparent; color:var(--body); border:1px solid rgba(38,32,26,.25);
  border-radius:999px; padding:.55rem 1.15rem; cursor:pointer;
  transition:background-color .2s ease, color .2s ease, border-color .2s ease;
}
.filter-bar button:hover{ border-color:var(--terracotta); color:var(--terracotta); }
.filter-bar button[aria-pressed="true"]{ background:var(--green); border-color:var(--green); color:var(--on-green); }

.gallery{ column-count:3; column-gap:1.1rem; }
.gallery__item{ break-inside:avoid; margin:0 0 1.1rem; position:relative; display:block; width:100%;
  border:0; padding:0; background:none; cursor:zoom-in; overflow:hidden; box-shadow:var(--shadow-img); }
.gallery__item img{ width:100%; transition:transform .5s ease; }
.gallery__item:hover img{ transform:scale(1.035); }
.gallery__cap{
  position:absolute; inset:auto 0 0; padding:2rem .9rem .7rem;
  background:linear-gradient(0deg, rgba(22,44,32,.82), rgba(22,44,32,0));
  color:var(--on-green); font-size:.78rem; letter-spacing:.08em; text-align:left;
  opacity:0; transform:translateY(6px); transition:opacity .3s ease, transform .3s ease;
}
.gallery__item:hover .gallery__cap, .gallery__item:focus-visible .gallery__cap{ opacity:1; transform:none; }
.gallery__item.is-hidden{ display:none; }

/* Lightbox */
.lightbox{ position:fixed; inset:0; z-index:300; display:none;
  background:rgba(22,28,24,.93); align-items:center; justify-content:center; padding:2.5rem; }
.lightbox.is-open{ display:flex; }
.lightbox img{ max-width:min(1100px,92vw); max-height:82vh; width:auto; box-shadow:0 30px 80px rgba(0,0,0,.5); }
.lightbox__cap{ position:absolute; bottom:1.4rem; left:0; right:0; text-align:center;
  color:var(--on-green-soft); font-size:.85rem; letter-spacing:.06em; }
.lightbox button{
  position:absolute; background:none; border:1px solid rgba(244,239,227,.4); color:var(--on-green);
  width:46px; height:46px; border-radius:50%; cursor:pointer; font-size:1.2rem; line-height:1;
  display:flex; align-items:center; justify-content:center; transition:border-color .2s ease;
}
.lightbox button:hover{ border-color:var(--on-green); }
.lightbox__close{ top:1.2rem; right:1.2rem; }
.lightbox__prev{ left:1.2rem; top:50%; transform:translateY(-50%); }
.lightbox__next{ right:1.2rem; top:50%; transform:translateY(-50%); }

/* ---------- 12. CARDS / MISC BLOCKS ---------- */
.card-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(1rem,2.4vw,1.8rem); }
.card{
  background:var(--cream-soft); border:1px solid rgba(38,32,26,.07);
  padding:2rem 1.7rem; box-shadow:var(--shadow-card);
}
.card--green{ background:var(--green); border-color:transparent; }
.card--green h3{ color:var(--on-green); }
.card--green p{ color:var(--on-green-soft); }
.card .num{
  font-family:var(--font-display); font-size:2rem; color:var(--gold);
  display:block; margin-bottom:.7rem; line-height:1;
}
.card h3{ font-size:1.18rem; margin-bottom:.5rem; }
.card p{ font-size:.94rem; margin:0; }

.quote-card{ background:var(--cream-soft); border-left:3px solid var(--gold); padding:1.8rem 1.8rem 1.4rem; position:relative; }
.quote-card blockquote{ margin:0 0 .9rem; font-family:var(--font-display); font-size:1.08rem; font-style:italic; color:var(--ink); }
.quote-card cite{ font-style:normal; font-size:.82rem; letter-spacing:.14em; text-transform:uppercase; color:var(--body-soft); }
.badge-sample{
  display:inline-block; font-size:.62rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  background:var(--terracotta); color:#FBF3E9; border-radius:2px; padding:.28rem .55rem; margin-bottom:.9rem;
}

.placeholder-portrait{
  aspect-ratio:4/5; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1rem;
  background:var(--green); background-image:var(--topo); color:var(--gold-soft);
  box-shadow:var(--shadow-img); text-align:center; padding:1.5rem;
}
.placeholder-portrait .mono{
  font-family:var(--font-display); font-size:3.4rem; font-weight:600;
  width:110px; height:110px; border:2px solid var(--gold-soft); border-radius:50%;
  display:flex; align-items:center; justify-content:center;
}
.placeholder-portrait .note{ font-size:.72rem; letter-spacing:.18em; text-transform:uppercase; color:var(--on-green-soft); }

.maker-photo{ margin:0; aspect-ratio:4/5; overflow:hidden; box-shadow:var(--shadow-img); }
.maker-photo img{ width:100%; height:100%; object-fit:cover; object-position:50% 18%; display:block; }

.stat-row{ display:flex; gap:clamp(1.5rem,5vw,4rem); flex-wrap:wrap; margin-top:2.4rem; }
.stat .stat__n{ font-family:var(--font-display); font-size:2.3rem; color:var(--gold); line-height:1; }
.stat .stat__l{ font-size:.76rem; letter-spacing:.18em; text-transform:uppercase; color:var(--body-soft); margin-top:.45rem; }
.band--green .stat .stat__l{ color:var(--on-green-soft); }

/* CTA band */
.cta-band{ text-align:center; }
.cta-band h2{ font-size:var(--fs-h2); max-width:22ch; margin-inline:auto; }
.cta-band p{ max-width:52ch; margin-inline:auto; }
.cta-band .hero__actions{ justify-content:center; margin-top:2rem; }

/* Step-line walk-down: the staircase lines are monotonic top-to-bottom, so a
   top-down clip sweep reveals them exactly in path order — one stair per
   steps() tick. Runs once on load. Under prefers-reduced-motion, animations
   are stripped and the un-clipped line rests fully drawn. */
@keyframes steps-climb{ from{ clip-path:inset(0 0 100% 0); } to{ clip-path:inset(0 0 0 0); } }
/* Sideways variants for the mobile step-lines, which run across the screen
   rather than down it. The home hero's mobile line is drawn right-to-left
   (its path starts at x=100); the sub-page line left-to-right. Same idea:
   the sweep follows the path's own direction, one stair per steps() tick. */
@keyframes steps-walk-rtl{ from{ clip-path:inset(0 0 0 100%); } to{ clip-path:inset(0 0 0 0); } }
@keyframes steps-walk-ltr{ from{ clip-path:inset(0 100% 0 0); } to{ clip-path:inset(0 0 0 0); } }

/* ---------- 12b. MOTION & SCROLL LAYER ----------
   Progressive enhancement only. A one-line inline script in each page's
   <head> adds a `js` class to <html>; every "hidden until revealed" state
   below is scoped to `.js`, so with scripts off the site renders fully and
   statically. The reduced-motion block at the end flattens all of it. */
:root{ --ease-out:cubic-bezier(.2,.7,.2,1); }

/* Header compacts once the page is scrolled */
.site-header__inner{ transition:padding .3s ease; }
.brand__mark{ transition:width .3s ease, height .3s ease; }
.site-header.is-scrolled .site-header__inner{ padding:.5rem 0; }
.site-header.is-scrolled .brand__mark{ width:38px; height:38px; }

/* Block reveal — text and cards fade up. --d is a per-item delay set by JS
   for children of [data-stagger] / [data-cascade] containers. */
.js .reveal, .js .reveal-item{
  opacity:0; transform:translateY(26px);
  transition:opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay:var(--d, 0ms);
}
.js .reveal.is-visible, .js .reveal-item.is-visible, .js .is-visible .reveal-item{ opacity:1; transform:none; }

/* Photo reveal — a top-down curtain wipe while the image settles out of a
   slight zoom. The open state uses negative insets so the box-shadow is
   not clipped once the wipe completes. (Chrome applies an element's own
   clip-path to IntersectionObserver, so individually observed photos are
   watched at threshold 0 — see main.js.) */
.js .reveal-img{
  clip-path:inset(0 -60px 100% -60px);
  transition:clip-path 1.05s var(--ease-out);
  transition-delay:var(--d, 0ms);
}
.js .reveal-img.is-visible, .js .is-visible .reveal-img{ clip-path:inset(-60px -60px -60px -60px); }
.js .reveal-img.is-visible img, .js .is-visible .reveal-img img{
  animation:img-settle 1.4s var(--ease-out) var(--d, 0ms) backwards;
}
@keyframes img-settle{ from{ transform:scale(1.12); } to{ transform:none; } }

/* The gold rule above a heading draws in with it */
.js .reveal.rule-above::before, .js .reveal .rule-above::before{
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform .9s var(--ease-out) .3s;
}
.js .reveal.is-visible.rule-above::before, .js .reveal.is-visible .rule-above::before{ transform:scaleX(1); }

/* Line-drawn SVG glyphs — dash lengths are measured and set by JS */
.js .draw path{ transition:stroke-dashoffset 1.1s var(--ease-out); }

/* Home hero — photo and panel drift at different speeds as you scroll off
   the top (JS feeds --py / --pp). The scale gives the photo room to move
   without exposing an edge. */
@media (min-width:821px){
  .js .hero__kb{ transform:translate3d(0, var(--py, 0px), 0) scale(var(--hero-zoom, 1.15)); will-change:transform; }
  .js .hero__panel, .js .hero__steps{ transform:translate3d(0, var(--pp, 0px), 0); }
}
/* Phones get the drift too, but smaller and on the photo alone: the panel is
   in normal flow there and the step-line is pinned to the seam between the
   two, so moving either would pull the notched edge off its line. The gentler
   1.08 keeps the mobile crop close to the Ken Burns resting frame above; JS
   caps the travel to the slack that leaves. */
@media (max-width:820px){
  .js .hero__kb{ transform:translate3d(0, var(--py, 0px), 0) scale(var(--hero-zoom, 1.08)); will-change:transform; }
}
.hero__cue{
  /* sits in the green panel's bottom-left, aligned with its text inset */
  position:absolute; z-index:3; left:clamp(1.6rem,4vw,3.6rem); bottom:2rem;
  display:flex; flex-direction:column; align-items:center; gap:.8rem;
  color:var(--on-green-soft); font-size:.62rem; font-weight:600; letter-spacing:.32em; text-transform:uppercase;
  transition:opacity .5s ease, transform .5s ease;
}
.hero__cue i{ display:block; width:1px; height:58px; background:rgba(244,239,227,.3); position:relative; overflow:hidden; }
.hero__cue i::after{
  content:""; position:absolute; left:0; top:0; width:100%; height:100%;
  background:var(--gold-soft); transform:translateY(-100%);
  animation:cue-drop 2.2s var(--ease-out) 1.2s infinite;
}
@keyframes cue-drop{ to{ transform:translateY(100%); } }
body.is-scrolled .hero__cue{ opacity:0; transform:translateY(10px); pointer-events:none; }

/* Materials ticker — a quiet tonal band of type that glides sideways as the
   page scrolls (scroll-driven with easing; it rests when the reader rests). */
.ticker{ background:var(--cream-deep); overflow:hidden; padding:.85rem 0; border-block:1px solid var(--gold-pale); }
.ticker__track{ display:flex; width:max-content; will-change:transform; }
.ticker__set{
  display:flex; align-items:center; gap:1.4rem; padding-right:1.4rem; white-space:nowrap;
  font-family:var(--font-display); font-style:italic; font-weight:500;
  font-size:clamp(1.35rem,2.6vw,2.1rem); line-height:1.3; color:var(--green);
}
.ticker__set i{ font-style:normal; color:var(--terracotta); font-size:.38em; opacity:.85; }

/* How-we-work story — the photo stays pinned while the steps scroll past it,
   and swaps to match whichever step is in the middle of the screen. */
.story{ display:grid; grid-template-columns:5fr 6fr; gap:clamp(2rem,5vw,4.5rem); align-items:start; margin-top:2.4rem; }
.story__media{ position:sticky; top:calc(var(--header-h, 56px) + 1.5rem); }
.story__frame{ margin:0; position:relative; aspect-ratio:4/5; overflow:hidden; background:var(--green); box-shadow:var(--shadow-img); }
.story__img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transform:scale(1.06);
  transition:opacity .8s ease, transform 1.6s var(--ease-out);
}
.story__img.is-active{ opacity:1; transform:none; }
.story__counter{
  position:absolute; left:1rem; bottom:1rem; z-index:2; margin:0;
  font-family:var(--font-display); font-size:.9rem; letter-spacing:.14em;
  color:var(--on-green-soft); background:rgba(22,44,32,.78);
  padding:.3rem .65rem; border-radius:2px;
}
.story__counter b{ color:var(--gold-soft); font-weight:600; }
.story__steps{ list-style:none; margin:0; padding:clamp(1rem,8vh,4rem) 0; display:flex; flex-direction:column; gap:clamp(2rem,12vh,7rem); }
.story__step{ border-left:3px solid transparent; }
.js .reveal.story__step{ transition:opacity .8s var(--ease-out), transform .8s var(--ease-out), border-color .5s ease; }
.story__step .num{ transition:color .4s ease; }
.story__step.is-active{ border-left-color:var(--terracotta); }
.story__step.is-active .num{ color:var(--terracotta); }

@media (prefers-reduced-motion: reduce){
  .js .reveal, .js .reveal-item{ opacity:1; transform:none; }
  .js .reveal-img, .js .reveal-img.is-visible, .js .is-visible .reveal-img{ clip-path:none; }
  .js .reveal.rule-above::before, .js .reveal .rule-above::before{ transform:none; }
  .js .hero__kb{ transform:scale(var(--hero-zoom, 1)); }
  .hero__cue{ display:none; }
}

/* ---------- 12c. FOLDER STACK ("What we build") ----------
   A full-height photo intro pins at the top of the viewport; three folder
   cards then slide up over it and park at the centre, each with its tab in
   a different third so the tabs fan out like a filing cabinet as the stack
   builds. Pure CSS position:sticky — no JS, no library — and it degrades
   to a plain stack of cards anywhere sticky is unsupported. */
.folders{ position:relative; --tab-h:2.6rem; --folder-radius:14px; --stage:100vh; }
.folders__intro{
  position:sticky; top:0; z-index:1;
  height:var(--stage);
  display:flex; align-items:center;
  background:var(--green); color:var(--on-green); overflow:hidden;
}
.folders__intro > img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 40%; }
.folders__scrim{ position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(22,44,32,.86) 0%, rgba(22,44,32,.62) 48%, rgba(22,44,32,.38) 100%); }
.folders__intro-body{ position:relative; z-index:1; padding-block:clamp(5rem,12vh,8rem); max-width:var(--wrap); }
.folders__intro-body h2{ color:var(--on-green); font-size:clamp(2.2rem,4.8vw,3.6rem); font-weight:500; max-width:16ch; margin-bottom:1rem; }
.folders__intro-body h2 em{ font-style:italic; color:var(--gold-soft); }
.folders__intro-body p{ color:var(--on-green-soft); max-width:46ch; font-size:1.05rem; margin:0; }
.folders__intro-body .kicker{ color:var(--gold-soft); }

.folders__stack{ position:relative; padding-top:12vh; }
/* Sticky boxes are constrained to the container's content box, so padding
   can't hold the finished stack on screen — a real spacer element can. */
.folders__dwell{ height:40vh; }
/* Each folder is a viewport-tall sticky box, transparent apart from the card
   itself, so its sticky range ends exactly where the intro's does: the
   finished stack and the photo behind it leave the screen together instead
   of the cards lifting first and exposing the intro copy. */
.folder{
  position:sticky; top:0; height:var(--stage);
  display:flex; align-items:center;
  padding-top:var(--header-h, 56px);
  pointer-events:none;
}
.folder__inner{ position:relative; width:100%; padding-top:var(--tab-h); pointer-events:auto; }
.folder--1{ z-index:2; --folder-bg:var(--cream-soft); --folder-ink:var(--ink); --folder-soft:var(--body); --folder-accent:var(--terracotta); --folder-line:rgba(38,32,26,.14); }
.folder--2{ z-index:3; --folder-bg:var(--green);      --folder-ink:var(--on-green); --folder-soft:var(--on-green-soft); --folder-accent:var(--gold-soft); --folder-line:var(--green-line); }
.folder--3{ z-index:4; --folder-bg:var(--terracotta-deep); --folder-ink:#FBF3E9; --folder-soft:#F0D8C6; --folder-accent:var(--gold-pale); --folder-line:rgba(251,243,233,.22); }
.folder__tab{
  position:absolute; top:0; height:calc(var(--tab-h) + 2px); width:34%;
  margin:0; display:flex; align-items:center; justify-content:center;
  background:var(--folder-bg); color:var(--folder-ink);
  border-radius:var(--folder-radius) var(--folder-radius) 0 0;
  font-family:var(--font-body); font-size:.72rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase;
  box-shadow:0 -12px 30px -18px rgba(0,0,0,.45);
}
.folder__tab b{ color:var(--folder-accent); font-weight:700; margin-right:.5em; }
.folder--1 .folder__tab{ left:0; }
.folder--2 .folder__tab{ left:33%; }
.folder--3 .folder__tab{ left:66%; }
.folder__body{
  position:relative; background:var(--folder-bg); color:var(--folder-soft);
  border-radius:var(--folder-radius);
  padding:clamp(1.4rem,3.4vw,3rem);
  display:grid; grid-template-columns:5fr 6fr; gap:clamp(1.5rem,4vw,3.5rem); align-items:center;
  box-shadow:0 30px 70px -30px rgba(0,0,0,.55);
}
.folder--1 .folder__body{ border-top-left-radius:0; }
.folder--3 .folder__body{ border-top-right-radius:0; }
.folder__media{ margin:0; aspect-ratio:4/3; overflow:hidden; border-radius:4px; }
.folder__media img{ width:100%; height:100%; object-fit:cover; }
.folder__copy h3{ color:var(--folder-ink); font-size:clamp(1.7rem,3vw,2.5rem); font-weight:500; line-height:1.1; margin-bottom:.8rem; }
.folder__copy h3 em{ font-style:italic; color:var(--folder-accent); }
.folder__copy p{ color:var(--folder-soft); margin-bottom:1.2rem; }
.folder__specs{
  list-style:none; margin:0 0 1.6rem; padding:1rem 0 0; border-top:1px solid var(--folder-line);
  display:flex; flex-wrap:wrap; gap:.4rem 1.1rem;
  font-size:.74rem; font-weight:600; letter-spacing:.14em; text-transform:uppercase; color:var(--folder-ink);
}
.folder__specs li{ display:flex; align-items:center; gap:.7rem; }
.folder__specs li + li::before{ content:"\25C6"; font-size:.5em; color:var(--folder-accent); }
.folder--3 .btn--ghost{ color:#FBF3E9; border-color:rgba(251,243,233,.55); }
.folder--3 .btn--ghost:hover{ border-color:#FBF3E9; }

@media (max-height:700px){
  .folder__media{ aspect-ratio:16/10; }
  .folder__body{ padding:clamp(1.2rem,2.5vw,1.8rem); }
  .folder__copy p{ margin-bottom:.9rem; }
}

/* ---------- 13. RESPONSIVE ---------- */
@media (max-width: 1020px){
  .site-nav ul{ gap:1.3rem; }
  .header-cta__phone{ display:none; }
  .contact-grid{ grid-template-columns:1fr 1fr; }
  .contact-sketch{ display:none; }   /* no room beside the form at this width */
  .gallery{ column-count:2; }
}
@media (max-width: 820px){
  .site-nav, .header-cta{ display:none; }
  .nav-toggle{ display:block; }
  body.nav-open .site-nav{
    display:block; position:absolute; left:0; right:0; top:100%; margin-left:0;
    background:var(--cream); border-bottom:1px solid rgba(38,32,26,.1);
    padding:1rem var(--space-gut) 1.6rem; box-shadow:0 24px 40px -20px rgba(38,32,26,.35);
  }
  body.nav-open .site-nav ul{ flex-direction:column; gap:.4rem; }
  body.nav-open .site-nav a{ display:block; padding:.7rem 0; font-size:.85rem; }
  body.nav-open .nav-toggle__bar:nth-child(1){ transform:translateY(8px) rotate(45deg); }
  body.nav-open .nav-toggle__bar:nth-child(2){ opacity:0; }
  body.nav-open .nav-toggle__bar:nth-child(3){ transform:translateY(-8px) rotate(-45deg); }

  /* --- Home hero: the notched green overlap, turned on its side ---------
     The desktop hero is side-by-side — a green panel with a stepped right
     edge sitting over the photo, the terracotta step-line tracing that edge.
     Stacked on a phone there is no room for that, so the same three moves
     are rotated a quarter turn: the panel keeps its stepped edge but along
     the BOTTOM, a negative margin pulls the photo up so the notches are
     filled by the picture rather than by flat green, and the step-line is
     re-aimed across that seam. --stair is the height of the stepped band;
     --media-h has to be a single value (not height + min-height) because the
     step-line is positioned off it. */
  .hero{ display:flex; flex-direction:column-reverse;
    --stair:clamp(58px, 17vw, 84px); --media-h:max(58vw, 290px); }
  .hero__panel{
    width:100%; min-height:0;
    padding-block:3.4rem calc(2.6rem + var(--stair));
    margin-bottom:calc(var(--stair) * -1);
    clip-path:polygon(
      0 0, 100% 0,
      100% calc(100% - var(--stair)),
      75%  calc(100% - var(--stair)),
      75%  calc(100% - var(--stair) * .667),
      50%  calc(100% - var(--stair) * .667),
      50%  calc(100% - var(--stair) * .333),
      25%  calc(100% - var(--stair) * .333),
      25%  100%,
      0    100%);
  }
  .hero__media{ position:relative; height:var(--media-h); }
  .hero__scrim{ display:none; }
  /* Sits over the stepped band: its bottom edge is the panel's bottom edge,
     which the negative margin above put --stair into the photo. It is then
     nudged down and right by --step-offset so the line reads as an echo
     dropped off the notch rather than an outline welded to it. The path runs
     a few units past the left of its viewBox (and the svg is allowed to spill)
     so the offset never leaves a stub of bare edge at the bottom-left. */
  .hero__steps{
    display:block; z-index:3;
    top:auto; bottom:calc(var(--media-h) - var(--stair));
    left:0; width:100%; height:var(--stair);
    --step-offset:clamp(4px, 1.5vw, 8px);
    transform:translate(var(--step-offset), var(--step-offset));
  }
  .hero__steps .hero__steps-v{ display:none; }
  .hero__steps .hero__steps-h{
    display:block; overflow:visible;
    animation:steps-walk-rtl 1.5s steps(4) .5s both;
  }

  .split, .split--rev{ grid-template-columns:1fr; }
  .split--rev > :last-child{ order:-1; }

  /* --- Staggered image groups ------------------------------------------
     Every mosaic on the site used to flatten to one full-width column on a
     phone, which reads as a stock photo list. They stay two-column instead,
     with the second column dropped by --offset so the group keeps the
     offbeat rhythm it has on desktop. */
  .mosaic{ grid-template-columns:1fr 1fr; align-items:start; --offset:clamp(1.2rem,6vw,2.4rem); }
  .mosaic__item--tall{ grid-column:1; grid-row:1 / span 2; align-self:stretch; aspect-ratio:auto; }
  .mosaic__item--tall img{ height:100%; }
  .mosaic__item--wide{ grid-column:2; grid-row:1; aspect-ratio:4/3; margin-top:var(--offset); }
  .mosaic__item:nth-child(3){ grid-column:2; grid-row:2; margin-top:var(--offset); }
  .mosaic__item:nth-child(4){ grid-column:1 / -1; aspect-ratio:16/9; }

  .strips{ grid-template-columns:1fr 1fr; align-items:start; }
  .strips figure:nth-child(2), .strips figure:nth-child(4){ margin-top:clamp(1.4rem,7vw,2.6rem); }

  .craft-grid{ grid-template-columns:4fr 5fr; align-items:start; }
  .craft-grid__a{ aspect-ratio:3/4.4; }
  .craft-grid__b, .craft-grid__c{ aspect-ratio:4/3; }
  .craft-grid__col{ margin-top:clamp(1.4rem,7vw,2.6rem); }

  /* --- Valley band: same notch, rotated ---------------------------------
     Desktop steps the photo's right edge into the green; stacked, it steps
     the bottom edge instead, so the green still climbs into the picture. */
  .valley{ grid-template-columns:1fr; }
  .valley__media{ min-height:250px; height:58vw; --stair:clamp(44px,12vw,64px); }
  .valley__media img{
    clip-path:polygon(
      0 0, 100% 0,
      100% calc(100% - var(--stair)),
      75%  calc(100% - var(--stair)),
      75%  calc(100% - var(--stair) * .667),
      50%  calc(100% - var(--stair) * .667),
      50%  calc(100% - var(--stair) * .333),
      25%  calc(100% - var(--stair) * .333),
      25%  100%,
      0    100%);
  }
  .valley__body{ padding:2.6rem var(--space-gut); grid-template-columns:1fr; }
  .valley__tree{ width:64px; }
  .contact-grid{ grid-template-columns:1fr; }
  /* Once the grid stacks there IS room again, so the animated stair sketch
     comes back — sized down and centred between the copy and the form. It
     stays lazy-loaded, so the GIF only costs anything once it is scrolled to. */
  .contact-sketch{ display:block; width:min(300px, 72%); margin:.4rem auto 1.6rem; }
  .card-grid{ grid-template-columns:1fr; }
  .site-footer__inner{ justify-content:center; text-align:center; }
  .site-footer__phone{ margin-left:0; }
  .site-footer__legal{ justify-content:center; text-align:center; }

  /* Sub-page step-line: too narrow to run down the right edge, so it walks
     across the foot of the green band instead. Extra padding keeps the lede
     clear of it. */
  .page-hero{ padding-bottom:calc(2.6rem + clamp(56px,15vw,88px)); }
  .page-hero__steps{
    left:0; right:auto; width:100%;
    top:auto; bottom:0; height:clamp(56px,15vw,88px);
  }
  .page-hero__steps svg{ animation:steps-walk-ltr 1.4s steps(8) .35s both; }

  .hero__cue{ display:none; }
  .story{ display:block; }
  .story__media{ top:var(--header-h, 56px); z-index:2; background:var(--cream-soft); padding-bottom:.9rem; }
  .story__frame{ aspect-ratio:16/10; max-height:34vh; }
  .story__steps{ padding:1.2rem 0 0; gap:1.4rem; }

  .folders{ --tab-h:2.2rem; --folder-radius:10px; }
  .folder{ align-items:flex-start; padding-top:calc(var(--header-h, 56px) + .75rem); background:var(--folder-bg); }
  .folder + .folder{ margin-top:10vh; }
  .folders__stack{ padding-top:6vh; }
  .folders__dwell{ height:26vh; }
  .folder__tab{ font-size:.6rem; letter-spacing:.12em; }
  .folder__body{ grid-template-columns:1fr; gap:1.1rem; padding:1.1rem; }
  .folder__media{ aspect-ratio:16/9; max-height:30vh; }
  .folder__copy h3{ font-size:1.6rem; }
  .folder__copy p{ font-size:.94rem; }
  .folder__specs{ margin-bottom:1.1rem; }
}
@media (max-width: 560px){
  .brand__mark{ width:48px; height:48px; }
  .brand{ gap:.7rem; }
  .form-card .row{ grid-template-columns:1fr; }
  /* The gallery stays a two-column masonry rather than collapsing to a
     single stack — the uneven column ends are the whole point of it. */
  .gallery{ column-count:2; column-gap:.7rem; }
  .gallery__item{ margin-bottom:.7rem; }
  .gallery__cap{ font-size:.68rem; padding:1.4rem .6rem .5rem; }
  .mosaic, .strips, .craft-grid{ gap:.7rem; }
}
@media (max-width: 380px){
  .gallery{ column-count:1; }
}

/* ---------- 14. PRINT ---------- */
@media print{
  .site-header, .site-footer, .nav-toggle, .lightbox, .hero__cue, .ticker{ display:none; }
  .js .reveal, .js .reveal-item{ opacity:1; transform:none; }
  .js .reveal-img{ clip-path:none; }
  .folders__intro, .folder{ position:static; height:auto; padding-top:0; }
  body{ background:#fff; color:#000; }
}
