/* ==========================================================
   CURATED BY CARRIE
   ----------------------------------------------------------
   SPACING RULES:
     rem    -> all margin and padding, from --space-*
     px     -> borders, hairlines, radii ONLY
     %      -> widths inside a container
     clamp()-> hero type only (kept minimal on purpose)
     cqi    -> Contact arch only (sizes locked to the photo)
   ========================================================== */

:root {

  /* ---- Colour ---- */
  --burgundy:  #3C0625;
  --cream:     #FFFFFF;
  --sage:      #7C949C;
  --gold:      #95773B;
  --olive:     #3D4435;
  --ink:       #252222;
  --ink-soft:  #6B625C;
  --rule:      #D8D1C6;

  /* ---- Spacing scale ---- */
  --space-xs:  0.5rem;
  --space-sm:  1rem;
  --space-s:   1rem;
  --space-md:  2rem;
  --space-lg:  3rem;
  --space-xl:  5rem;
  --space-2xl: 8rem;

  --section-pad-y: clamp(6rem, 8vw, 10rem);
  --section-pad-x: clamp(1.5rem, 5vw, 6rem);

  /* ---- Layout ---- */
  --measure:   98rem;
  --measure-page: 78rem;   /* narrower column for Portfolio + project pages */
  --ba-fade:   350ms;      /* before/after toggle crossfade */

  /* ---- project thumb grid ----
     0.25rem is 4px on the default root size, so this stays on the
     rem spacing scale rather than being a stray pixel value. */
  --thumb-columns: 3;
  --thumb-gap:     0.25rem;

  /* ---- project page lead photo + title ---- */
  --lead-inset-top:       6rem;    /* cream band above the lead photo */
  --project-title-y: clamp(6rem, 22%, 18rem);     /* title's vertical spot on the photo */
  --project-title-color:  var(--cream);
  --title-rule-max:       12rem;   /* longest a flanking rule will get */
  --title-rule-gap:       2rem;    /* space between rule and text */
  --title-rule-thickness: 2px;
  --title-rule-opacity:   0.7;
  
/* ---- portfolio grid ---- */
  --card-columns:   3;
  --card-gap:       0.5rem;
  --card-title-y:   3rem;     /* title's distance from top of the card */
  --card-rule-max:  5rem;     /* flanking rules, shorter than the lead photo's */
  --card-rule-gap:  1rem;
  --card-fade:      rgba(60, 6, 37, 0.55);

  /* ---- services ---- */
  --svc-columns:    3;
  --svc-gap-x:      clamp(2rem, 4vw, 5rem);   /* columns tighten as the viewport shrinks */
  --svc-gap-y:      var(--space-xl);
  --svc-icon:       clamp(6rem, 9vw, 10rem);  /* icon width, scales with viewport */
  --svc-rule-max:   4rem;                     /* flanking rules on each heading */
  --svc-rule-gap:   1rem;
  --svc-pad-top:    clamp(10rem, calc(12vw + 2rem), 18rem);
  --card-cta-size:  0.9rem;
  --nav-h:     9rem;       /* fixed nav clearance — nudge to taste.
                              Roughly logo height + bar padding. If you
                              change --nav-logo-width, revisit this. */

  /* ---- Type ---- */
  --font-display: "Cormorant Garamond", Georgia, serif;
  --font-nav:     "Raleway", system-ui, sans-serif;
  --font-body:    "DM Sans", system-ui, sans-serif;

  --type-hero:  clamp(2.5rem, 6vw, 5rem);
  --type-h2:    clamp(1.75rem, 3.5vw, 2.75rem);
  --type-body:  clamp(1rem, 1.1vw, 1.125rem);
  --type-small: 0.9375rem;
}


/* ==========================================================
   RESET / BASE
   ========================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--sage);
  outline-offset: 3px;
}

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


/* ==========================================================
   HEADER / NAV — LEVERS
   Every number below is yours to nudge directly.
   ========================================================== */

:root {
  --nav-bar-padding-top:    0.75rem;
  --nav-bar-padding-bottom: 0.75rem;

  /* Logo. px on purpose — this is an image dimension, not spacing.
     Source art is 568px wide, so 285px is the crisp-on-retina ceiling.
     Try 200px, then 285px, and see which you like. */
  --nav-logo-width:         200px;

  --nav-logo-gap:           2rem;      /* logo -> start of the nav links */
  --nav-links-offset:       2rem;      /* extra push of the link group to the right */
  --nav-links-gap:          2.5rem;    /* space between Portfolio / Services / etc */
  --nav-links-size:         1.3rem;    /* nav link type size */
  --nav-active-scale: 1.18;   /* how much the active link inflates */
  --nav-shrink:       0.62;   /* how small it goes while moving */
  --nav-shrink-speed: 0.25s;

  /* Blur behind the bar. Off over the hero, on everywhere else. */
  --nav-blur:               14px;
}

