:root {
  color-scheme: dark;
  --bg: #070806;
  --ink: #f4f2ee;
  --muted: rgba(244, 242, 238, 0.72);
  --soft: rgba(244, 242, 238, 0.14);
  --line: rgba(244, 242, 238, 0.22);
  --accent: #d8ff55;
  --heat: #d14b3a;
  --cool: #80d8e8;
  --max: 1820px;
  --nav-x: clamp(18px, 2.7vw, 46px);
  --nav-y: clamp(18px, 2.7vw, 46px);
  --brand-font-size: clamp(1.35rem, 0.98rem + 1.16vw, 2.25rem);
  --button-font-size: clamp(0.78rem, 0.64rem + 0.42vw, 1.1rem);
  --nav-icon-size: clamp(1.22rem, 0.9rem + 0.72vw, 1.72rem);
  --button-font: "Helvetica Neue", "Avenir Next", Avenir, Helvetica, Arial, sans-serif;
  --brand-letter-spacing: 0.16em;
  --button-letter-spacing: 0.12em;
  --nav-font-size: var(--brand-font-size);
  --nav-letter-spacing: var(--brand-letter-spacing);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-width: 320px;
  background: #000;
  color: var(--ink);
  font-family: Inter, Arial, Helvetica, sans-serif;
  overflow-x: hidden;
}

.home-page {
  height: 100svh;
  overflow: hidden;
}

body::after {
  content: none;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
}

.instagram-icon {
  display: inline-flex;
  width: var(--nav-icon-size);
  height: var(--nav-icon-size);
  flex: 0 0 var(--nav-icon-size);
  align-items: center;
  justify-content: center;
  line-height: 0;
}

.instagram-icon svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
}

.mail-icon svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
}

.social-icons {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  line-height: 0;
}

.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
}

.hero::before {
  content: none;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  background: #000;
}

.hero-media::after {
  content: none;
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.15);
  transform-origin: center;
  opacity: 0;
  transition: opacity 700ms ease;
}

.hero.has-video .hero-video {
  opacity: 1;
}

.hero-name {
  position: absolute;
  top: var(--nav-y);
  left: var(--nav-x);
  z-index: 2;
  margin: 0;
  color: rgba(244, 242, 238, 0.98);
  font-family: var(--button-font);
  font-size: var(--brand-font-size);
  font-weight: 300;
  line-height: 1;
  letter-spacing: var(--brand-letter-spacing);
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.46);
}

.hero-instagram {
  position: absolute;
  top: var(--nav-y);
  right: var(--nav-x);
  z-index: 2;
  color: rgba(244, 242, 238, 0.92);
  filter: drop-shadow(0 2px 18px rgba(0, 0, 0, 0.46));
}

.home-actions {
  position: absolute;
  right: clamp(24px, 4vw, 60px);
  top: 50%;
  left: clamp(24px, 4vw, 60px);
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 24px;
  color: rgba(244, 242, 238, 0.88);
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.32);
  transform: translateY(-50%);
}

.enter-archive {
  grid-column: 2;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--button-font);
  font-size: var(--brand-font-size);
  font-weight: 400;
  letter-spacing: var(--button-letter-spacing);
  line-height: 1;
  text-transform: uppercase;
}

.archive-label {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(10px);
  transition:
    max-width 260ms ease,
    opacity 180ms ease,
    transform 220ms ease;
  white-space: nowrap;
}

.archive-arrow {
  font-size: 1.15em;
  font-weight: 400;
  transition: transform 180ms ease;
}

.enter-archive:hover .archive-label,
.enter-archive:focus-visible .archive-label {
  max-width: 18ch;
  opacity: 1;
  transform: translateX(0);
}

.enter-archive:hover .archive-arrow,
.enter-archive:focus-visible .archive-arrow {
  transform: translateX(8px);
}

.home-contact {
  position: fixed;
  right: clamp(24px, 4vw, 60px);
  bottom: clamp(24px, 4vw, 60px);
  z-index: 3;
  color: rgba(244, 242, 238, 0.92);
  filter: drop-shadow(0 2px 18px rgba(0, 0, 0, 0.38));
}

.projects {
  width: min(100%, var(--max));
  margin: 0 auto;
}

.projects {
  padding: clamp(14px, 1.6vw, 28px) clamp(20px, 3vw, 58px) clamp(52px, 8vw, 120px);
}

.project-row {
  display: grid;
  grid-template-columns: minmax(240px, 0.38fr) minmax(300px, 0.62fr);
  gap: clamp(18px, 2.6vw, 42px);
  padding: 12px 0;
  border-top: 1px solid rgba(244, 242, 238, 0.34);
}

.project-row:last-child {
  border-bottom: 1px solid rgba(244, 242, 238, 0.34);
}

.project-image {
  position: relative;
  display: block;
  height: clamp(210px, 25vw, 430px);
  overflow: hidden;
  background: var(--fallback);
}

.project-image::after {
  content: none;
}

.project-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-image--wrinkles img {
  object-position: center 34%;
}

.project-image--untitled-folder-2 img {
  object-position: center 30%;
}

.project-image--untitled-folder img {
  object-position: center 86%;
}

.project-image img[src=""],
.project-image img.is-missing {
  display: none;
}

.project-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  min-height: 100%;
  padding-top: clamp(4px, 0.9vw, 14px);
}

.project-meta {
  display: flex;
  gap: clamp(30px, 5vw, 72px);
  color: rgba(244, 242, 238, 0.48);
  font-size: clamp(0.98rem, 0.84rem + 0.42vw, 1.34rem);
  font-weight: 500;
  line-height: 1.05;
}

.project-copy h2 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(1.58rem, 1.1rem + 1.35vw, 2.65rem);
  font-weight: 800;
  line-height: 0.96;
  letter-spacing: 0;
  text-transform: uppercase;
}

.project-label {
  color: rgba(244, 242, 238, 0.58);
  font-family: var(--button-font);
  font-size: clamp(0.76rem, 0.66rem + 0.28vw, 0.98rem);
  font-weight: 300;
  letter-spacing: var(--button-letter-spacing);
  line-height: 1;
  text-transform: uppercase;
}

.project-copy p,
.read-more {
  max-width: 680px;
  margin: 0;
  font-size: clamp(1rem, 0.86rem + 0.42vw, 1.34rem);
  font-weight: 500;
  line-height: 1.16;
}

.project-description-preview {
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}


