/* =============================================================================
   Peter Himmelstein Design & Architecture — design system

   One neo-grotesque throughout, set bold and tight for headings. Near-white
   paper so the photography supplies all of the colour.
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */

:root {
  --paper:      #fdfdfc;
  --paper-2:    #f1f1ef;
  --ink:        #121211;
  --ink-soft:   #3a3a38;
  --muted:      #6e6e6a;
  --rule:       #e4e4e0;
  --rule-strong:#c8c8c3;
  --accent:     #3d3d39;
  --invert-bg:  #141413;
  --invert-fg:  #f4f4f2;

  --sans: "Helvetica Neue", Helvetica, Inter, -apple-system, BlinkMacSystemFont,
          "Segoe UI", Arial, sans-serif;

  --gutter: clamp(1.25rem, 3.2vw, 3rem);
  --pad:    clamp(1.25rem, 5vw, 5.5rem);
  --max:    1680px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --slow: 900ms;

  --header-h: 5.25rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #131313;   --paper-2: #1c1c1b;
    --ink: #f2f2f0;     --ink-soft: #d5d5d2;
    --muted: #94948f;
    --rule: #2d2d2b;    --rule-strong: #43433f;
    --accent: #cfcfc9;
    --invert-bg: #fdfdfc; --invert-fg: #121211;
  }
}
:root[data-theme="dark"] {
  --paper: #131313;   --paper-2: #1c1c1b;
  --ink: #f2f2f0;     --ink-soft: #d5d5d2;
  --muted: #94948f;
  --rule: #2d2d2b;    --rule-strong: #43433f;
  --accent: #cfcfc9;
  --invert-bg: #fdfdfc; --invert-fg: #121211;
}

/* --- 2. Base ------------------------------------------------------------- */

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

/* Author `display` beats the UA's [hidden] rule; restore it. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.18vw, 1.0625rem);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
::selection { background: var(--ink); color: var(--paper); }

/* --- 3. Typography ------------------------------------------------------- */

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--sans);
  font-weight: 700;
  line-height: 1.04;
  /* Bold grotesques need pulling in harder than a serif does, and more so as
     the size grows — the per-size values below tighten further. */
  letter-spacing: -0.028em;
  text-wrap: balance;
}

p { margin: 0 0 1.15em; text-wrap: pretty; hanging-punctuation: first last; }
p:last-child { margin-bottom: 0; }

.display {
  font-size: clamp(2.6rem, 7.6vw, 6.75rem);
  line-height: 0.94;
  letter-spacing: -0.042em;
}
.h1 { font-size: clamp(1.95rem, 4.4vw, 3.5rem); letter-spacing: -0.034em; }
.h2 { font-size: clamp(1.45rem, 2.6vw, 2.2rem); letter-spacing: -0.028em; }
.h3 { font-size: clamp(1.1rem, 1.4vw, 1.35rem); letter-spacing: -0.02em; }

.lede {
  font-size: clamp(1.1rem, 1.55vw, 1.4rem);
  line-height: 1.52;
  letter-spacing: -0.008em;
  color: var(--ink-soft);
}

/* Uppercase, tracked-out small text — section markers and metadata. */
.label {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.4;
}
.meta {
  font-family: var(--sans);
  font-size: 0.8125rem;
  letter-spacing: 0.005em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.statement {
  font-size: clamp(1.4rem, 2.8vw, 2.5rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.032em;
  text-wrap: balance;
}

.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

.link-underline {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 100%;
  transition: background-size 420ms var(--ease);
  padding-bottom: 2px;
}
.link-underline:hover, .link-underline:focus-visible { background-size: 100% 1px; }

/* --- 4. Layout ----------------------------------------------------------- */

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--pad); }
.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--gutter); }
.rule { border: 0; border-top: 1px solid var(--rule); margin: 0; }

.section { padding-block: clamp(4rem, 10vw, 10rem); }
.section--tight { padding-block: clamp(2.75rem, 5.5vw, 5.5rem); }
/* The city pages run straight from the hero title into the grid; the full
   section padding left an awkward gap under "Los Angeles". */
.section--after-hero { padding-top: clamp(1.25rem, 2.1vw, 2rem); }

/* Services chart. Service on the left, everything it covers on the right,
   one row per item. Deliberately declares no font-size anywhere: every cell
   inherits the body size, so reading down the page never changes scale.
   Scoped to .chart so nothing else on the site is affected. */