/* Single .site-header rule. Everything that was split across three
   separate blocks now lives here — including --nav-ink and the full
   transition list. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: transparent;
  padding-top: var(--nav-bar-padding-top);
  padding-bottom: var(--nav-bar-padding-bottom);
  --nav-ink: var(--cream);
  transition: color 0.4s ease, backdrop-filter 0.4s ease;
}

/* Blur kicks in only once we've scrolled off the hero. */
.site-header.nav-dark {
  backdrop-filter: blur(var(--nav-blur));
  -webkit-backdrop-filter: blur(var(--nav-blur));
  --nav-ink: var(--burgundy);
}
/* ...except over a section tagged data-nav-blur="off" (Contact).
   The wall photo is busy enough; the blur muddies it. */
.site-header.nav-clear {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* Over Contact the form is the CTA — the bar button just competes. */
.site-header.nav-clear > .header-inner > .btn-talk {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}
.header-inner {
  position: relative;
  max-width: var(--measure);
  margin: 0 auto;
  padding-left: var(--section-pad-x);
  padding-right: var(--section-pad-x);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--nav-logo-gap);
  transition: transform var(--nav-shrink-speed) ease,
              opacity   var(--nav-shrink-speed) ease;
}

/* Two stacked PNGs — cream over the hero, burgundy after. Both are
   always in the DOM so the swap is a fade, not a flash of nothing. */
.nav-logo {
  position: relative;
  display: block;
  flex: 0 0 auto;
  width: var(--nav-logo-width);
  aspect-ratio: 568 / 329;
}

.nav-logo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 0.4s ease;
}

.logo-dark { opacity: 0; }

.site-header.nav-dark .logo-light { opacity: 0; }
.site-header.nav-dark .logo-dark  { opacity: 1; }

.site-nav { margin-left: var(--nav-links-offset); }

.nav-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--nav-links-gap);
}

/* Merged — this was two separate .nav-link rules. */
.nav-link {
  display: inline-block;
  font-family: var(--font-nav);
  font-size: var(--nav-links-size);
  color: var(--nav-ink);
  padding: var(--space-xs) 0;
  border-bottom: 1px solid transparent;
  transform-origin: center bottom;
  transition: border-color 0.2s ease, opacity 0.2s ease, transform 0.3s ease;
}

.nav-link:hover { opacity: 0.7; }

.nav-link.is-active {
  transform: scale(var(--nav-active-scale));
  border-bottom-color: var(--nav-ink);
}

.btn-talk {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--font-nav);
  font-size: var(--type-small);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nav-ink);
  padding: var(--space-xs) var(--space-md);
  border: 1px solid var(--nav-ink);
  border-radius: 999px;
  white-space: nowrap;
  transition: background-color 0.25s ease,
              border-color 0.25s ease,
              color 0.25s ease;
}

/* Filled by default: burgundy fill, cream outline and type. */
.site-header.nav-dark .btn-talk {
  background: var(--burgundy);
  border-color: var(--cream);
  color: var(--cream);
}

/* Hover empties it out. */
.site-header.nav-dark .btn-talk:hover {
  background: var(--cream);
  border-color: var(--burgundy);
  color: var(--burgundy);
}
.site-header.is-scrolling .header-inner {
  transform: translateY(-120%);
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .site-header.is-scrolling .header-inner { transform: none; opacity: 1; }
}
/* ==========================================================
   BURGER NAV — LEVERS
   Burger shows on phones + tablet portrait. Tablet landscape
   and up keep the desktop bar. The breakpoint lives in the
   single @media line below (CSS can't put it in a variable).
   ========================================================== */

:root {
  /* Bar, in burger mode */
  --burger-logo-width:   clamp(100px, 30vw, 140px);  /* bar logo, scales with screen. px: image dimension */
  --burger-bar-gap:      1rem;     /* logo / CTA / burger spacing */

  /* Burger icon */
  --burger-size:         1.75rem;  /* line length */
  --burger-line-gap:     0.4rem;   /* space between lines */
  --burger-line:         2px;      /* line thickness */

  /* Overlay */
  --overlay-opacity:     96%;      /* 100% = solid burgundy */
  --overlay-blur:        10px;     /* blurs the page behind; only shows below 100% */
  --overlay-logo-width:  160px;    /* centered logo. px on purpose: image dimension */
  --overlay-logo-gap:    3rem;     /* logo -> first link */
  --overlay-cta-gap:     3rem;     /* last link -> CTA */
  --overlay-links-gap:   1.5rem;   /* between links */
  --overlay-links-size:  1.75rem;
  --overlay-speed:       0.3s;
}

/* Desktop: burger and overlay logo stay hidden. */
.nav-burger,
.menu-logo,
.menu-cta { display: none; }