.read-more {
  margin-top: auto;
  margin-bottom: clamp(8px, 0.9vw, 14px);
  width: fit-content;
  color: rgba(244, 242, 238, 0.48);
  font-family: var(--button-font);
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.project-page {
  min-height: 100svh;
  background: #151515;
}

.archive-page {
  background: #151515;
}

.gallery-page {
  min-height: 100svh;
  background: #f7f7f5;
  color: #3f403d;
}

.info-page {
  min-height: 100svh;
  background: #f7f7f5;
  color: #171816;
}

.gallery-nav {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 3;
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: var(--nav-y) var(--nav-x);
  color: #2e302d;
  font-family: var(--button-font);
  font-size: var(--nav-font-size);
  font-weight: 300;
  line-height: 1;
  letter-spacing: var(--nav-letter-spacing);
  text-transform: uppercase;
}

.gallery-nav div {
  display: flex;
  align-items: center;
  gap: 22px;
}

.gallery-nav div a:not(.instagram-icon),
.project-nav a:nth-child(2),
.project-nav-right a:not(.instagram-icon) {
  font-size: var(--button-font-size);
  font-weight: 300;
  letter-spacing: var(--button-letter-spacing);
}

.photo-viewer {
  display: grid;
  min-height: 100svh;
  align-content: center;
  row-gap: clamp(18px, 3vw, 36px);
  padding: clamp(56px, 6vw, 92px) clamp(18px, 5vw, 96px) clamp(44px, 7vw, 92px);
  place-items: center;
}

.viewer-frame {
  display: grid;
  grid-template-columns: repeat(2, minmax(220px, 410px));
  gap: clamp(20px, 2.8vw, 34px);
  align-items: center;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0;
  opacity: 1;
  transition: opacity 420ms ease;
}

.viewer-frame.is-fading-out {
  opacity: 0;
  pointer-events: none;
}

.viewer-frame.is-fading-in {
  opacity: 1;
  pointer-events: none;
}

.viewer-frame.is-single {
  grid-template-columns: minmax(220px, min(72vw, 860px));
}

.viewer-frame.is-single .viewer-photo img {
  max-height: min(66svh, 780px);
}

.viewer-frame.series-03 .viewer-photo {
  aspect-ratio: 3222 / 4296;
  overflow: hidden;
}

.viewer-frame.series-03 .viewer-photo img {
  height: 100%;
  max-height: none;
}

.viewer-frame.series-03 .viewer-photo:nth-child(2) img {
  object-fit: cover;
  object-position: center center;
}

.viewer-frame.series-07 {
  grid-template-columns: auto auto;
  max-width: 100%;
  justify-content: center;
}

.viewer-frame.series-07 .viewer-photo {
  width: auto;
}

.viewer-frame.series-07 .viewer-photo img {
  width: auto;
  height: min(64svh, 680px, 46vw);
  max-height: none;
}

.viewer-photo {
  display: block;
  width: 100%;
  background: transparent;
}

.viewer-photo img {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(64svh, 680px);
  object-fit: contain;
}

.viewer-photo img.is-missing {
  display: none;
}

.viewer-frame.is-single .viewer-photo:has(img.is-missing) {
  display: none;
}

.viewer-caption {
  margin: 0;
  color: #4a4b48;
  font-size: clamp(0.82rem, 0.72rem + 0.28vw, 1rem);
  font-style: italic;
  font-weight: 600;
  letter-spacing: 0;
  text-align: center;
  text-transform: uppercase;
  pointer-events: none;
}

/* Shared menu primitives. Page-specific rules decide where the
   hamburger appears; the button itself stays reusable across
   archive, projects, and project detail pages. */
.menu-toggle {
  position: relative;
  z-index: 5;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 8px;
  margin: -8px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  line-height: 0;
}

.menu-toggle svg {
  width: 1.7rem;
  height: 1.7rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
}

.menu-toggle .menu-icon-close {
  display: none;
}

.menu-toggle[aria-expanded="true"] .menu-icon-open {
  display: none;
}

.menu-toggle[aria-expanded="true"] .menu-icon-close {
  display: block;
}

/* Side-drawer menu panel. Shared across all pages that have a
   hamburger toggle. Slides in from the right; the rest of the
   page is covered by .menu-backdrop. */
.menu-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  width: min(480px, calc(100vw - 48px));
  padding: 72px 48px 48px;
  background: #ffffff;
  color: rgba(15, 15, 14, 0.9);
  box-shadow: -16px 0 56px rgba(0, 0, 0, 0.18);
  font-family: var(--button-font);
  transform: translateX(100%);
  visibility: hidden;
  overflow-y: auto;
  will-change: transform;
  transition:
    transform 480ms cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 480ms;
}

/* Close button inside the panel */
.menu-close {
  position: absolute;
  top: 24px;
  right: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: rgba(15, 15, 14, 0.4);
  cursor: pointer;
  line-height: 0;
  transition: color 200ms ease;
}

.menu-close:hover {
  color: rgba(15, 15, 14, 0.9);
}

.menu-close svg {
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
}

.menu-panel .menu-link {
  display: block;
  font-size: clamp(1.9rem, 3.5vw, 3rem);
  font-weight: 300;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: rgba(15, 15, 14, 0.9);
  line-height: 1.2;
  padding: 0.22em 0;
  transition: color 180ms ease;
}

.menu-panel .menu-link:hover {
  color: rgba(15, 15, 14, 0.3);
}

.menu-panel .menu-icons {
  display: flex;
  align-items: center;
  gap: 26px;
  margin-top: auto;
  padding-top: 36px;
  border-top: 1px solid rgba(15, 15, 14, 0.1);
}

.menu-panel .menu-icons .instagram-icon {
  color: rgba(15, 15, 14, 0.5);
  transition: color 180ms ease;
}

.menu-panel .menu-icons .instagram-icon:hover {
  color: rgba(15, 15, 14, 0.9);
}

/* Semi-transparent overlay that fades in behind the panel */
.menu-backdrop {
  position: fixed;
  inset: 0;
  z-index: 49;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  pointer-events: none;
  touch-action: none;
  transition: opacity 420ms ease;
}

.menu-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* Prevent body scroll while drawer is open */
.menu-is-open {
  overflow: hidden;
}

.info-content {
  display: grid;
  min-height: 100svh;
  align-items: center;
  padding: clamp(96px, 13vw, 180px) var(--nav-x) clamp(72px, 10vw, 130px);
}

.info-grid {
  display: grid;
  grid-template-columns: minmax(260px, 0.72fr) minmax(360px, 1fr);
  gap: clamp(64px, 10vw, 150px);
  width: min(100%, 820px);
  margin: 0 auto;
  color: #151614;
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: clamp(0.82rem, 0.72rem + 0.25vw, 1rem);
  font-weight: 600;
  line-height: 1.52;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.info-grid p {
  margin: 0;
}

.info-contact {
  display: grid;
  align-content: start;
  gap: 28px;
}

.info-bio {
  max-width: 430px;
}

.project-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 20px;
  padding: var(--nav-y) var(--nav-x);
  color: rgba(244, 242, 238, 0.96);
  font-family: var(--button-font);
  font-size: var(--nav-font-size);
  font-weight: 300;
  line-height: 1;
  letter-spacing: var(--nav-letter-spacing);
  text-transform: uppercase;
}

.project-page .project-nav {
  position: sticky;
  top: 0;
  z-index: 5;
  background: transparent;
  isolation: isolate;
}

.project-page .project-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.58));
  box-shadow:
    0 18px 44px rgba(0, 0, 0, 0.26),
    inset 0 -1px 0 rgba(244, 242, 238, 0.08);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-100%);
  transition:
    opacity 360ms ease,
    transform 440ms cubic-bezier(0.22, 1, 0.36, 1);
  backdrop-filter: blur(18px) saturate(128%);
  -webkit-backdrop-filter: blur(18px) saturate(128%);
  will-change: opacity, transform;
}

.project-page .project-nav.is-glass-nav-visible::before,
.project-page .project-nav.is-open::before {
  opacity: 1;
  transform: translateY(0);
}

.project-page .project-nav > * {
  position: relative;
  z-index: 1;
}

.project-nav a:nth-child(2) {
  justify-self: center;
}

.project-nav a:last-child {
  justify-self: end;
}

.project-nav-right {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: clamp(18px, 2vw, 34px);
}

.project-nav sup {
  color: rgba(244, 242, 238, 0.38);
  font-size: 0.5em;
}

.archive-nav {
  background: #151515;
}

