/* ==========================================================================
   Plumbline — shell, grid, header, footer
   ========================================================================== */

.wrap {
  width: 100%; max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--wide { max-width: 1480px; }

/* Every section carries its own opaque ground and sits a layer above the
   hero, because the hero is sticky: the page scrolls over it rather than
   pushing it off. Anything transparent here would show the photograph
   through the whole document. */
.section {
  padding-block: var(--section-y);
  position: relative; z-index: 1;
  background: var(--paper);
}
.section--tight { padding-block: calc(var(--section-y) * 0.62); }

.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-6);
}
@media (max-width: 1024px) { .grid { grid-template-columns: repeat(8, minmax(0,1fr)); gap: var(--s-4); } }
@media (max-width: 640px)  { .grid { grid-template-columns: repeat(4, minmax(0,1fr)); gap: var(--s-4); } }

/* Section head: label + heading left, supporting copy right. */
.head {
  display: grid; grid-template-columns: minmax(0,1.25fr) minmax(0,1fr);
  gap: var(--s-8) var(--s-12); align-items: end;
  margin-bottom: var(--s-16);
}
.head > p { padding-bottom: 6px; }
/* One column, middle of the page — for a section whose content is
   symmetrical about the centre line and would look lopsided under a
   heading pinned to the left. */
.head--center {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center; text-align: center;
}
@media (max-width: 860px) { .head { grid-template-columns: 1fr; margin-bottom: var(--s-12); } }

/* ==========================================================================
   Preloader — the bob drops, the name lifts, the sheet goes.
   Opt-in by design: .pl-on is set in <head> before the first paint, and only
   when motion is welcome. No script or a reduced-motion setting means no sheet
   at all, because a full-screen layer nobody can lift is a blank page.
   ========================================================================== */

.pl { display: none; }
.pl-on .pl {
  display: grid; place-items: center;
  position: fixed; inset: 0; z-index: 500;
  /* Ink, like the hero underneath it and like the theme colour the browser
     paints before any of this exists — so the sheet lifting is a fade between
     two dark grounds rather than a flash of light and then dark again. */
  background: var(--ink);
  /* Ends on visibility: hidden, so the layer stops swallowing clicks even if
     the script that removes the node never runs. */
  animation: plLift 420ms var(--ease-out) 900ms both;
  contain: layout paint style;
}
@keyframes plLift {
  from { opacity: 1; visibility: visible; }
  to   { opacity: 0; visibility: hidden; }
}

.pl__brand { display: flex; align-items: center; gap: clamp(10px, 1.1vw, 16px); }

/* It's a plumb bob. It arrives the way a plumb bob does. */
.pl__mark {
  width: clamp(30px, 2.8vw, 42px); height: auto; aspect-ratio: 22 / 26;
  animation: plDrop 620ms cubic-bezier(.22, .9, .24, 1) both;
}
/* The inverted lockup, same as the header carries over the hero photograph. */
.pl__mark .stem { fill: var(--text-inv); }
.pl__mark .bob  { fill: var(--action-hi); }
@keyframes plDrop {
  from { opacity: 0; transform: translateY(-16px); }
  to   { opacity: 1; transform: none; }
}

.pl__word {
  display: flex;
  font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem);
  font-weight: var(--wt-head);
  letter-spacing: var(--ls-h1);
  line-height: 1;
  color: var(--text-inv);
}
.pl__word span {
  display: inline-block;
  animation: plLetter 520ms cubic-bezier(.22, .9, .24, 1) both;
  animation-delay: calc(160ms + var(--i) * 40ms);
}
@keyframes plLetter {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Header — two objects in the corners, nothing in between.
   The nav lives in a full-screen menu so the photograph gets the whole frame.
   ========================================================================== */

.header {
  position: fixed; inset: 0 0 auto; z-index: 100;
  /* No scrim of its own. A gradient that reaches zero at the header's own
     bottom edge still stops dead there, and the eye reads that break in the
     falloff as a hairline across the photograph. The hero's scrim already
     darkens this band, and it runs the full height with nowhere to end. */
  background: transparent;
  transition: background var(--t-mid) var(--ease-out),
              box-shadow var(--t-mid) var(--ease-out),
              border-color var(--t-mid) var(--ease-out);
  border-bottom: 1px solid transparent;
}
.header__inner {
  display: flex; align-items: center; justify-content: space-between;
  height: clamp(76px, 5.4vw, 96px);
  transition: height var(--t-mid) var(--ease-out);
}
.header.is-stuck {
  background: rgba(244,240,233,.94);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--line);
}
.header.is-stuck .header__inner { height: 68px; }