@media (max-width: 1032px) and (orientation: portrait), (max-width: 960px) {

  /* ---- bar ---- */
  .site-header {
    --nav-logo-width: var(--burger-logo-width);
    --nav-logo-gap:   var(--burger-bar-gap);
  }

  .nav-logo {
    z-index: 2;
    transition: opacity var(--overlay-speed) ease;
  }

  /* Bar CTA hides; its twin (.menu-cta) sits in the overlay. */
  .header-inner > .btn-talk { display: none; }

  /* ---- burger button (44px tap target) ---- */
  .nav-burger {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    margin-left: auto;                 /* pins it to the right edge */
    position: relative;
    z-index: 2;
    width: calc(var(--burger-size) + var(--space-sm));
    aspect-ratio: 1;
    padding: 0;
    border: 0;
    background: none;
    color: var(--nav-ink);
    cursor: pointer;
  }

  .nav-burger-lines,
  .nav-burger-lines::before,
  .nav-burger-lines::after {
    display: block;
    width: var(--burger-size);
    height: var(--burger-line);
    background: currentColor;
    transition: transform var(--overlay-speed) ease,
                background-color var(--overlay-speed) ease;
  }

  .nav-burger-lines { position: relative; }

  .nav-burger-lines::before,
  .nav-burger-lines::after {
    content: "";
    position: absolute;
    left: 0;
  }

  .nav-burger-lines::before { top: calc(-1 * (var(--burger-line-gap) + var(--burger-line))); }
  .nav-burger-lines::after  { top: calc(var(--burger-line-gap) + var(--burger-line)); }

  /* ---- overlay (the nav itself, pulled full-screen) ---- */
  .site-nav {
    position: fixed;
    inset: 0;
    z-index: 1;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--space-xl) var(--section-pad-x);
    background: color-mix(in srgb, var(--burgundy) var(--overlay-opacity), transparent);
    backdrop-filter: blur(var(--overlay-blur));
    -webkit-backdrop-filter: blur(var(--overlay-blur));
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--overlay-speed) ease,
                visibility 0s linear var(--overlay-speed);
  }

  /* Auto margins center the stack, and collapse (instead of
     clipping the top) if a short screen runs out of room. */
  .menu-logo {
    display: block;
    flex: 0 0 auto;
    width: var(--overlay-logo-width);
    height: auto;
    margin: auto 0 var(--overlay-logo-gap);
  }

  .site-nav .nav-list {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: var(--overlay-links-gap);
  }

  .menu-cta {
    display: block;
    margin: var(--overlay-cta-gap) 0 auto;
  }

  .site-nav .nav-link { font-size: var(--overlay-links-size); }

  /* ---- open state ---- */
  html.menu-open { overflow: hidden; }   /* page can't scroll behind the menu */

  .site-header.menu-open {
    --nav-ink: var(--cream);
    backdrop-filter: none;               /* a blur here would trap the overlay inside the bar */
    -webkit-backdrop-filter: none;
    transition: none;
  }

  .site-header.menu-open .header-inner { transform: none; opacity: 1; }

  .site-header.menu-open .nav-logo {
    opacity: 0;                          /* centered overlay logo takes over */
    pointer-events: none;
  }

  .site-header.menu-open .site-nav {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--overlay-speed) ease, visibility 0s;
  }

  .site-header.menu-open .btn-talk:hover {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--cream);
  }

  /* burger -> X */
  .site-header.menu-open .nav-burger-lines { background-color: transparent; }
  .site-header.menu-open .nav-burger-lines::before {
    transform: translateY(calc(var(--burger-line-gap) + var(--burger-line))) rotate(45deg);
  }
  .site-header.menu-open .nav-burger-lines::after {
    transform: translateY(calc(-1 * (var(--burger-line-gap) + var(--burger-line)))) rotate(-45deg);
  }
}

/* ==========================================================
   HERO
   ========================================================== */

/* ==========================================================
   HERO — LEVERS
   Full-bleed photo background. Text position is set by the
   four values below — nudge any one, nothing else moves.
   ========================================================== */

:root {
  --hero-height:        100vh;
  --hero-overlay:       rgba(60, 6, 37, 0.25);  /* burgundy tint over the photo */
  --hero-text-top:      50%;   /* vertical position of the text block */
  --hero-text-left:     46%;    /* horizontal position of the text block */
  --hero-text-width:    41rem; /* max width of the text block */
  --hero-rule-color:    var(--sage);
  --hero-rule-thickness: 4px;
  --hero-rule-gap:       clamp(1rem, 7vh, 4rem);  /* rules -> text; tightens on short screens */
  --hero-type:           clamp(2.5rem, min(6vw, 10vh), 5rem);  /* headline size; shrinks on narrow OR short screens */
  --hero-arrow-size:    3.5rem;   /* the ‹ › glyph size */
  --hero-arrow-opacity: 0.75;     /* resting state */

  /* ---- script accent ("feels") ----
     em, not rem, on purpose: these must scale with the headline
     as the viewport changes. This is the documented exception
     to the rem-for-spacing rule. */
  --script-size:        1.55em;   /* optical match to the serif */
  --script-shift:       0.06em;   /* baseline nudge, + = down */
  --script-space:       0.04em;   /* breathing room either side */

  /* ---- carousel levers ---- */
  --hero-fade:          900ms; /* crossfade duration */
  --hero-autoplay:      6;     /* seconds between photos. Plain number, read by hero.js */
  --hero-arrow-x:       2rem;  /* arrow distance from left/right edge */
  --hero-dots-below:    2rem;  /* dot row distance from bottom */
}