.archive-page .archive-nav {
  transition:
    opacity 220ms ease,
    transform 220ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}

.gallery-page,
.archive-page,
.project-page {
  --nav-x: 22px;
  --nav-y: 24px;
  --brand-font-size: 1.55rem;
  --brand-letter-spacing: 0.2em;
  --nav-icon-size: 1.95rem;
}

.gallery-page .gallery-nav,
.archive-page .project-nav,
.project-page .project-nav {
  z-index: 5;
  align-items: center;
  font-weight: 400;
}

.archive-page .project-nav,
.project-page .project-nav {
  display: flex;
  grid-template-columns: none;
  gap: 0;
}

.archive-page .project-nav {
  position: relative;
  box-sizing: border-box;
  min-height: calc((var(--nav-y) * 2) + 1.7rem);
}

.gallery-page .gallery-nav > a,
.archive-page .project-nav > a:first-child,
.project-page .project-nav > a:first-child {
  position: absolute;
  top: var(--nav-y);
  left: var(--nav-x);
  margin: 0;
  white-space: nowrap;
  font-size: 1.55rem;
  font-weight: 400;
  letter-spacing: 0.2em;
}

.gallery-page .gallery-nav > div,
.archive-page .project-nav > a:nth-child(2),
.archive-page .project-nav-right,
.project-page .project-nav > a:nth-child(2),
.project-page .project-nav-right {
  display: none;
}

.gallery-page .menu-toggle,
.archive-page .menu-toggle,
.project-page .menu-toggle {
  display: inline-flex;
  margin-left: auto;
}

/* Panel open state – slide in from the right. */
.gallery-page .gallery-nav.is-open + .menu-panel,
.info-page .gallery-nav.is-open + .menu-panel,
.archive-page .project-nav.is-open + .menu-panel,
.project-page .project-nav.is-open + .menu-panel {
  transform: translateX(0);
  visibility: visible;
  pointer-events: auto;
  transition:
    transform 480ms cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s;
}

.archive-page .project-nav.is-open {
  background: transparent;
}

.archive-page.is-project-transitioning {
  cursor: progress;
}

.archive-page.is-project-transitioning .archive-nav {
  z-index: 40;
}

.archive-page.is-project-header-fading .archive-nav {
  opacity: 0;
  pointer-events: none;
  transform: translateY(-10px);
}

.archive-page.is-project-layer-lifting .archive-nav {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
  transition:
    opacity 520ms ease 70ms,
    transform 520ms cubic-bezier(0.16, 1, 0.3, 1) 70ms;
}

.project-transition-layer {
  position: fixed;
  top: var(--project-transition-top, 0px);
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 30;
  overflow: hidden;
  background: #151515;
  box-shadow: 0 -28px 70px rgba(0, 0, 0, 0.46);
  opacity: 0.98;
  pointer-events: none;
  transform: translateY(100%);
  transition:
    transform 980ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity 420ms ease;
  will-change: transform, opacity;
}

.project-transition-layer.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.project-transition-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: #151515;
}

.project-transition-embed body.project-page {
  min-height: 100%;
  overflow: hidden;
}

.project-transition-embed body.project-page .project-nav,
.project-transition-embed body.project-page .menu-panel,
.project-transition-embed body.project-page .menu-backdrop,
.project-transition-embed body.project-page .project-pager {
  display: none !important;
}

.project-article {
  width: min(100% - clamp(36px, 8vw, 180px), 1320px);
  margin: 0 auto;
  padding: clamp(28px, 5vw, 84px) 0 94px;
}

.project-article h1 {
  max-width: 1100px;
  margin: 0 0 clamp(14px, 2.1vw, 30px);
  color: var(--ink);
  font-size: clamp(3.1rem, 6.4vw, 7.4rem);
  font-weight: 900;
  line-height: 0.92;
  letter-spacing: 0;
  text-transform: uppercase;
}

.project-info {
  display: grid;
  gap: clamp(24px, 3vw, 44px);
  margin-bottom: clamp(80px, 10vw, 140px);
  color: rgba(244, 242, 238, 0.84);
  font-size: clamp(0.96rem, 0.84rem + 0.32vw, 1.24rem);
  font-weight: 600;
  line-height: 1.25;
}

.project-info p {
  margin: 0;
}

.project-kicker {
  color: rgba(244, 242, 238, 0.58);
  font-family: Inter, Arial, Helvetica, sans-serif;
  font-size: clamp(0.76rem, 0.66rem + 0.28vw, 0.98rem);
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
}

.project-description {
  max-width: min(100%, 880px);
  font-size: clamp(1rem, 0.88rem + 0.3vw, 1.22rem);
  font-weight: 500;
  line-height: 1.55;
  color: rgba(244, 242, 238, 0.92);
}

.project-attribution {
  display: block;
  width: fit-content;
  margin-left: clamp(110px, 14vw, 250px);
  margin-top: clamp(22px, 3vw, 44px);
  font: inherit;
  font-weight: 500;
  line-height: inherit;
  color: rgba(244, 242, 238, 0.82);
}

.project-info .credit {
  font-family: "Courier New", Courier, monospace;
}

.project-body {
  display: grid;
  gap: clamp(42px, 6vw, 76px);
  color: rgba(244, 242, 238, 0.9);
  font-size: clamp(1rem, 0.88rem + 0.36vw, 1.28rem);
  font-weight: 600;
  line-height: 1.22;
}

.project-body p {
  max-width: 1380px;
  margin: 0;
}

.project-collection {
  width: min(100% - clamp(36px, 8vw, 180px), 1500px);
}

.project-gallery {
  display: grid;
  gap: clamp(28px, 5vw, 76px);
  justify-items: center;
}

.project-gallery img {
  display: block;
  width: auto;
  max-width: min(100%, 1120px);
  max-height: none;
  height: auto;
}

.scroll-reveal {
  opacity: 0;
  translate: 0 40px;
  transition:
    opacity 0.8s ease-out,
    translate 0.8s ease-out;
}

.scroll-reveal.in-view {
  opacity: 1;
  translate: 0 0;
}

.project-gallery img[src=""],
.project-gallery img.is-missing {
  display: none;
}

.project-gallery--folder-two {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(48px, 7vw, 120px);
  align-items: start;
}

.project-gallery--folder-two .folder-two-tetraptych {
  grid-column: 1 / -1;
  max-width: min(70%, 784px);
}

.project-gallery--folder-two .folder-two-layout {
  grid-column: 1 / -1;
  justify-self: stretch;
}

.folder-two-layout {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: clamp(12px, 1.6vw, 28px);
  row-gap: clamp(60px, 7vw, 140px);
  width: 100%;
  margin-top: clamp(80px, 8vw, 140px);
  align-items: start;
}

.folder-two-layout .img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  object-fit: cover;
  opacity: 0;
  transform: translateY(40px);
  transition:
    opacity 0.8s ease-out,
    transform 0.8s ease-out;
}

.folder-two-layout .img.in-view {
  opacity: 1;
  transform: translateY(0);
}

.folder-two-layout .img-1 {
  grid-column: 2 / span 5;
  grid-row: 1;
}

.folder-two-layout .img-2 {
  grid-column: 9 / span 3;
  grid-row: 1;
  margin-top: clamp(140px, 16vw, 280px);
}

.folder-two-layout .img-3 {
  grid-column: 4 / span 6;
  grid-row: 2;
}

.folder-two-layout .img-4 {
  grid-column: 2 / span 5;
  grid-row: 3;
}