.chart { border-top: 1px solid var(--rule); }
.chart__row {
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) 2.1fr;
  gap: var(--gutter);
  padding-block: 0.9rem;
  border-bottom: 1px solid var(--rule);
}
/* The first row of each service carries the name and a heavier rule above. */
.chart__row--start { border-top: 1px solid var(--ink); }
.chart__service { font-weight: 700; letter-spacing: -0.02em; }
/* The items are the detail, so they sit back. */
.chart__item { margin: 0; color: var(--muted); }
/* The "PHD&A..." sentences lead each group and carry the weight. */
.chart__note { color: var(--ink); font-weight: 700; }
/* Sub-points belong to the item above them, so they stay in the same cell. */
.chart__sub {
  list-style: none;
  margin: 0.5rem 0 0;
  padding-left: clamp(1rem, 2.5vw, 1.5rem);
  color: var(--muted);
}
.chart__sub li + li { margin-top: 0.3rem; }

@media (max-width: 760px) {
  .chart__row { grid-template-columns: 1fr; gap: 0.4rem; }
  .chart__service { padding-bottom: 0.1rem; }
}

/* --- 5. Header ----------------------------------------------------------- */

.header {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--header-h);
  display: flex; align-items: center;
  transition: background-color 500ms var(--ease), border-color 500ms var(--ease);
  border-bottom: 1px solid transparent;
}
.header[data-over-hero="true"] { color: #fff; }
.header[data-over-hero="false"] {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: var(--rule);
}

.header__inner {
  width: 100%; max-width: var(--max); margin-inline: auto;
  padding-inline: var(--pad);
  display: flex; align-items: baseline; justify-content: space-between; gap: 2rem;
}

/*
 * The header is set the same way as the "Los Angeles" / "New York" titles:
 * bold, mixed case, tight negative tracking, at full strength rather than
 * faded. Both scale with the viewport because five nav items and a wordmark
 * that cannot wrap have to share one line.
 */
.wordmark {
  font-family: var(--sans);
  font-size: clamp(1rem, 0.78rem + 0.6vw, 1.375rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  white-space: nowrap;
}
.wordmark span { color: inherit; font-weight: 700; }

.nav { display: flex; gap: clamp(1.1rem, 2.2vw, 2.5rem); align-items: baseline; }
.nav a {
  font-family: var(--sans);
  font-size: clamp(0.875rem, 0.76rem + 0.32vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  opacity: 1;
  transition: opacity 300ms var(--ease);
}
.nav a:hover, .nav a:focus-visible { opacity: 0.6; }
/* Everything is bold now, so weight can no longer mark the current page. */
.nav a[aria-current="page"] {
  text-decoration: underline;
  text-underline-offset: 0.42em;
  text-decoration-thickness: 1.5px;
}

.nav-toggle {
  display: none;
  background: none; border: 0; padding: 0.5rem 0; margin: 0;
  color: inherit; cursor: pointer;
  font-family: var(--sans);
  font-size: clamp(0.875rem, 0.76rem + 0.32vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: -0.025em;
}

@media (max-width: 760px) {
  .nav-toggle { display: block; }
  .nav {
    position: fixed; inset: 0;
    background: var(--paper); color: var(--ink);
    flex-direction: column; justify-content: center; align-items: stretch;
    gap: 0; padding: var(--pad);
    transform: translateY(-100%);
    transition: transform 620ms var(--ease);
    visibility: hidden;
  }
  .nav[data-open="true"] { transform: translateY(0); visibility: visible; }

  /* The overlay is fixed, so these would otherwise paint underneath it — and
     the Close button would be unclickable. */
  .wordmark, .nav-toggle { position: relative; z-index: 2; }
  .header:has(.nav[data-open="true"]) { color: var(--ink); }
  .header:has(.nav[data-open="true"]) .wordmark span { color: var(--muted); }

  /* A backdrop-filter makes the header the containing block for its fixed
     children. On every page with the frosted header that squeezed this
     full-screen menu into the header strip, so the links spilled over the page
     with nothing behind them. Dropping the blur while the menu is open lets it
     fill the screen, as it always did on the landing page. */
  .header:has(.nav[data-open="true"]) {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .nav a {
    font-size: clamp(1.65rem, 7.5vw, 2.6rem);
    font-weight: 700;
    text-transform: none; letter-spacing: -0.035em;
    opacity: 1; padding-block: 0.5em;
    border-bottom: 1px solid var(--rule);
  }
}

/* --- 6. Split landing ---------------------------------------------------- */

.split {
  display: flex;
  height: 100svh;
  min-height: 34rem;
  background: var(--invert-bg);
}

.split__panel {
  position: relative;
  flex: 1 1 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.split__panel + .split__panel { border-left: 1px solid rgba(255,255,255,0.16); }

@media (hover: hover) and (min-width: 761px) {
  /* The interaction is a highlight, not a movement: pointing at one panel
     lifts it and settles the other back. Both selectors are descendant-scoped
     so the "lift" rule outranks the "settle back" rule — `.split__panel:hover`
     alone loses to `.split:hover .split__panel` on specificity and never
     applies. */
  .split:hover .split__media img,
  .split:focus-within .split__media img { filter: brightness(0.58) saturate(0.85); }

  .split:hover .split__panel:hover .split__media img,
  .split:focus-within .split__panel:focus-visible .split__media img {
    filter: brightness(0.96) saturate(1.02);
  }
}

.split__media { position: absolute; inset: 0; }
.split__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(0.72) saturate(0.9);
  transition: filter 420ms var(--ease);
}

/* The caption sits dead centre, where a top-and-bottom scrim leaves nothing, so
   a soft band runs through the middle too. It is light — the title is large
   enough to hold itself, and only the small button below really needs help. */
.split__panel::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0,0,0,0.36) 0%,
    rgba(0,0,0,0.12) 24%,
    rgba(0,0,0,0.26) 50%,
    rgba(0,0,0,0.12) 76%,
    rgba(0,0,0,0.36) 100%
  );
  pointer-events: none;
  transition: opacity 420ms var(--ease);
}
/* Ease it back on the panel being highlighted so the photograph opens up. */
.split__panel:hover::after,
.split__panel:focus-visible::after { opacity: 0.6; }

.split__body {
  position: relative; z-index: 2;
  text-align: center;
  padding: var(--pad);
}
/* The panel title is the whole caption — the panel itself is the link, and the
   hover (the photograph lightens, the other settles back) is the affordance. */
.split__title {
  font-size: clamp(2.25rem, 5.4vw, 5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.042em;
  margin: 0;
}

@media (max-width: 760px) {
  .split { flex-direction: column; height: auto; }
  .split__panel { min-height: 56svh; }
  .split__panel + .split__panel { border-left: 0; border-top: 1px solid rgba(255,255,255,0.16); }
}

/* --- 7. Hero (interior pages) -------------------------------------------- */

.hero {
  position: relative;
  height: 74svh; min-height: 26rem;
  overflow: hidden;
  background: var(--paper-2);
}
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.12) 13%, rgba(0,0,0,0) 26%),
    linear-gradient(to top,    rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.22) 26%, rgba(0,0,0,0) 52%);
  pointer-events: none;
}
.hero__caption {
  position: absolute; left: 0; right: 0; bottom: clamp(1.75rem, 4vw, 3.25rem);
  z-index: 2; color: #fff;
}
.hero__title {
  font-size: clamp(2rem, 5.4vw, 4.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.042em;
  max-width: 16ch;
  margin-bottom: 0;
}
/* The city pages are now title-only, so the spacing lives here rather than on
   the title — it only applies when there is actually a footer to separate. */
.hero__footer {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--gutter);
  margin-top: clamp(1.5rem, 3.5vw, 2.5rem);
  padding-top: 1.1rem;
  border-top: 1px solid rgba(255,255,255,0.34);
}
.hero__meta { display: flex; gap: clamp(1.5rem, 3vw, 4rem); }
.hero__meta .label { color: rgba(255,255,255,0.68); }
.hero__meta p { font-size: 0.9375rem; margin: 0.35rem 0 0; }
.hero__cue {
  flex: none;
  font-family: var(--sans);
  font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255,255,255,0.8);
}
@media (max-width: 680px) {
  .hero__meta { gap: 1.25rem; flex-wrap: wrap; }
  .hero__meta > div:nth-child(3) { display: none; }
  .hero__cue { display: none; }
}