.hero {
  position: relative;
  height: var(--hero-height);
  overflow: hidden;
}

.hero-media {
  position: absolute;
  inset: 0;
}

.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--hero-fade) ease;
}

.hero-slide.is-active { opacity: 1; }

.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--hero-overlay);
}

/* ---- carousel controls ---- */

.hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-nav);
  font-size: var(--hero-arrow-size);
  line-height: 1;
  color: var(--cream);
  background: none;
  border: 0;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.2s ease;
}

.hero-arrow:hover { opacity: 1; }

.hero-arrow-prev { left: var(--hero-arrow-x); }
.hero-arrow-next { right: var(--hero-arrow-x); }

/* Phones: the arrows would sit on the headline. Dots still change slides.
   640px matches the existing phone breakpoint (contact side images). */
@media (max-width: 640px) {
  .hero-arrow { display: none; }
}

.hero-dots {
  position: absolute;
  bottom: var(--hero-dots-below);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  gap: var(--space-xs);
}

.hero-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 1px solid var(--cream);
  border-radius: 999px;
  background: none;
  cursor: pointer;
}

.hero-dot.is-active { background: var(--cream); }

/* Invisible tap area: fills the gap between dots and reaches
   above/below, so the 9px dots are easier to hit on a phone.
   Looks identical. */
.hero-dot { position: relative; }

.hero-dot::after {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--space-sm)) calc(var(--space-xs) / -2);
}

.hero-copy {
  position: absolute;
  top: var(--hero-text-top);
  left: max(2rem, min(var(--hero-text-left), 100% - var(--hero-text-width) - 2rem));  /* slides left to stay on screen */
  width: var(--hero-text-width);
  max-width: calc(100% - 4rem);
  transform: translateY(-50%);
  z-index: 2;
}

.hero-headline {
  margin: 0 0 var(--space-md);
  padding: var(--hero-rule-gap) 0;
  border-top:    var(--hero-rule-thickness) solid var(--hero-rule-color);
  border-bottom: var(--hero-rule-thickness) solid var(--hero-rule-color);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--hero-type);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--cream);
}

/* Handwritten accent on a single word. line-height:0 is load-bearing —
   without it the taller script glyph box pushes the headline lines apart. */
.script {
  font-family: 'Mrs Saint Delafield', cursive;
  font-size: var(--script-size);
  font-weight: 400;
  line-height: 0;
  position: relative;
  top: var(--script-shift);
  margin: 0 var(--script-space);
}

.hero-sub {
  margin: 0 0 var(--space-lg);
  color: var(--cream);
}

.btn-outline {
  display: inline-block;
  font-family: var(--font-nav);
  font-size: var(--type-small);
  color: var(--cream);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--cream);
  transition: background-color 0.2s ease, color 0.2s ease;
}

.btn-outline:hover { background: var(--cream); color: var(--burgundy); }


/* ==========================================================
   SERVICES
   ========================================================== */

/* Full bleed laterally, like the portfolio and project grids.
   No max-width — the clamps below do the shrinking instead. */
.services {
  padding: var(--svc-pad-top) var(--section-pad-x) var(--section-pad-y);
}
/* Fixed 3 across. Grid, not flex, so the columns stay equal
   regardless of how much copy sits in each one. */
.services-grid {
  display: grid;
  grid-template-columns: repeat(var(--svc-columns), 1fr);
  gap: var(--svc-gap-y) var(--svc-gap-x);
  align-items: start;
}

/* One media query. Three columns of body copy get unreadable
   on a phone, so below this they stack. */
@media (max-width: 52rem) {
  .services-grid { --svc-columns: 1; }
  .service-item  { max-width: 32rem; margin: 0 auto; }
}

.service-item {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Icons share a 1200x900 box, so one width gives three matched heights. */
.service-item img {
  width: var(--svc-icon);
  height: auto;
  margin-bottom: var(--space-sm);
}

/* Same flanking-rule treatment as the project and card titles,
   scaled down to suit a column heading. */
.service-item h3 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--svc-rule-gap);
  width: 100%;
  margin: 0 0 var(--space-sm);
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-h2);
  line-height: 1.1;
  color: var(--burgundy);
}

.service-item h3::before,
.service-item h3::after {
  content: "";
  flex: 1 1 auto;
  max-width: var(--svc-rule-max);
  height: var(--title-rule-thickness);
  opacity: var(--title-rule-opacity);
}

.service-item h3::before { background: linear-gradient(to right, transparent, var(--burgundy)); }
.service-item h3::after  { background: linear-gradient(to left,  transparent, var(--burgundy)); }