.folder-two-layout .img-5 {
  grid-column: 9 / span 3;
  grid-row: 3;
  margin-top: clamp(140px, 16vw, 280px);
}

.folder-two-layout .img-6 {
  grid-column: 4 / span 6;
  grid-row: 4;
}

@media (max-width: 768px) {
  .folder-two-layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(8px, 2vw, 18px);
    row-gap: clamp(12px, 3vw, 24px);
    margin-top: 60px;
  }

  .folder-two-layout .img-1,
  .folder-two-layout .img-2,
  .folder-two-layout .img-3,
  .folder-two-layout .img-4,
  .folder-two-layout .img-5,
  .folder-two-layout .img-6 {
    grid-column: auto;
    grid-row: auto;
    margin-top: 0;
    width: 100%;
    justify-self: stretch;
  }
}

/* ===========================
   project-001 — Still Life
   Desktop editorial layout.
   All values use cqw so the
   composition scales as one
   unit with the gallery's
   container width (locked
   relative positions).
   Narrow-screen 2-col grid is
   handled in the
   @media (max-width: 820px)
   block further below.
   =========================== */

.project-gallery--still-life {
  container-type: inline-size;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 9cqw;
  align-items: start;
}

.project-gallery--still-life img:nth-child(n + 3) {
  grid-column: 1 / -1;
}

.project-gallery--still-life img:first-child {
  grid-column: 1;
  grid-row: 1;
  justify-self: end;
  width: 42cqw;
}

.project-gallery--still-life img:nth-child(2) {
  grid-column: 2;
  grid-row: 1;
  justify-self: start;
  width: 44cqw;
  margin-top: 14cqw;
}

.project-gallery--still-life img:nth-child(3) {
  width: 42cqw;
  justify-self: start;
  margin-left: 8cqw;
  margin-top: 4cqw;
}

.project-gallery--still-life img:nth-child(4) {
  width: 36cqw;
  justify-self: end;
  margin-right: 6cqw;
  margin-top: -12cqw;
}

.project-gallery--still-life img:nth-child(5) {
  width: 30cqw;
  justify-self: start;
  margin-left: 14cqw;
  margin-top: -4cqw;
}

.project-gallery--still-life img:nth-child(6) {
  width: 48cqw;
  justify-self: center;
  margin-top: 4cqw;
}

/* Project-001 text overrides have been promoted into
   the base .project-info / .project-description rules
   above so every project page shares the same text
   layout. Page-specific text overrides can go here
   in the future if needed. */

.project-gallery--wrinkles img:first-child {
  grid-column: 1;
  grid-row: 1;
  justify-self: end;
  width: 36cqw;
}

.project-gallery--wrinkles img:nth-child(2) {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  width: 43.2cqw;
  margin-top: 15cqw;
}

.project-gallery--wrinkles img:nth-child(3) {
  width: 36cqw;
}

.project-gallery--wrinkles .wrinkles-photo-shift {
  position: relative;
  z-index: 2;
  transform: translate(-18cqw, -8cqw);
}

.project-gallery--wrinkles img:nth-child(4) {
  width: 32.752512cqw;
  transform: translateX(15.12cqw);
}

.project-gallery--wrinkles img:nth-child(5) {
  width: 26.2020096cqw;
  transform: translate(-17cqw, -24cqw);
}

.project-gallery--wrinkles img:nth-child(6) {
  width: 24cqw;
  justify-self: end;
  margin-right: 10cqw;
  margin-top: -34cqw;
}

.project-gallery--wrinkles img:nth-child(7) {
  width: 22cqw;
  justify-self: start;
  margin-left: 16cqw;
  margin-top: -13cqw;
}

.project-gallery--wrinkles img:nth-child(8) {
  width: 34cqw;
  justify-self: center;
  margin-top: -8cqw;
}


.project-gallery--wrinkles {
  container-type: inline-size;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 11cqw;
  align-items: start;
}

.project-gallery--wrinkles img:nth-child(n + 3) {
  grid-column: 1 / -1;
}

/* ===========================
   project-005 — Untamed Soul
   Desktop editorial layout.
   10 images arranged with two
   2-up paired moments breaking
   up full-row solo pieces, for
   a unique rhythm vs. wrinkles.
   All values use cqw so the
   composition scales as one
   unit with the gallery's
   container width.
   Narrow-screen 2-col grid is
   handled in the
   @media (max-width: 820px)
   block further below.
   =========================== */

.project-gallery--untamed-soul {
  container-type: inline-size;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 8cqw;
  align-items: start;
}

/* Full-row images: 1, 4, 5, 8, 9, 10 */
.project-gallery--untamed-soul img:first-child,
.project-gallery--untamed-soul img:nth-child(4),
.project-gallery--untamed-soul img:nth-child(5),
.project-gallery--untamed-soul img:nth-child(8),
.project-gallery--untamed-soul img:nth-child(9),
.project-gallery--untamed-soul img:nth-child(10) {
  grid-column: 1 / -1;
}

/* img 1 — opener, left-anchored, dominant */
.project-gallery--untamed-soul img:first-child {
  width: 46cqw;
  justify-self: start;
  margin-left: 6cqw;
}

/* img 2, 3 — first 2-up pair (col 1 higher, col 2 dropped) */
.project-gallery--untamed-soul img:nth-child(2) {
  grid-column: 1;
  justify-self: end;
  width: 38cqw;
  margin-top: 6cqw;
}

.project-gallery--untamed-soul img:nth-child(3) {
  grid-column: 2;
  justify-self: start;
  width: 42cqw;
  margin-top: 18cqw;
}

/* img 4 — right-anchored, lifted to interlock with row above */
.project-gallery--untamed-soul img:nth-child(4) {
  width: 36cqw;
  justify-self: end;
  margin-right: 8cqw;
  margin-top: -6cqw;
}

/* img 5 — center, large statement */
.project-gallery--untamed-soul img:nth-child(5) {
  width: 50cqw;
  justify-self: center;
  margin-top: 4cqw;
}

/* img 6, 7 — second 2-up pair (opposite asymmetry from row 2) */
.project-gallery--untamed-soul img:nth-child(6) {
  grid-column: 1;
  justify-self: end;
  width: 42cqw;
  margin-top: 16cqw;
}

.project-gallery--untamed-soul img:nth-child(7) {
  grid-column: 2;
  justify-self: start;
  width: 38cqw;
  margin-top: 4cqw;
}

/* img 8 — left dominant */
.project-gallery--untamed-soul img:nth-child(8) {
  width: 44cqw;
  justify-self: start;
  margin-left: 8cqw;
  margin-top: 4cqw;
}

/* img 9 — right, lifted */
.project-gallery--untamed-soul img:nth-child(9) {
  width: 36cqw;
  justify-self: end;
  margin-right: 6cqw;
  margin-top: -8cqw;
}

/* img 10 — finale, center, largest */
.project-gallery--untamed-soul img:nth-child(10) {
  width: 52cqw;
  justify-self: center;
  margin-top: 4cqw;
}

/* ===========================
   PROJECT-002 — UNTITLED FOLDER
   Three-photograph editorial layout.
   Top pair sits asymmetrically on row 1 with a deep
   right-side drop for negative space; the closing image
   sits centered on row 2 as a feature beat.
   The shared narrow-screen reset (further below) collapses
   this to a clean 2-column grid; one extra override in this
   file makes image 3 span the full row on narrow screens.
   =========================== */

.project-gallery--folder {
  container-type: inline-size;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 6cqw;
  align-items: start;
}