/* Over the photograph the header runs inverted; stuck, it flips back. */
.header:not(.is-stuck) { color: var(--text-inv); }
.header:not(.is-stuck) .brand__mark .bob { fill: var(--action-hi); }

.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: var(--wt-display);
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.25rem); letter-spacing: var(--ls-h3);
}
.brand__mark { width: 22px; height: 26px; }
/* currentColor carries the stem, so the mark follows whatever ground it lands
   on — dark header, light header, dark footer — and the bob stays the accent,
   which .on-ink re-points for us. */
.brand__mark .stem { fill: currentColor; }
.brand__mark .bob  { fill: var(--action); }

/* --- Menu button -------------------------------------------------------- */
.menu-btn {
  width: clamp(52px, 4.2vw, 64px); height: clamp(52px, 4.2vw, 64px);
  display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer; padding: 0;
  background: var(--paper); color: var(--ink);
  box-shadow: var(--shadow-card);
  transition: background var(--t-fast) var(--ease-out), transform var(--t-mid) var(--ease-out);
}
.menu-btn:hover { background: #fff; transform: scale(1.05); }
.menu-btn__bars { display: grid; gap: 6px; width: 22px; }
.menu-btn__bars span {
  display: block; height: 2px; width: 100%; border-radius: 2px;
  background: currentColor;
  transition: transform var(--t-mid) var(--ease-out), opacity var(--t-fast) linear, width var(--t-mid) var(--ease-out);
}
.menu-btn__bars span:last-child { width: 15px; justify-self: end; }
.menu-btn:hover .menu-btn__bars span:last-child { width: 22px; }
.menu-btn[aria-expanded="true"] .menu-btn__bars span:first-child { transform: translateY(4px) rotate(45deg); }
.menu-btn[aria-expanded="true"] .menu-btn__bars span:last-child { width: 22px; transform: translateY(-4px) rotate(-45deg); }

/* --- Full-screen menu --------------------------------------------------- */
.menu {
  position: fixed; inset: 0; z-index: 99;
  background: var(--ink); color: var(--text-inv);
  display: flex; align-items: center;
  /* GSAP wipes this open. The class is the no-JS / reduced-motion fallback. */
  clip-path: inset(0 0 100% 0);
}
.menu.is-open { clip-path: inset(0 0 0% 0); }
.menu__inner {
  display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--s-16); align-items: center;
  padding-block: 120px var(--s-16);
  width: 100%;
}
.menu__nav { display: grid; }
.menu__nav a {
  display: flex; align-items: baseline; gap: var(--s-6);
  overflow: hidden;
  padding-block: clamp(0.5rem, 0.2rem + 1vw, 1rem);
  font-size: clamp(2rem, 1rem + 4.2vw, 4.5rem);
  line-height: var(--lh-head); letter-spacing: var(--ls-h1);
  font-weight: var(--wt-display);
  border-bottom: 1px solid var(--line-inv);
  color: var(--text-inv);
  transition: color var(--t-fast) var(--ease-out), padding-left var(--t-mid) var(--ease-out);
}
.menu__nav a:hover { color: var(--action-hi); padding-left: var(--s-4); }
.menu__nav a[aria-current="true"] { color: var(--action-hi); }
.menu__nav a[aria-current="true"] i { color: var(--action-hi); }
.menu__nav a i {
  font-style: normal;
  font-size: var(--fs-cap); letter-spacing: 0.14em;
  font-weight: var(--wt-display);
  color: var(--text-inv-sub);
  font-variant-numeric: tabular-nums;
}
/* Each label sits in its own mask so it can be lifted into place. */
.menu__mask { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.menu__mask > span { display: block; will-change: transform; }

.menu__aside { display: grid; justify-items: start; gap: var(--s-3); }
.menu__phone {
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2rem);
  font-weight: var(--wt-display); letter-spacing: var(--ls-h2);
  font-variant-numeric: tabular-nums;
}
.menu__phone:hover { color: var(--action-hi); }
.menu__addr { font-size: var(--fs-sm); color: var(--text-inv-sub); margin-top: var(--s-2); }
.menu__aside .btn { margin-top: var(--s-4); }