/* --- 8. Work grid -------------------------------------------------------- */

.work-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--gutter);
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

/* Even three-up grid. Every tile the same size, so the photographs are compared
   rather than ranked. */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 3.4vw, 3.25rem) var(--gutter);
}
@media (max-width: 1000px) { .work-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .work-grid { grid-template-columns: 1fr; } }

.project__media {
  position: relative; overflow: hidden;
  background: var(--paper-2);
  margin-bottom: 1rem;
  /* 4:3 rather than 3:2 — forgiving of the one portrait cover in the set. */
  aspect-ratio: 4 / 3;
}
.project__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1100ms var(--ease);
}
.project:hover .project__media img,
.project a:focus-visible .project__media img { transform: scale(1.04); }

.project__index {
  position: absolute; top: 0.9rem; left: 0.9rem; z-index: 2;
  font-family: var(--sans);
  color: #fff; font-size: 0.6875rem; letter-spacing: 0.14em;
  text-shadow: 0 1px 6px rgba(0,0,0,0.5);
}

.project__title {
  font-size: clamp(1.05rem, 1.3vw, 1.25rem);
  letter-spacing: -0.026em;
  margin: 0 0 0.3rem;
}
.project__meta { display: flex; flex-wrap: wrap; gap: 0.55rem; }
.project__meta span::after { content: "·"; margin-left: 0.55rem; }
.project__meta span:last-child::after { content: ""; }