.project-gallery--folder img:first-child {
  grid-column: 1;
  grid-row: 1;
  justify-self: end;
  width: 46cqw;
}

.project-gallery--folder img:nth-child(2) {
  grid-column: 2;
  grid-row: 1;
  justify-self: start;
  width: 32cqw;
  margin-top: 22cqw;
}

.project-gallery--folder img:nth-child(3) {
  grid-column: 1 / -1;
  grid-row: 2;
  width: 54cqw;
  justify-self: center;
  margin-top: 6cqw;
}

.project-detail-image {
  display: block;
  width: min(100%, 920px);
  min-height: clamp(320px, 44vw, 680px);
  margin: clamp(12px, 2vw, 28px) 0;
  object-fit: cover;
  background: #050505;
}

.project-detail-image.is-missing {
  display: none;
}

.project-pager {
  position: fixed;
  right: clamp(18px, 3vw, 46px);
  bottom: 28px;
  left: clamp(18px, 3vw, 46px);
  display: flex;
  justify-content: space-between;
  color: rgba(244, 242, 238, 0.9);
  font-size: clamp(0.95rem, 0.82rem + 0.35vw, 1.18rem);
  font-weight: 700;
  text-transform: uppercase;
  pointer-events: none;
}

.project-pager a {
  pointer-events: auto;
}

@media (max-width: 1180px) {
  .project-row {
    grid-template-columns: minmax(220px, 0.42fr) minmax(260px, 0.58fr);
  }

  .project-image {
    height: clamp(200px, 30vw, 360px);
  }
}