@media (max-width: 900px) {
  .menu__inner {
    grid-template-columns: 1fr; gap: var(--s-12);
    align-content: center; padding-block: 108px var(--s-12);
  }
  .menu { align-items: stretch; overflow-y: auto; }
}

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

.footer { padding-top: var(--s-24); overflow: hidden; }
.footer__top {
  display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,1.4fr);
  gap: var(--s-16) var(--s-12);
  padding-bottom: var(--s-16);
  border-bottom: 1px solid var(--line);
}
.footer__links { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--s-8); }
.footer__links h3 {
  font-size: var(--fs-cap); letter-spacing: var(--ls-body);
  font-weight: var(--wt-display);
  color: var(--text-mute); margin-bottom: var(--s-4);
}
.footer__links li + li { margin-top: var(--s-1); }
/* 24px minimum target — these are a list of links, not links in a sentence. */
.footer__links a { display: inline-block; padding-block: 5px; font-size: var(--fs-sm); color: var(--text-sub); transition: color var(--t-fast) var(--ease-out); }
.footer__links a:hover { color: var(--action-hi); }

/* The wordmark is set from the column it sits in rather than the viewport, so
   it can be sized to overrun that column by a fixed amount at every width. */
.footer > .wrap { container-type: inline-size; }

.footer__wordmark {
  /* Viewport-based fallback first, for anything without container queries. */
  font-size: clamp(3.5rem, 17vw, 15.4rem);
  /* Wider than the column on purpose: the word runs past both edges instead of
     sitting politely inside them. */
  font-size: 20.6cqw;
  font-weight: var(--wt-head);
  letter-spacing: var(--ls-hero);
  line-height: 0.8;
  /* A tone off the footer's own ground rather than a colour on top of it: the
     word reads as a shape pressed into the floor, not as a line of type. The
     hairline token is the lightest thing on this ground that still reads. */
  color: var(--line-inv);
  /* Full tone at the cap line, gone by the baseline — the letters sink into
     the floor of the page rather than ending on one. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.70) 67%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.70) 67%, transparent 100%);
  /* The box itself is the overrun, rather than letting an over-long line
     overflow a narrower one — that way the bleed is the same on both sides at
     every width instead of depending on how the line happens to overflow. */
  width: 105%;
  margin-block: var(--s-12) 0;
  margin-inline: -2.5%;
  text-align: center;
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
}
.footer__base {
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-8);
  justify-content: space-between; align-items: center;
  padding-block: var(--s-8);
  font-size: var(--fs-cap); color: var(--text-mute);
}
.footer__base ul { display: flex; gap: var(--s-6); flex-wrap: wrap; }
.footer__base a { display: inline-block; padding-block: 6px; }
.footer__base a:hover { color: var(--action-hi); }

@media (max-width: 900px) {
  .footer__top { grid-template-columns: 1fr; }
  .footer__links { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 480px) { .footer__links { grid-template-columns: 1fr; } }