.service-item p {
  margin: 0;
  color: var(--ink);
  text-align: center;
}

.dev-spacer {
  min-height: 70vh;
  display: grid;
  place-items: center;
  font-family: var(--font-nav);
  color: var(--sage);
  border-top: 1px solid rgba(60, 6, 37, 0.15);
}

/* ==========================================================
   ABOUT
   ---------------------------------------------------------- */

/* ---- ABOUT — LEVERS ---- */
:root {
  --about-photo-w:      20rem;   /* portrait width */
  --about-arch-radius:  3.6rem;  /* shoulder curve — same proportion as the Contact arch */
  --about-line-1:       0.75rem; /* photo -> inner gold line */
  --about-line-2:       0.4rem;  /* inner line -> outer line */
  --about-bar-width:    8rem;
  --about-sig-size:     4.5rem;  /* signature */
}

.about {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(3rem, 7vw, 6rem);
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(6rem, calc(10vw + 3rem), 12rem) var(--section-pad-x) calc(var(--nav-h) + var(--space-lg));
}

.about-media  { flex: 0 1 var(--about-photo-w); max-width: var(--about-photo-w); }
.about-copy   { flex: 0 1 42rem; }

/* Portrait: full photo, nothing cropped. The arch is a frame that
   sits OUTSIDE the photo — two gold lines, open at the bottom like
   the Contact doorway. */
.about-frame { position: relative; }

.about-frame img {
  width: 100%;
  border-radius: var(--about-arch-radius) var(--about-arch-radius) 0 0;
}

.about-frame::before,
.about-frame::after {
  content: "";
  position: absolute;
  bottom: 0;
  border: 1px solid var(--gold);
  border-bottom: 0;
  pointer-events: none;
}
.about-frame::before {
  top:   calc(-1 * var(--about-line-1));
  left:  calc(-1 * var(--about-line-1));
  right: calc(-1 * var(--about-line-1));
  border-radius: calc(var(--about-arch-radius) + var(--about-line-1)) calc(var(--about-arch-radius) + var(--about-line-1)) 0 0;
}
.about-frame::after {
  top:   calc(-1 * (var(--about-line-1) + var(--about-line-2)));
  left:  calc(-1 * (var(--about-line-1) + var(--about-line-2)));
  right: calc(-1 * (var(--about-line-1) + var(--about-line-2)));
  border-radius: calc(var(--about-arch-radius) + var(--about-line-1) + var(--about-line-2)) calc(var(--about-arch-radius) + var(--about-line-1) + var(--about-line-2)) 0 0;
}

/* Same eyebrow / headline / bar language as Contact, in rem */
.about-copy .about-eyebrow {
  margin: 0 0 var(--space-xs);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.8rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}

.about-copy h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--type-h2);
  line-height: 1.15;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--burgundy);
}

.about-copy h2 .script {
  font-size: 1.8em;
  top: -0.03em;
  margin: 0 0.12em 0 0.04em;
  text-transform: none;
  letter-spacing: 0;
}

/* Left-aligned copy, so the streak fades one way only */
.about-bar {
  width: var(--about-bar-width);
  height: 2px;
  margin: var(--space-md) 0 var(--space-lg);
  background: linear-gradient(to right, var(--burgundy), transparent);
  opacity: 0.7;
}

.about-copy p {
  margin: 0 0 var(--space-md);
  max-width: 42rem;
  color: var(--ink);
}

.about-copy .about-signature {
  margin: 0 0 var(--space-md);
  font-family: 'Mrs Saint Delafield', cursive;
  font-size: var(--about-sig-size);
  line-height: 1;
  color: var(--gold);
}

/* Double-line button: 2px outer border, 1px inner hairline drawn by
   ::after. Inner line uses currentColor, so both flip together. */
.btn-outline {
  --rule-ink:    var(--burgundy);
  --rule-outer:  2px;
  --rule-inner:  1px;
  --rule-gap:    4px;      /* space between the two lines */
  --rule-radius: 0.75rem;  /* corner round */

  position: relative;
  display: inline-block;
  font-family: var(--font-nav);
  font-size: var(--type-small);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rule-ink);
  background: transparent;
  padding: var(--space-sm) var(--space-lg);

  border: var(--rule-outer) solid var(--rule-ink);
  border-radius: var(--rule-radius);

  transition: color 0.25s ease, border-color 0.25s ease, letter-spacing 0.25s ease;
}

.btn-outline::after {
  content: "";
  position: absolute;
  inset: var(--rule-gap);
  border: var(--rule-inner) solid currentColor;
  border-radius: calc(var(--rule-radius) - var(--rule-gap));
  pointer-events: none;
}

.btn-outline:hover {
  --rule-ink: var(--gold);
  letter-spacing: 0.2em;
}/* ==========================================================
   CONTACT — LEVERS
   The form lives inside the arch painted on the photo, so every
   position below is a % of the photo, measured off the image
   (1536 x 1024). Sizes use cqi (1cqi = 1% of the photo's width)
   so type and fields shrink WITH the photo. Documented exception
   to the rem-for-spacing rule: inside the stage, the photo is
   the ruler. max() = a floor so small screens stay legible.
   ========================================================== */