@media (min-width: 721px) {
  .archive-page {
    height: 100svh;
    overflow: hidden;
  }

  .archive-page main {
    height: calc(100svh - (var(--nav-y) * 2 + var(--brand-font-size)));
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scrollbar-color: rgba(244, 242, 238, 0.32) transparent;
    scrollbar-width: thin;
  }

  .archive-page main::-webkit-scrollbar {
    height: 8px;
  }

  .archive-page main::-webkit-scrollbar-track {
    background: transparent;
  }

  .archive-page main::-webkit-scrollbar-thumb {
    background: rgba(244, 242, 238, 0.24);
  }

  .archive-page .projects {
    display: flex;
    width: max-content;
    max-width: none;
    min-height: 100%;
    margin: 0;
    padding: clamp(120px, 19vh, 230px) var(--nav-x) clamp(34px, 6vh, 82px);
    align-items: flex-end;
    gap: clamp(24px, 2vw, 42px);
    scroll-snap-type: x proximity;
  }

  .archive-page.is-project-transitioning .archive-nav {
    position: relative;
  }

  .archive-page .project-row {
    position: relative;
    display: block;
    flex: 0 0 clamp(520px, 42vw, 790px);
    padding: 0;
    border: 0;
    scroll-snap-align: start;
  }

  .archive-page .project-row:last-child {
    border: 0;
  }

  .archive-page .project-image {
    width: 100%;
    height: min(58vh, 620px);
    min-height: 340px;
    overflow: hidden;
    background: #111;
  }

  .archive-page .project-image img {
    transform: scale(1);
    transition: transform 760ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform;
  }

  .archive-page .project-row:hover .project-image img,
  .archive-page .project-row:focus-within .project-image img {
    transform: scale(1.045);
  }

  .archive-page .project-copy {
    position: absolute;
    right: 0;
    bottom: calc(100% + clamp(8px, 1vw, 14px));
    left: 0;
    display: block;
    height: clamp(2.4rem, 5vw, 5.4rem);
    min-height: 0;
    overflow: hidden;
    padding: 0;
    pointer-events: none;
  }

  .archive-page .project-copy h2 {
    position: absolute;
    bottom: 0;
    left: 0;
    max-width: 100%;
    opacity: 0;
    color: rgba(244, 242, 238, 0.96);
    font-size: clamp(2rem, 3vw, 4.35rem);
    line-height: 0.92;
    text-shadow: 0 16px 34px rgba(0, 0, 0, 0.56);
    transform: translateY(105%);
    transition:
      opacity 280ms ease,
      transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  .archive-page .project-row:hover .project-copy h2,
  .archive-page .project-row:focus-within .project-copy h2 {
    opacity: 1;
    transform: translateY(0);
  }

  .archive-page .project-label,
  .archive-page .project-description-preview,
  .archive-page .read-more {
    display: none;
  }
}

@media (max-width: 720px) {
  :root {
    --nav-x: 14px;
    --nav-y: 14px;
    --brand-font-size: clamp(0.98rem, 3.4vw, 1.18rem);
    --button-font-size: clamp(0.64rem, 2.15vw, 0.78rem);
    --nav-icon-size: clamp(0.96rem, 3.4vw, 1.18rem);
    --brand-letter-spacing: 0.14em;
    --button-letter-spacing: 0.08em;
  }

  .project-row {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 12px 0 22px;
  }

  .project-image {
    height: 58vw;
  }

  .project-meta {
    justify-content: space-between;
    gap: 20px;
  }

  .home-actions {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .enter-archive {
    justify-self: end;
  }

  .project-copy p,
  .read-more {
    font-size: 1rem;
  }

  .project-attribution {
    margin-left: 0;
  }

  .gallery-nav div {
    gap: 12px;
  }

  .info-content {
    align-items: start;
    padding: 108px 18px 60px;
  }

  .info-grid {
    grid-template-columns: 1fr;
    gap: 34px;
    width: min(100%, 420px);
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.5;
  }

  .photo-viewer {
    align-content: center;
    row-gap: 18px;
    padding: 50px 18px 46px;
  }

  .viewer-frame {
    grid-template-columns: 1fr;
    width: min(100%, 420px);
  }

  .viewer-frame.series-07 {
    grid-template-columns: 1fr;
  }

  .viewer-frame.series-07 .viewer-photo {
    width: 100%;
  }

  .viewer-frame.series-07 .viewer-photo img {
    width: 100%;
    height: auto;
    max-height: min(60svh, 560px);
  }

  .viewer-photo {
    width: 100%;
  }

  .project-nav {
    grid-template-columns: 1fr auto 1fr;
    gap: 12px;
  }

  .project-nav a:nth-child(2) {
    justify-self: center;
  }

  .project-nav-right {
    justify-self: end;
    gap: 12px;
  }

  .project-article {
    width: min(100% - 36px, 1320px);
    padding-bottom: 120px;
  }

  .project-collection {
    width: min(100% - 36px, 1500px);
  }

  .project-gallery--folder-two {
    grid-template-columns: 1fr;
  }

  .project-gallery--folder-two .folder-two-tetraptych {
    grid-column: auto;
    justify-self: center;
    width: 100%;
    max-width: 100%;
  }

  .project-gallery--wrinkles img:first-child {
    grid-column: auto;
    grid-row: auto;
    width: 100%;
    max-width: 100%;
    margin-top: 0;
    margin-left: 0;
  }

  .project-gallery--wrinkles .wrinkles-photo-shift {
    transform: none;
  }


  .project-gallery--wrinkles,
  .project-gallery--wrinkles img:nth-child(2),
  .project-gallery--wrinkles img:nth-child(n + 3) {
    grid-template-columns: 1fr;
    grid-column: auto;
    grid-row: auto;
    justify-self: center;
    width: 100%;
  }

  .project-gallery--wrinkles img:nth-child(4) {
    transform: none;
  }

  .project-gallery--wrinkles img:nth-child(5) {
    transform: none;
  }

  .project-gallery--wrinkles img:nth-child(6) {
    transform: none;
  }

  .project-article h1 {
    font-size: clamp(2.5rem, 13vw, 4.8rem);
  }

  .project-pager {
    position: static;
    padding: 0 18px 22px;
  }
}

@media (max-width: 820px) {
  .project-gallery--still-life,
  .project-gallery--folder,
  .project-gallery--wrinkles,
  .project-gallery--untamed-soul {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(8px, 2vw, 18px);
    row-gap: clamp(12px, 3vw, 24px);
    align-items: start;
    justify-items: stretch;
  }

  .project-gallery--still-life.project-gallery--still-life > img,
  .project-gallery--folder.project-gallery--folder > img,
  .project-gallery--wrinkles.project-gallery--wrinkles > img,
  .project-gallery--untamed-soul.project-gallery--untamed-soul > img {
    grid-column: auto;
    grid-row: auto;
    width: 100%;
    max-width: 100%;
    margin: 0;
    justify-self: stretch;
    transform: none;
  }

  /* Project-002 narrow-screen override: image 3 spans the full row
     instead of sitting alone in column 1 with an empty column 2. */
  .project-gallery--folder.project-gallery--folder > img:nth-child(3) {
    grid-column: 1 / -1;
  }
}

/* Homepage-only mobile tuning. Scoped to .home-page so other pages
   keep their existing mobile layouts untouched. Bumps brand wordmark
   and icons up to comfortable phone sizes and adds breathing room
   from the screen edges. */
@media (max-width: 720px) {
  .home-page {
    --nav-x: 22px;
    --nav-y: 24px;
    --brand-font-size: 1.55rem;
    --nav-icon-size: 1.95rem;
    --brand-letter-spacing: 0.2em;
    --button-letter-spacing: 0.14em;
  }

  .home-page .hero-name {
    font-weight: 400;
  }

  .home-page .home-contact {
    right: 22px;
    bottom: 28px;
  }
}

/* Archive (gallery-page) mobile tuning. Scoped to .gallery-page so
   no other page is affected. Matches the LANCE SIO wordmark size to
   the homepage, hides the desktop INFO/PROJECTS/icons cluster, and
   reveals a single hamburger menu button. The menu panel drops down
   when .is-open is set on the nav. Each photo is capped at ~40svh
   so the pair reads as one composition without awkward scrolling. */
@media (max-width: 720px) {
  .gallery-page {
    --nav-x: 22px;
    --nav-y: 24px;
    --brand-font-size: 1.55rem;
    --brand-letter-spacing: 0.2em;
    --nav-icon-size: 1.95rem;
  }

  /* Bump the nav above the menu panel so the X (and the wordmark)
     stay tappable while the panel is open. */
  .gallery-page .gallery-nav {
    z-index: 5;
    align-items: center;
  }

  .gallery-page .gallery-nav {
    font-weight: 400;
  }

  /* Mirror .hero-name's positioning and pin the wordmark's font
     properties to the same explicit values as the homepage
     (font-size 1.55rem, font-weight 400, letter-spacing 0.2em) so
     the archive wordmark visually matches index.html. Setting
     font-size and letter-spacing directly avoids the
     var(--nav-font-size) → var(--brand-font-size) chain, which
     iOS Safari can drop. */
  .gallery-page .gallery-nav > a {
    position: absolute;
    top: var(--nav-y);
    left: var(--nav-x);
    margin: 0;
    white-space: nowrap;
    font-size: 1.55rem;
    font-weight: 400;
    letter-spacing: 0.2em;
  }

  .gallery-page .gallery-nav > div {
    display: none;
  }

  .gallery-page .menu-toggle {
    display: inline-flex;
    margin-left: auto;
  }

  .gallery-page .photo-viewer {
    padding: 96px 16px 32px;
    row-gap: 12px;
  }

  .gallery-page .photo-viewer[data-viewer-series="series-05"],
  .gallery-page .photo-viewer[data-viewer-series="series-06"] {
    min-height: auto;
    align-content: start;
    justify-items: center;
    padding-top: 112px;
    padding-bottom: 20px;
    row-gap: 8px;
  }

  .gallery-page .viewer-frame.series-05,
  .gallery-page .viewer-frame.series-06 {
    width: min(86vw, 360px);
    justify-content: center;
    justify-self: center;
    margin-inline: auto;
  }

  .gallery-page .viewer-frame.series-05 .viewer-photo,
  .gallery-page .viewer-frame.series-06 .viewer-photo {
    display: flex;
    justify-content: center;
  }

  .gallery-page .viewer-frame.series-05 .viewer-photo img,
  .gallery-page .viewer-frame.series-06 .viewer-photo img {
    width: auto;
    max-width: 100%;
    margin-inline: auto;
  }

  .gallery-page .viewer-photo img {
    max-height: 40svh;
  }

  .gallery-page .viewer-frame.series-03,
  .gallery-page .viewer-frame.series-07 {
    width: min(64vw, 280px);
    gap: 12px;
  }
}

/* Info mobile menu. Uses the same light-page menu primitives as
   archive.html while keeping desktop info navigation untouched. */
@media (max-width: 720px) {
  .info-page {
    --nav-x: 22px;
    --nav-y: 24px;
    --brand-font-size: 1.55rem;
    --brand-letter-spacing: 0.2em;
    --nav-icon-size: 1.95rem;
  }

  .info-page .gallery-nav {
    z-index: 5;
    align-items: center;
    font-weight: 400;
  }

  .info-page .gallery-nav > a {
    position: absolute;
    top: var(--nav-y);
    left: var(--nav-x);
    margin: 0;
    white-space: nowrap;
    font-size: 1.55rem;
    font-weight: 400;
    letter-spacing: 0.2em;
  }

  .info-page .gallery-nav > div {
    display: none;
  }

  .info-page .menu-toggle {
    display: inline-flex;
    margin-left: auto;
  }
}

/* Projects (archive-page) mobile tuning. Mirrors the .gallery-page
   mobile menu system: hides the desktop HOME / INFO / icons cluster,
   pins the wordmark on the left at the same size as the homepage,
   and reveals a single hamburger menu button on the right that opens
   the shared .menu-panel. Scoped to .archive-page so no other page
   is affected; desktop layout (above 720px) is untouched. */
@media (max-width: 720px) {
  .archive-page {
    --nav-x: 22px;
    --nav-y: 24px;
    --brand-font-size: 1.55rem;
    --brand-letter-spacing: 0.2em;
    --nav-icon-size: 1.95rem;
  }

  .archive-page .project-nav {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    grid-template-columns: none;
    gap: 0;
    font-weight: 400;
  }

  .archive-page .project-nav > a:first-child {
    position: absolute;
    top: var(--nav-y);
    left: var(--nav-x);
    margin: 0;
    white-space: nowrap;
    font-size: 1.55rem;
    font-weight: 400;
    letter-spacing: 0.2em;
  }

  .archive-page .project-nav > a:nth-child(2),
  .archive-page .project-nav-right {
    display: none;
  }

  .archive-page .menu-toggle {
    display: inline-flex;
    margin-left: auto;
  }

  /* Offset the project list so the first row clears the now-fixed nav. */
  .archive-page .projects {
    padding-top: 96px;
  }
}

/* Individual project mobile menu. Reuses the approved project/archive
   primitives while keeping every rule scoped to dark project pages. */
@media (max-width: 720px) {
  .project-page {
    --nav-x: 22px;
    --nav-y: 24px;
    --brand-font-size: 1.55rem;
    --brand-letter-spacing: 0.2em;
    --nav-icon-size: 1.95rem;
  }

  .project-page .project-nav {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    grid-template-columns: none;
    gap: 0;
    background: #151515;
    font-weight: 400;
  }

  .project-page .project-nav > a:first-child {
    position: absolute;
    top: var(--nav-y);
    left: var(--nav-x);
    margin: 0;
    white-space: nowrap;
    font-size: 1.55rem;
    font-weight: 400;
    letter-spacing: 0.2em;
  }

  .project-page .project-nav > a:nth-child(2),
  .project-page .project-nav-right {
    display: none;
  }

  .project-page .menu-toggle {
    display: inline-flex;
    margin-left: auto;
  }

  .project-page .project-article {
    padding-top: 96px;
  }

  .project-page .project-nav {
    background: transparent;
  }
}

/* Cinematic Archive → Projects scroll experience.
   The entire Archive photo-viewer panel and the projects horizontal
   gallery share one continuous scroll-linked translateX. A tall
   .cinematic-scroller provides the vertical scroll distance;
   .cinematic-stage pins the visible viewport; .cinematic-track holds
   both panels in a single horizontal strip that JS translates left as
   the user scrolls. The Archive panel also receives a blur filter so
   it visually dissolves as it exits screen-left. On mobile the
   wrappers collapse to display: contents and each panel renders
   normally in vertical flow. */
.cinematic-scroller {
  position: relative;
  width: 100%;
}

.cinematic-stage,
.cinematic-track {
  display: contents;
}

@media (min-width: 721px) {
  .gallery-page--cinematic {
    height: auto;
    overflow-x: hidden;
    overflow-y: visible;
  }

  .gallery-page--cinematic main {
    height: auto;
    overflow: visible;
  }

  /* Transparent nav with mix-blend-mode so the wordmark and menu icon
     auto-invert against both the light archive panel and the dark
     projects panel — no background bar required. */
  .gallery-page--cinematic .gallery-nav {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 6;
    background: transparent;
    color: #ffffff;
    mix-blend-mode: difference;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    pointer-events: none;
  }

  .gallery-page--cinematic .gallery-nav > a,
  .gallery-page--cinematic .gallery-nav .menu-toggle {
    pointer-events: auto;
  }

  /* The wordmark belongs to the Archive layer during phase 1: JS sets
     its translateX to follow the panel, then snaps it back at the
     start of phase 2 and fades it in. */
  .gallery-page--cinematic .gallery-nav > a:first-child {
    will-change: transform, opacity;
  }

  .gallery-page--cinematic .cinematic-scroller {
    width: 100%;
  }

  .gallery-page--cinematic .cinematic-stage {
    position: sticky;
    top: 0;
    display: block;
    height: 100svh;
    overflow: hidden;
  }

  .gallery-page--cinematic .cinematic-track {
    display: flex;
    align-items: stretch;
    width: max-content;
    height: 100%;
    transform: translate3d(0, 0, 0);
    will-change: transform;
  }

  .gallery-page--cinematic .cinematic-panel {
    flex: 0 0 auto;
    height: 100svh;
  }

  /* Archive panel: full-viewport version of the existing photo viewer.
     Overrides default min-height so it lives cleanly inside the
     pinned stage. The blur filter is applied to .viewer-frame (not
     this wrapper) so the panel's edge stays sharp against the
     projects panel during the seam crossing — a filter on this
     element would render past its bounding box and bleed a light
     halo into the next section. */
  .gallery-page--cinematic .cinematic-panel--archive {
    flex: 0 0 100vw;
    width: 100vw;
    min-height: 0;
    background: #f7f7f5;
    color: #3f403d;
    overflow: hidden;
  }

  .gallery-page--cinematic .cinematic-panel--archive .viewer-frame {
    will-change: filter;
    transform: translateZ(0);
  }

  /* Image-inside-frame parallax for the Archive viewer photos. The
     frame clips, the image is slightly oversized so the parallax
     translate (driven by JS) never exposes an edge, and translate
     is set as the individual `translate` property so it never
     collides with the hover/scale system used on project covers. */
  .gallery-page--cinematic .cinematic-panel--archive .viewer-photo {
    overflow: hidden;
  }

  .gallery-page--cinematic .cinematic-panel--archive .viewer-photo img {
    transform: none;
    scale: 1.06;
    translate: 0 0;
    will-change: translate;
  }

  /* Projects panel inside the cinematic flow. Phase 2 of the scroll
     experience: a single 100vw / 100svh viewport that masks a tall
     vertical stack. JS translates .projects-index__inner upward by
     the scroll offset past archiveExitDist, so each project section
     scrolls up into the viewport in turn. */
  .gallery-page--cinematic .cinematic-panel--projects {
    position: relative;
    display: block;
    flex: 0 0 100vw;
    width: 100vw;
    height: 100svh;
    margin: 0;
    padding: 0;
    background: #f7f7f5;
    color: #2a2b29;
    overflow: hidden;
  }

  .gallery-page--cinematic .cinematic-panel--projects .projects-index__inner {
    transform: translate3d(0, 0, 0);
    will-change: transform;
  }

  /* Floating title inside the cinematic panel: absolutely covers the
     entire 100svh panel so it is unaffected by projectsStack's Y
     translate. Uses the same 4-column grid as .project-feature so
     the title-inner lands precisely in column 2. */
  .gallery-page--cinematic .projects-index__floating-title {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    height: auto;
    margin-bottom: 0;
    z-index: 3;
  }
}

/* Shared editorial vertical project index. Each .project-feature is a
   viewport-tall section with three images in columns 1, 3, 4 of a
   4-column grid. Column 2 is intentionally left empty — a single
   floating title block occupies it, staying visually fixed while the
   image stack scrolls. */
.projects-index {
  position: relative;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  background: #f7f7f5;
  color: #1a1b19;
}

.projects-index__inner {
  display: block;
}

/* ── Shared column / gap tokens (duplicated in project-feature and the
      floating-title grid so both grids align pixel-perfect) ────── */
:root {
  --pi-col: minmax(0, 1.05fr) minmax(0, 0.9fr) minmax(0, 1.25fr) minmax(0, 0.95fr);
  --pi-gap: clamp(24px, 2.6vw, 56px);
  --pi-pad-x: clamp(28px, 4vw, 70px);
}

/* Floating title — the one persistent title block.
   On standalone projects.html: sticky so it sits at a fixed point in
   the viewport as the image stack scrolls past it.
   On archive.html (cinematic): overridden to position:absolute within
   the 100svh panel (see cinematic block above). */
.projects-index__floating-title {
  position: sticky;
  top: 0;
  height: 100svh;
  /* Negative margin collapses the sticky element's flow contribution
     so the inner stack starts right below the section top, not below
     the full 100svh that the sticky block occupies. */
  margin-bottom: -100svh;
  display: grid;
  grid-template-columns: var(--pi-col);
  column-gap: var(--pi-gap);
  padding: 0 var(--pi-pad-x);
  align-items: center;
  pointer-events: none;
  z-index: 4;
}

.projects-index__title-inner {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 0.6vh, 10px);
  pointer-events: auto;
  /* Fade transition when active project changes */
  transition: opacity 180ms ease;
}

.projects-index__title-inner.is-changing {
  opacity: 0;
}

.projects-index__title-heading {
  margin: 0;
  color: #1a1b19;
  font-size: clamp(1.5rem, 1rem + 1.7vw, 3.05rem);
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.02;
  text-transform: none;
}

.project-feature {
  position: relative;
  display: grid;
  width: 100%;
  box-sizing: border-box;
  border: 0;
  background: transparent;
}

.project-feature__title {
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 0.6vh, 10px);
}