/* A project credited to another firm carries that attribution everywhere. */
.credit {
  display: block;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-style: normal;
  color: var(--muted);
  margin-top: 0.35rem;
}

/* --- 9. Index (list view) ------------------------------------------------ */

.index-list { border-top: 1px solid var(--rule); }
.index-row {
  display: grid;
  grid-template-columns: 3.5rem 1fr 1fr 9rem 5rem;
  gap: var(--gutter);
  align-items: baseline;
  padding-block: clamp(1.1rem, 2vw, 1.6rem);
  border-bottom: 1px solid var(--rule);
  transition: background-color 350ms var(--ease), padding-inline 400ms var(--ease);
}
.index-row:hover { background: var(--paper-2); padding-inline: 1rem; }
.index-row__num { font-family: var(--sans); font-size: 0.6875rem; color: var(--muted); }
.index-row__title { font-size: clamp(1.05rem, 1.4vw, 1.25rem); font-weight: 600; letter-spacing: -0.024em; }
.index-row__loc, .index-row__type { font-family: var(--sans); font-size: 0.8125rem; color: var(--muted); }
.index-row__year {
  font-family: var(--sans); font-size: 0.8125rem; color: var(--muted);
  text-align: right; font-variant-numeric: tabular-nums;
}

@media (max-width: 860px) {
  .index-row { grid-template-columns: 2.5rem 1fr auto; row-gap: 0.25rem; }
  .index-row__loc  { grid-column: 2; }
  .index-row__type { grid-column: 2; }
  .index-row__year { grid-column: 3; grid-row: 1; }
}

.view-toggle { display: flex; gap: 1rem; align-items: baseline; }
.view-toggle button {
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  font-family: var(--sans); font-size: 0.6875rem; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--muted);
  transition: color 300ms var(--ease);
}
.view-toggle button[aria-pressed="true"] { color: var(--ink); }
.view-toggle button:hover { color: var(--ink); }

/* --- 9a. Project head ----------------------------------------------------- */

.project-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gutter);
  flex-wrap: wrap;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--rule);
}
.project-head__meta {
  display: flex;
  gap: clamp(1.5rem, 3vw, 3.5rem);
  margin: 0;
}
.project-head__meta dt { margin-bottom: 0.35rem; }
.project-head__meta dd { margin: 0; font-size: 0.9375rem; }

@media (max-width: 620px) {
  .project-head__meta { gap: 1.25rem; }
  .project-head__meta dd { font-size: 0.875rem; }
}

/* --- 9b. Slideshow (project pages) --------------------------------------- */

/*
 * A project page is a slideshow: one photograph at a time, click or arrow to
 * move. The stage is a fixed height with object-fit:contain so that mixing
 * portrait and landscape shots doesn't make the page jump on every step.
 */
.slideshow { position: relative; }

/*
 * The frame is sized to each photograph by JS rather than being one fixed shape
 * for all of them — a fixed frame mattes every photo that isn't the same ratio,
 * which looked like grey padding around the image. The aspect-ratio below is
 * only the pre-JS starting shape; it is replaced with exact pixel dimensions as
 * soon as a slide is shown.
 */