:root {
  --arch-left:   24.7%;   /* inner gold line, left edge */
  --arch-top:    25%;     /* inner gold line, top */
  --arch-outer:  24%;     /* outer gold line — headline centers above this */
  --arch-width:  50.5%;
  --arch-height: 66%;

  --c-eyebrow:   max(0.95cqi, 0.75rem);
  --c-headline:  3.6cqi;
  --c-intro:     max(1.15cqi, 0.95rem);
  --c-label:     max(0.85cqi, 0.75rem);
  --c-field:     max(1cqi, 0.875rem);
  --c-gap:       1.5cqi;               /* space between fields */
  --c-bar-width: 16cqi;
  --c-bar-thickness: 2px;

  /* "more" — contact-only. Hero's .script is untouched. */
  --c-script-size:  1.8em;
  --c-script-shift: -0.03em;           /* + = down */
  --c-nav-bite:     5rem;   /* how far the photo's top edge sits ABOVE the nav's bottom */
  --c-head-drop:    8.5rem; /* headline's clearance below that */
}
}

/* ==========================================================
   CONTACT
   ========================================================== */

/* Clicking "Contact" lands the photo's top edge just below the
   fixed nav, so the nav sits over the previous section instead. */
.contact { scroll-margin-top: calc(var(--nav-h) - var(--c-nav-bite)); }

/* Full bleed. Height comes from the photo's shape, not content. */
.contact-stage {
  position: relative;
  aspect-ratio: 3 / 2;
  background: url("../images/contact-arch.jpg") center / cover no-repeat;
  container-type: inline-size;
}

/* Wall above the arch: eyebrow + headline, centered vertically
   between the top of the photo and the outer gold line */
.contact-head {
  position: absolute;
  top: 0;
  left: var(--arch-left);
  width: var(--arch-width);
  height: var(--arch-outer);
  padding-top: var(--c-head-drop);
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.contact-eyebrow {
  margin: 0 0 0.8cqi;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--c-eyebrow);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}

.contact-head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--c-headline);
  line-height: 1.1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--burgundy);
  white-space: nowrap;
}

.contact-head .script {
  font-size: var(--c-script-size);
  top: var(--c-script-shift);
  margin: 0 0.14em 0 0;
  text-transform: none;
  letter-spacing: 0;
}

/* Inside the arch */
.contact-arch {
  position: absolute;
  left: var(--arch-left);
  top: var(--arch-top);
  width: var(--arch-width);
  height: var(--arch-height);
  padding: 3.5cqi 5cqi 0;
  text-align: center;
  line-height: 1.35;   /* tighter than body's 1.6 so the form fits the arch */
}

.contact-bar {
  width: var(--c-bar-width);
  height: var(--c-bar-thickness);
  margin: 0 auto 1.6cqi;
  background: linear-gradient(to right, transparent, var(--burgundy), transparent);
  opacity: 0.7;
}

.contact-intro {
  margin: 0 0 2.4cqi;
  font-size: var(--c-intro);
  color: var(--ink);
}

.contact-form { text-align: left; }

.c-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--c-gap);
  margin-bottom: var(--c-gap);
  align-items: end;   /* a wrapped label pushes up, fields stay level */
}
.c-row.c-two  { grid-template-columns: 2fr 1fr; }
.c-row.c-full { grid-template-columns: 1fr; }

.c-field { display: flex; flex-direction: column; gap: 0.3cqi; min-width: 0; }

.c-field > label,
.c-legend {
  font-family: var(--font-nav);
  font-size: var(--c-label);
  color: var(--olive);
}

/* Underline fields — reads like writing on the wall */
.c-field input,
.c-field select {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--c-field);
  padding: 0.5cqi 0.2cqi;
  border: 0;
  border-bottom: 1px solid var(--gold);
  background: transparent;
  color: var(--ink);
  border-radius: 0;
}

/* Select + checkbox options match the labels */
.c-field select,
.c-checks label {
  font-family: var(--font-nav);
  font-size: var(--c-label);
  color: var(--olive);
}

.c-field input:focus,
.c-field select:focus { outline: none; border-bottom-color: var(--burgundy); }

.c-checks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6cqi 2cqi;
  margin-top: 0.4cqi;
}
.c-checks label {
  display: flex;
  align-items: center;
  gap: 0.5cqi;
}
.c-checks input {
  width: var(--c-label);
  height: var(--c-label);
  margin: 0;
  accent-color: var(--burgundy);
}

/* Same double-line treatment as .btn-outline, but sized in cqi
   so it scales with the photo like everything else in the arch. */