.project-feature__title h2 {
  margin: 0;
  color: #1a1b19;
  font-size: clamp(1.5rem, 1rem + 1.7vw, 3.05rem);
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.02;
  text-transform: none;
}

.project-feature__title h2 a {
  color: inherit;
  text-decoration: none;
}

.project-feature__meta {
  margin: 0;
  max-width: none;
  color: rgba(26, 27, 25, 0.72);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: clamp(0.72rem, 0.62rem + 0.28vw, 0.9rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.4;
}

.project-feature .project-image {
  background: transparent;
  width: 100%;
  height: auto;
  /* --frame-ratio is set per-image by script.js from the loaded image's
     naturalWidth / naturalHeight, so each frame matches its image's
     orientation (landscape vs portrait) instead of being forced into a
     fixed vertical box. The 3/4 fallback keeps layout stable before the
     image loads. */
  aspect-ratio: var(--frame-ratio, 3 / 4);
  overflow: hidden;
}

.project-feature .project-image::after {
  content: none;
}

.project-feature .project-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: none;
  /* 1.20 gives a 10% buffer per side — enough headroom for the
     stronger vertical parallax (up to ~9% of frame height at cap). */
  scale: 1.20;
  translate: 0 0;
  transition: scale 760ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: translate, scale;
}

@media (hover: hover) {
  .project-feature .project-image:hover img,
  .project-feature .project-image:focus-visible img {
    scale: 1.25;
  }
}