.slideshow__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  margin-inline: auto;
  background: var(--paper-2);
  overflow: hidden;
  transition: width 340ms var(--ease), height 340ms var(--ease);
}
@media (prefers-reduced-motion: reduce) { .slideshow__stage { transition: none; } }

.slide { margin: 0; position: absolute; inset: 0; }
.slide img, .slide video {
  display: block;
  width: 100%; height: 100%;
  /* The frame matches the photo, so cover and contain agree — contain is the
     safe choice if a photo's width/height attributes are ever wrong. */
  object-fit: contain;
  cursor: e-resize;
}

.slideshow__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 3;
  background: none; border: 0; padding: 0.9rem;
  cursor: pointer; color: var(--ink);
  opacity: 0.45;
  transition: opacity 300ms var(--ease);
}
.slideshow__nav:hover, .slideshow__nav:focus-visible { opacity: 1; }
.slideshow__nav--prev { left: clamp(0.25rem, 1.5vw, 1rem); }
.slideshow__nav--next { right: clamp(0.25rem, 1.5vw, 1rem); }
.slideshow__nav svg {
  width: clamp(1.75rem, 2.6vw, 2.25rem); height: clamp(1.75rem, 2.6vw, 2.25rem);
  fill: none; stroke: currentColor; stroke-width: 1.25;
  stroke-linecap: square; stroke-linejoin: miter;
}

.slideshow__count {
  margin: 1.1rem 0 0;
  text-align: center;
  font-family: var(--sans); font-size: 0.6875rem;
  letter-spacing: 0.14em; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 620px) {
  /* Arrows would sit over the photograph; swipe and tap-to-advance cover it. */
  .slideshow__nav { display: none; }
}

/* Without JS every slide simply stacks, so the photographs are all still there. */
.no-js .slideshow__stage { height: auto; aspect-ratio: auto; }
.no-js .slide { position: static; margin-bottom: var(--gutter); }
.no-js .slide img { height: auto; }
.no-js .slideshow__nav, .no-js .slideshow__count { display: none; }

/* --- 10. Project detail -------------------------------------------------- */

.spec {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}
.spec dt { margin-bottom: 0.4rem; }
.spec dd { margin: 0; font-size: 0.9375rem; }

.figure { margin: 0; }
.figure img { width: 100%; background: var(--paper-2); }
.figure figcaption {
  font-family: var(--sans);
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: var(--muted);
  max-width: 46ch;
}

/* Editorial layout for a project's own photographs — deliberately varied,
   unlike the even grid on the city pages. The pattern repeats every six, so a
   gallery of any length keeps the rhythm; without the 6n it would run out of
   rules and collapse every image past the sixth into a single column. */
.plates { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: clamp(2rem,4vw,4.5rem) var(--gutter); }
.plates .figure:nth-child(6n+1) { grid-column: 1 / -1; }
.plates .figure:nth-child(6n+2) { grid-column: 1 / span 5; }
.plates .figure:nth-child(6n+3) { grid-column: 7 / span 6; align-self: end; }
.plates .figure:nth-child(6n+4) { grid-column: 3 / span 8; }
.plates .figure:nth-child(6n+5) { grid-column: 1 / span 6; }
.plates .figure:nth-child(6n+6) { grid-column: 8 / span 5; align-self: end; }
@media (max-width: 900px) { .plates .figure { grid-column: 1 / -1 !important; } }

.pager {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--gutter);
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

/* --- 11. Contact --------------------------------------------------------- */

/*
 * A page laid over a full-bleed photograph:
 *   <body class="page-image">
 *     <div class="page-image__bg"><img src="assets/img/contact.jpg" alt=""></div>
 *
 * A real <img> rather than a CSS background, for two reasons: url() inside a
 * custom property resolves against the stylesheet's folder, not the page's, so
 * "assets/img/x.jpg" silently became "assets/assets/img/x.jpg"; and the
 * Squarespace build rewrites src attributes to the CDN but cannot rewrite a
 * URL buried in CSS.
 *
 * Fixed, so the photograph stays put while the content scrolls, with a scrim
 * heavy enough to hold white text and hairline form rules over a bright sky.
 */
.page-image { color: #fff; }

.page-image__bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
}
.page-image__bg img { width: 100%; height: 100%; object-fit: cover; }