.contact-send {
  --rule-ink:    var(--burgundy);
  --rule-outer:  2px;
  --rule-inner:  1px;
  --rule-gap:    4px;      /* space between the two lines */
  --rule-radius: 0.75rem;  /* corner round */

  position: relative;
  display: block;
  margin: 1cqi auto 0;
  font-family: var(--font-nav);
  font-size: var(--c-label);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rule-ink);
  background: transparent;
  padding: 0.8cqi 3cqi;

  border: var(--rule-outer) solid var(--rule-ink);
  border-radius: var(--rule-radius);
  cursor: pointer;

  transition: color 0.25s ease, border-color 0.25s ease, letter-spacing 0.25s ease;
}

.contact-send::after {
  content: "";
  position: absolute;
  inset: var(--rule-gap);
  border: var(--rule-inner) solid currentColor;
  border-radius: calc(var(--rule-radius) - var(--rule-gap));
  pointer-events: none;
}

.contact-send:hover {
  --rule-ink: var(--gold);
  letter-spacing: 0.2em;
}

/* TEMPORARY safety net until we design mobile/tablet Contact.
   Below 960px the form no longer fits inside the arch, so the
   photo drops and everything stacks on plain white. Delete this
   whole block when the real small-screen design lands. */
@media (max-width: 60rem) {
  .contact {
    --c-headline: var(--type-h2);
    --c-gap: var(--space-sm);
/* Phone portrait: pull Contact up under the nav */
@media (max-width: 44rem) and (orientation: portrait) {
  .contact-stage { padding-top: var(--space-sm); }
}
  }
  .contact-stage {
    aspect-ratio: auto;
    background: none;
    padding: var(--section-pad-y) var(--section-pad-x);
  }
  .contact-head,
  .contact-arch {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
  }
  .contact-head { margin-bottom: var(--space-md); }
  .contact-head h2 { white-space: normal; }
  .contact-bar { margin-bottom: var(--space-sm); }
  .contact-intro { margin-bottom: var(--space-lg); }
  .c-row,
  .c-row.c-two { grid-template-columns: 1fr; }
  .contact-send { margin-top: var(--space-md); padding: var(--space-sm) var(--space-lg); }
}
.hidden-field { display: none; }

/* ==========================================================
   PORTFOLIO + PROJECT PAGES
   ----------------------------------------------------------
   Shared by portfolio.html and every project-*.html.
   Uses the same --space-* / --type-* tokens as the rest of
   the site. Nav on these pages is always dark ink, set by
   the .nav-dark class hardcoded on <header> in the HTML.
   ========================================================== */

.wrap {
  width: 100%;
  max-width: var(--measure-page);
  margin: 0 auto;
  padding-left: var(--section-pad-x);
  padding-right: var(--section-pad-x);
}

/* ---- page head ---- */

.page-head {
  padding-top: calc(var(--nav-h) + var(--space-md));
  padding-bottom: var(--space-lg);
}

/* Title centered, a burgundy rule flanking each side. The rules are
   flex children, so they take whatever width is left over and cap
   at --title-rule-max. Nothing to maintain per page. */

.page-head h1 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--title-rule-gap);
  margin: 0 0 var(--space-sm);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--type-h2);
  line-height: 1.1;
  text-align: center;
  color: var(--burgundy);
}

.page-head h1::before,
.page-head h1::after {
  content: "";
  flex: 1 1 auto;
  max-width: var(--title-rule-max);
  height: var(--title-rule-thickness);
  background: var(--burgundy);
}

.page-head p {
  width: fit-content;   /* box hugs the text, so the bars can size off it */
  max-width: 100%;
  margin: 0 auto;
  font-size: 1.25rem;
  text-align: center;
  text-wrap: balance;   /* if it does wrap on small screens, lines stay even */
}

/* Sage streaks above and below, fading both ways, 75% of the text width */
.page-head p::before,
.page-head p::after {
  content: "";
  display: block;
  width: 75%;
  height: var(--title-rule-thickness);
  margin: var(--space-md) auto;
  background: linear-gradient(to right, transparent, var(--sage), transparent);
}
/* ---- portfolio index: 2 across ---- */

/* Full bleed laterally, fixed 3 across. auto-fit would give five or six
   columns on a wide monitor now that nothing constrains the width. */
.project-grid {
  display: grid;
  grid-template-columns: repeat(var(--card-columns), 1fr);
  gap: var(--card-gap);
  padding-bottom: var(--section-pad-y);
}

@media (max-width: 44rem) {
  .project-grid { --card-columns: 1; }
}

.project-card figure {
  position: relative;
  margin: 0;
  overflow: hidden;
}

.project-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--sage);
  transition: transform 0.5s ease;
}

/* Title over the photo, same treatment as the project page lead. */
.card-title {
  position: absolute;
  top: var(--card-title-y);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--card-rule-gap);
  width: 90%;
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--type-h2);
  line-height: 1.1;
  color: var(--cream);
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.5);
}

.card-title::before,
.card-title::after {
  content: "";
  flex: 1 1 auto;
  max-width: var(--card-rule-max);
  height: var(--title-rule-thickness);
  opacity: var(--title-rule-opacity);
}