/* Desktop layout: four-column grid, images in columns 1 / 3 / 4.
   Column 2 is intentionally empty — the shared floating title block
   (outside the scrolling stack) occupies that slot via its own
   matching grid, giving the title a fixed visual position. */
@media (min-width: 721px) {
  .project-feature {
    grid-template-columns: var(--pi-col);
    grid-template-rows: 1fr;
    column-gap: var(--pi-gap);
    align-items: center;
    height: 100svh;
    padding: clamp(96px, 12vh, 150px) var(--pi-pad-x) clamp(56px, 8vh, 100px);
  }

  /* Inline title is hidden on desktop — floating title takes over. */
  .project-feature .project-feature__title {
    display: none;
  }

  /* Explicit column placement keeps images in cols 1, 3, 4 while
     col 2 stays empty for the floating title to align with. */
  /* Each slot fills its column width; aspect-ratio drives the height
     based on the image's natural orientation. max-height caps very tall
     portrait frames so the page rhythm stays close to the original
     design, while landscape images simply render shorter and keep their
     horizontal composition (no forced vertical cropping). */
  .project-feature .project-feature__cover {
    grid-column: 1;
    align-self: end;
    width: 100%;
    min-height: 0;
    max-height: clamp(280px, 50vh, 540px);
  }

  .project-feature .project-feature__image--two {
    grid-column: 3;
    align-self: center;
    width: 100%;
    min-height: 0;
    max-height: clamp(320px, 68vh, 720px);
  }

  .project-feature .project-feature__image--three {
    grid-column: 4;
    align-self: end;
    width: 100%;
    min-height: 0;
    max-height: clamp(240px, 48vh, 500px);
  }

  /* Untamed Soul: lift the cover so its vertical center sits near the
     title block, rather than anchoring to the row bottom. */
  [data-project="untamed-soul"] .project-feature__cover {
    align-self: center;
  }

  /* Hide floating title on mobile (handled by inline titles per row). */
  .projects-index__floating-title {
    display: grid; /* stays visible on desktop */
  }

  /* Inside the cinematic Projects panel, force each section to one
     viewport width so the inner stack is exactly N viewports tall. */
  .gallery-page--cinematic .cinematic-panel--projects .project-feature {
    width: 100vw;
  }
}

/* Mobile: editorial two-image layout.
   Cover (left, ~58% width, top-anchored) + image-two (right, ~42%,
   bottom-anchored) form a natural vertical offset — no manual margins.
   Title spans the full width beneath the image pair.
   Image-three remains hidden; floating title replaced by inline titles. */
@media (max-width: 720px) {
  .projects-index__floating-title {
    display: none;
  }

  .project-feature {
    grid-template-columns: 7fr 5fr;
    grid-template-rows: auto auto;
    column-gap: 8px;
    row-gap: 0;
    padding: 20px 16px 32px;
  }

  .project-feature .project-feature__cover {
    grid-column: 1;
    grid-row: 1;
    width: 100%;
    height: auto;
    max-height: none;
    align-self: start;
  }

  /* All secondary images hidden by default; --two is re-shown below. */
  .project-feature .project-feature__image {
    display: none;
  }

  /* Image-two: right column, bottom-aligned — its shorter height floats
     down to meet the cover's bottom edge, producing the offset effect. */
  .project-feature .project-feature__image--two {
    display: block;
    grid-column: 2;
    grid-row: 1;
    width: 100%;
    height: auto;
    max-height: none;
    align-self: end;
  }

  .project-feature .project-feature__title {
    display: flex;
    flex-direction: column;
    grid-column: 1 / -1;
    grid-row: 2;
    gap: 4px;
    padding: 10px 2px 8px;
  }

  .project-feature .project-feature__title h2 {
    margin: 0;
    color: #1a1b19;
    font-size: clamp(1.3rem, 5.6vw, 1.65rem);
    font-weight: 500;
    text-transform: none;
  }

  .project-feature .project-feature__title h2 a {
    color: inherit;
    text-decoration: none;
  }
}

/* Standalone projects.html: opt out of the archive-page horizontal
   strip and render the new vertical index in natural document flow.
   Light theme to match the editorial layout. */
.projects-index-page {
  background: #f7f7f5;
  color: #1a1b19;
}

.projects-index-page .archive-nav {
  background: transparent;
  color: #1a1b19;
}

.projects-index-page .archive-nav a {
  color: inherit;
}

.projects-index-page .archive-nav .instagram-icon svg {
  stroke: #1a1b19;
  fill: none;
}

.projects-index-page .menu-toggle {
  color: #1a1b19;
}

@media (min-width: 721px) {
  .projects-index-page {
    height: auto;
    overflow-x: hidden;
    overflow-y: visible;
  }

  .projects-index-page main {
    height: auto;
    overflow-x: visible;
    overflow-y: visible;
  }

  /* Neutralise the .archive-page .projects horizontal flex strip on
     the new vertical index. */
  .projects-index-page .projects-index {
    display: block;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    align-items: stretch;
    gap: 0;
    scroll-snap-type: none;
  }
}

/* Mobile fallback: the cinematic flow is desktop-only. On mobile the
   Archive page keeps its existing photo-viewer experience untouched;
   the cinematic projects panel is hidden because mobile users reach
   projects via the dedicated projects.html page from the menu. */
@media (max-width: 720px) {
  .gallery-page--cinematic .cinematic-panel--projects {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .archive-page.is-project-header-fading .archive-nav,
  .archive-page.is-project-layer-lifting .archive-nav,
  .project-transition-layer {
    pointer-events: auto;
    opacity: 1;
    transform: none;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  .archive-page--cinematic .cinematic-track {
    transform: none !important;
  }

  .archive-page--cinematic .archive-hero img {
    filter: none !important;
  }
}