.page-image::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.34) 26%, rgba(0,0,0,0.34) 70%, rgba(0,0,0,0.6) 100%),
    rgba(20,20,20,0.18);
}

/*
 * Type on this page follows the "Los Angeles" / "New York" treatment — bold,
 * mixed case, tight tracking — rather than the small tracked caps used for
 * labels elsewhere. Over a photograph the tiny caps were hard to read.
 */
.contact-title {
  font-size: clamp(2rem, 4.6vw, 3.75rem);
  font-weight: 700;
  letter-spacing: -0.038em;
  line-height: 1;
  margin: 0 0 clamp(2rem, 4vw, 3.25rem);
  color: #fff;
}

.page-image .field .label {
  font-size: clamp(0.9375rem, 0.85rem + 0.2vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  text-transform: none;
  color: rgba(255,255,255,0.94);
  margin-bottom: 0.4rem;
}
.page-image .field input,
.page-image .field textarea { font-size: 1.0625rem; }

.page-image .btn {
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-transform: none;
  padding: 0.85rem 2rem;
}

.page-image .footer__inner,
.page-image .footer a { font-weight: 700; letter-spacing: -0.02em; }

.page-image .label { color: rgba(255,255,255,0.88); }
.page-image .footer { border-top-color: rgba(255,255,255,0.22); }
.page-image .footer__inner { color: rgba(255,255,255,0.72); }
.page-image .footer a:hover { color: #fff; }
.page-image .btn:hover,
.page-image .btn:focus-visible { background: #fff; color: #141414; }

/* The default hairline is a fraction of currentColor, which is too faint to
   find over a photograph. */
.page-image .field input,
.page-image .field textarea,
.page-image .field select { border-bottom-color: rgba(255,255,255,0.5); }
.page-image .field input:focus,
.page-image .field textarea:focus,
.page-image .field select:focus { border-bottom-color: #fff; }
.page-image ::selection { background: #fff; color: #141414; }

/* The confirmation (or error) that replaces the form after Send. */
.page-image .form-status {
  margin: 1.5rem 0 0;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #fff;
}

/* The contact details, set large enough to be the thing you notice. */
.contact-direct a {
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  font-weight: 700;
  letter-spacing: -0.028em;
  display: inline-block;
}

.contact-page {
  display: flex;
  align-items: center;
  min-height: calc(100svh - var(--header-h));
  padding-block: clamp(2.5rem, 6vw, 5rem);
}

.contact { background: var(--invert-bg); color: var(--invert-fg); }
.contact .label { color: color-mix(in srgb, var(--invert-fg) 58%, transparent); }

.field { display: block; margin-bottom: 1.75rem; }
.field span { display: block; margin-bottom: 0.55rem; }
.field input, .field textarea, .field select {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, currentColor 28%, transparent);
  padding: 0.65rem 0;
  color: inherit;
  font-family: var(--sans);
  font-size: 1.0625rem;
  border-radius: 0;
  transition: border-color 350ms var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-bottom-color: currentColor;
}
.field textarea { resize: vertical; min-height: 6.5rem; }
.field select {
  appearance: none; -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.55rem center, right 0.25rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 1.75rem;
  cursor: pointer;
}
.field select option { color: var(--ink); background: var(--paper); }

.btn {
  display: inline-block;
  background: none;
  border: 1px solid currentColor;
  padding: 1rem 2.25rem;
  font-family: var(--sans);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: inherit;
  cursor: pointer;
  border-radius: 0;
  transition: background-color 400ms var(--ease), color 400ms var(--ease);
}
.btn:hover, .btn:focus-visible { background: var(--ink); color: var(--paper); }
.contact .btn:hover, .contact .btn:focus-visible { background: var(--invert-fg); color: var(--invert-bg); }

/* --- 12. Footer ---------------------------------------------------------- */

.footer { padding-block: clamp(3rem, 5vw, 4.5rem); border-top: 1px solid var(--rule); }
.footer__inner {
  display: flex; flex-wrap: wrap; gap: var(--gutter);
  justify-content: space-between; align-items: baseline;
  font-family: var(--sans);
  font-size: 0.8125rem; color: var(--muted);
}
.footer a:hover { color: var(--ink); }

/* --- 13. Reveal & lightbox ----------------------------------------------- */

[data-reveal] {
  opacity: 0; transform: translateY(1.35rem);
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
  transition-delay: var(--d, 0ms);
}
[data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
}
.no-js [data-reveal] { opacity: 1; transform: none; }

[data-zoom] { cursor: zoom-in; }

.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3.5rem);
  background: color-mix(in srgb, var(--invert-bg) 96%, transparent);
  opacity: 0;
  transition: opacity 380ms var(--ease);
}
.lightbox.is-open { opacity: 1; }

.lightbox__stage {
  margin: 0;
  display: flex; flex-direction: column; align-items: center;
  gap: 0.9rem;
  max-width: 100%; max-height: 100%;
  min-width: 0;
}
.lightbox img {
  max-width: 100%;
  /* Leave room for the caption and the counter below. */
  max-height: calc(100svh - 9rem);
  object-fit: contain;
  transform: scale(0.985);
  transition: transform 480ms var(--ease);
  cursor: e-resize;
}
.lightbox.is-open img { transform: none; }

.lightbox__caption {
  font-family: var(--sans); font-size: 0.8125rem;
  color: color-mix(in srgb, var(--invert-fg) 66%, transparent);
  text-align: center; max-width: 54ch;
}

.lightbox__close {
  position: absolute; top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem);
  background: none; border: 0; padding: 0.5rem; cursor: pointer;
  color: var(--invert-fg);
  font-family: var(--sans); font-size: 0.6875rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  z-index: 2;
}

.lightbox__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 2;
  background: none; border: 0; padding: 0.75rem;
  cursor: pointer; color: var(--invert-fg);
  opacity: 0.55;
  transition: opacity 300ms var(--ease);
}
.lightbox__nav:hover, .lightbox__nav:focus-visible { opacity: 1; }
.lightbox__nav--prev { left: clamp(0.25rem, 2vw, 1.5rem); }
.lightbox__nav--next { right: clamp(0.25rem, 2vw, 1.5rem); }
.lightbox__nav svg {
  width: clamp(1.75rem, 3vw, 2.5rem); height: clamp(1.75rem, 3vw, 2.5rem);
  fill: none; stroke: currentColor; stroke-width: 1.25;
  stroke-linecap: square; stroke-linejoin: miter;
}