.card-title::before { background: linear-gradient(to right, transparent, var(--cream)); }
.card-title::after  { background: linear-gradient(to left,  transparent, var(--cream)); }

/* Hover CTA. Hidden by default so touch devices never see it —
   tapping the photo is the obvious action there. */
.card-cta {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: var(--space-xl);
  background: var(--card-fade);
  color: var(--cream);
  font-family: var(--font-nav);
  font-size: var(--card-cta-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 0.35s ease;
}

@media (hover: hover) {
  .project-card:hover .card-cta { opacity: 1; }
  .project-card:hover img { transform: scale(1.04); }
}

/* ---- project page: lead photo ---- */

/* position:relative anchors the title. padding-top is the cream band
   that used to come from .page-head — now deliberate, same on every
   project page regardless of what's at the top of the photo. */
.project-hero {
  position: relative;
  padding-top: var(--lead-inset-top);
  margin: 0 0 var(--space-lg);
}

.project-hero img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  background: var(--sage);
}

/* Title sits over the photo. % keeps it in place as the image scales. */
.project-title {
  position: absolute;
  top: var(--project-title-y);
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--title-rule-gap);
  width: 90%;
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--type-hero);
  line-height: 1.1;
  color: var(--project-title-color);
  text-shadow: 0 2px 28px rgba(0, 0, 0, 0.5);
}

/* Each rule fades outward only, staying solid where it meets the text. */
.project-title::before,
.project-title::after {
  content: "";
  flex: 1 1 auto;
  max-width: var(--title-rule-max);
  height: var(--title-rule-thickness);
  opacity: var(--title-rule-opacity);
}

.project-title::before {
  background: linear-gradient(to right, transparent, var(--project-title-color));
}

.project-title::after {
  background: linear-gradient(to left, transparent, var(--project-title-color));
}

/* Photo runs full bleed, caption stays on a readable measure. */
.project-hero figcaption {
  max-width: 52rem;
  margin: 0 auto;
  padding: var(--space-md) var(--section-pad-x) 0;
  text-align: center;
  font-size: var(--type-small);
  color: var(--ink-soft);
}

/* ---- project page: scope + design ---- */

.narrative {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--space-md) var(--space-lg);
  padding-top: var(--space-lg);
  padding-bottom: var(--space-lg);
}

.narrative h2 {
  margin: 0 0 var(--space-sm);
  padding-bottom: var(--space-xs);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--type-h2);
  color: var(--burgundy);
  border-bottom: 1px solid var(--sage);
}

.narrative p { margin: 0 0 var(--space-sm); }
.narrative p:last-child { margin-bottom: 0; }

/* ---- project page: thumbs, 3 across ---- */

/* Full-bleed grid. Sits outside .wrap in the HTML, so it spans the
   viewport at every size and the tiles grow or shrink with it. */
.thumbs {
  display: grid;
  grid-template-columns: repeat(var(--thumb-columns), 1fr);
  gap: var(--thumb-gap);
  padding-bottom: var(--section-pad-y);
}

/* The one media query here. Three tiles at 4px apart get too small to
   read on a phone, so below this width they stack. */
@media (max-width: 44rem) {
  .thumbs { --thumb-columns: 1; }
}

.thumb { margin: 0; }

.thumb button {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  font: inherit;
}

.thumb img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--sage);
}

/* No captions on project thumbs by design. The lead photo carries
   the one caption for the whole project. */

/* ---- lightbox ---- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: var(--space-md);
  background: rgba(37, 34, 34, 0.93);
  cursor: zoom-out;
}

.lightbox[open] { display: flex; }

.lightbox figure { margin: 0; max-width: 100%; }

/* Both photos stack in one grid cell so the flip has no reflow
   and no white flash. The before sits under the after. */
.lightbox-frame {
  display: grid;
  justify-items: center;
}

.lightbox-frame img {
  grid-area: 1 / 1;
  width: auto;
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
  transition: opacity var(--ba-fade) ease;
}

.lightbox-before { opacity: 0; }

.lightbox.show-before .lightbox-after  { opacity: 0; }
.lightbox.show-before .lightbox-before { opacity: 1; }

/* ---- before / after toggle ---- */

.lightbox-toggle {
  display: flex;
  justify-content: center;
  gap: var(--space-xs);
  padding-top: var(--space-sm);
  cursor: default;
}

.lightbox-toggle[hidden] { display: none; }

.lightbox-toggle button {
  font-family: var(--font-nav);
  font-size: var(--type-small);
  letter-spacing: 0.04em;
  padding: var(--space-xs) var(--space-md);
  color: var(--cream);
  background: none;
  border: 1px solid rgba(242, 238, 231, 0.45);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.lightbox-toggle button:hover { border-color: var(--cream); }

.lightbox-toggle button.is-active {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--ink);
}

.lightbox figcaption {
  padding-top: var(--space-sm);
  text-align: center;
  font-size: var(--type-small);
  color: var(--cream);
}