.lightbox__count {
  position: absolute; bottom: clamp(1rem, 3vw, 2rem); left: 50%;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--sans); font-size: 0.6875rem;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--invert-fg) 62%, transparent);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 620px) {
  /* The arrows would sit on top of the photograph at this width; swipe and the
     tap-to-advance on the image itself cover it. */
  .lightbox__nav { display: none; }
  .lightbox img { max-height: calc(100svh - 8rem); }
}

@media (prefers-reduced-motion: reduce) { .lightbox, .lightbox img { transition: none; } }

/* Count badge on a grid card, so it reads as a set before you click. */
.project__count {
  position: absolute; bottom: 0.75rem; right: 0.75rem; z-index: 2;
  font-family: var(--sans); font-size: 0.625rem;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #fff;
  background: rgba(0,0,0,0.42);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 0.3rem 0.55rem;
  opacity: 0; transform: translateY(0.25rem);
  transition: opacity 350ms var(--ease), transform 350ms var(--ease);
}
.project:hover .project__count,
.project a:focus-visible .project__count { opacity: 1; transform: none; }

/* --- 14. Utilities ------------------------------------------------------- */

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; top: -100%; left: var(--pad); z-index: 200;
  background: var(--ink); color: var(--paper);
  padding: 0.75rem 1.25rem; font-size: 0.8125rem;
}
.skip-link:focus { top: 1rem; }

.col-span-4 { grid-column: span 4; }
.col-span-5 { grid-column: span 5; }
.col-span-6 { grid-column: span 6; }
.col-span-7 { grid-column: span 7; }
.col-start-6 { grid-column: 6 / -1; }
.col-start-7 { grid-column: 7 / -1; }
@media (max-width: 900px) {
  .col-span-4, .col-span-5, .col-span-6, .col-span-7,
  .col-start-6, .col-start-7 { grid-column: 1 / -1; }
}

.stack > * + * { margin-top: var(--s, 1.5rem); }

/* --- 15. Print ----------------------------------------------------------- */

@media print {
  .header, .nav-toggle, .contact form, .pager { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .hero, .split { height: auto; }
  a { text-decoration: underline; }
}
