/* ─── Fonts ─────────────────────────────────────────────────── */
@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-55Rg.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-56It.ttf') format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-65Md.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-66MdIt.ttf') format('truetype');
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-75Bd.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Neue Haas Grotesk Text Pro';
  src: url('../fonts/NHaasGroteskTXPro-76BdIt.ttf') format('truetype');
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

/* ─── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ─── Base ──────────────────────────────────────────────────── */
:root {
  --black:  #000000;
  --border: #000000;
  --white:  #F7F5F8;
  --f: 'Neue Haas Grotesk Text Pro', 'NeueHaasGroteskTextPro', 'Helvetica Neue', Arial, sans-serif;
  /* Small UI text (labels, header, footer, list meta) — Antonia Variable */
  --f-ui: 'antonia-variable', 'Neue Haas Grotesk Text Pro', 'Helvetica Neue', Arial, sans-serif;
  --fw: 400;
  --pad: 28px;
  --header-h: 84px;
  --placeholder: #e8e8e8;
  /* Project page: left text column width. The divider (image left edge) sits at
     the LEFT EDGE of the cursor ball, which is ~one ball (32px) left of the pill's
     left edge. Pill is 447px wide and centred → its left edge = 50vw − 223.5px,
     so the ball's left edge ≈ 50vw − 256px. Clamped for narrow / ultrawide. */
  --proj-col: clamp(480px, calc(50vw - 256px), 720px);
}

html.dark {
  --black:  #ffffff;
  --border: #ffffff;
  --white:  #000000;
  --placeholder: #1a1a1a;
}

html { font-size: 13px; }

body {
  font-family: var(--f);
  font-weight: var(--fw);
  background: var(--white);
  color: var(--black);
  -webkit-font-smoothing: antialiased;
  transition: background 0.3s ease, color 0.3s ease;
}

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

/* Fullscreen project background on hover (behind everything) */
#bg-preview {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: brightness(0.6); /* darkened so the list text reads over the image */
  opacity: 0;
  transform: scale(1.22); /* headroom for the parallax movement */
  transform-origin: center center;
  transition: opacity 0.3s ease;
  will-change: transform, opacity;
  pointer-events: none;
}

#bg-preview.visible { opacity: 1; }

/* While a project image is shown, force all text/lines white regardless of theme */
body.bg-active {
  --black: #ffffff;
  --border: #ffffff;
}

/* The hovered project's row stays a solid white box with black text,
   standing out against the darkened image. */
body.bg-active .project-row:hover { background: #ffffff; }
body.bg-active .project-row:hover .p-num,
body.bg-active .project-row:hover .p-name,
body.bg-active .project-row:hover .p-cat,
body.bg-active .project-row:hover .p-year { color: #000000; }

/* ─── Header — floating capsule menu (orchard-dark exact specs) ─── */
/* Geometry lifted 1:1 from orchard-dark.framer.website:
     pill 559px wide · border-radius 80px · backdrop blur(40px)
     bar padding 8px 8px 8px 20px · bg rgba(255,255,255,.21) (dark)
     toggle 40px · radius 20px · bg rgba(0,0,0,.15) · 14px icon
     nav pills: 2px rgba(191,191,191,.5) border · padding 9px 16px
   Colours flip for the light theme. */
/* Original frosted palette: 21%-translucent glass, adaptive per theme (light =
   rgba(0,0,0,.21) over the light page, dark = rgba(255,255,255,.21) over black).
   Header text is always white (--pill-fg). */
:root {
  --pill-bg:       rgba(0, 0, 0, 0.21);
  --pill-item:     rgba(0, 0, 0, 0.06);
  --pill-item-h:   rgba(0, 0, 0, 0.12);
  --pill-item-brd: rgba(0, 0, 0, 0.20);
  --pill-plus:     rgba(0, 0, 0, 0.10);
  --pill-plus-h:   rgba(0, 0, 0, 0.16);
  --pill-fg:       #ffffff;
}
html.dark {
  --pill-bg:       rgba(255, 255, 255, 0.21);
  --pill-item:     rgba(255, 255, 255, 0.10);
  --pill-item-h:   rgba(255, 255, 255, 0.18);
  --pill-item-brd: rgba(255, 255, 255, 0.25);
  --pill-plus:     rgba(0, 0, 0, 0.10);
  --pill-plus-h:   rgba(0, 0, 0, 0.18);
  --pill-fg:       #ffffff;
}

/* Header text always white. */
.pill,
.pill .logo,
.pill .pill-nav a,
.pill .pill-copy,
.pill .f-links a { color: var(--pill-fg); }

header {
  position: fixed;
  top: 16px;
  left: 0;
  right: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: 1fr auto 1fr;   /* clock | menu | theme */
  align-items: start;
  gap: 9.6px;
  padding: 0 var(--pad);
  pointer-events: none;                   /* only the pills are interactive */
}
.header-left  { justify-self: start; }
.pill         { justify-self: center; }
.header-right { justify-self: end; }

/* Clock + theme toggle sit bare in the corners (no pill), vertically centred
   against the menu bar. */
.clock-pill,
.theme-pill {
  pointer-events: auto;
  display: flex;
  align-items: center;
  height: 43px;                            /* aligns with the menu bar centre */
}
.clock-pill {
  font-family: var(--f);                   /* Neue Haas Grotesk — matches the logo */
  font-size: 13.6px;                       /* same size as "Marco da Silva" */
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--black);                     /* follows the page theme, readable */
  font-variant-numeric: tabular-nums;      /* stable digit width — no jitter */
}

/* On desktop the reference keeps the stadium BAR and drops a SEPARATE frosted
   panel just below it (it does NOT grow into one blob). So .pill is only a
   transparent column wrapper; the bar and the panel are their own frosted
   boxes with a small gap between them. Measured live: panel 559 wide, bg
   rgba(255,255,255,.17) in dark, radius ~24px, ~6px gap under the bar. */
.pill {
  pointer-events: auto;
  width: 447px;
  max-width: calc(100vw - 2 * var(--pad));
  display: flex;
  flex-direction: column;
  gap: 4.8px;
  color: var(--black);
}

/* The always-visible stadium bar */
.pill-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 13px;
  padding: 6.4px 6.4px 6.4px 16px;
  background: var(--pill-bg);
  border-radius: 64px;
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
}

.logo {
  font-family: var(--f);   /* Neue Haas Grotesk */
  font-size: 13.6px;
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--black);
  white-space: nowrap;
}

/* + / − toggle */
.pill-toggle {
  position: relative;
  flex: 0 0 auto;
  width: 41.6px;
  height: 30.4px;
  border: none;
  border-radius: 16px;
  background: var(--pill-plus);
  cursor: pointer;
  transition: background 0.2s ease;
}
.pill-toggle:hover { background: var(--pill-plus-h); }
.pill-toggle::before,
.pill-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 11.2px;
  height: 1.2px;
  background: var(--pill-fg);
  transform: translate(-50%, -50%);
  transition: transform 0.45s cubic-bezier(0.5, 0.1, 0.1, 1);
}
.pill-toggle::after { transform: translate(-50%, -50%) rotate(90deg); }
.pill.open .pill-toggle::after { transform: translate(-50%, -50%) rotate(0deg); }

/* Separate frosted panel below the bar; expands via the grid-rows 0fr→1fr
   technique. Easing + timing measured live from the reference (getAnimations):
   cubic-bezier(0.12,0.23,0.5,1), ~600ms. */
.pill-panel {
  display: grid;
  grid-template-rows: 0fr;
  background: var(--pill-bg);
  border-radius: 19.2px;
  overflow: hidden;                  /* clip content to the rounded box */
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
  transition: grid-template-rows 0.6s cubic-bezier(0.12, 0.23, 0.5, 1);
}
.pill.open .pill-panel { grid-template-rows: 1fr; }

.pill-panel-inner {
  min-height: 0;
  overflow: hidden;
  padding: 0 14.4px;                  /* NB: vertical padding here would leave a
                                          residual strip when collapsed (0fr), so
                                          top/bottom spacing lives on the children. */
}
.pill-panel-inner > :last-child { margin-bottom: 14.4px; }

.pill-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4.8px;
  margin: 12.8px 0 14.4px;
}
.pill-nav a {
  font-family: var(--f-ui);
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  padding: 7.2px 12.8px;
  border-radius: 100px;               /* stadium pills, like the reference row */
  background: var(--pill-item);
  opacity: 0;                         /* revealed on open (staggered below) */
  transition: opacity 0.55s cubic-bezier(0.12, 0.23, 0.5, 1),
              background 0.2s ease;
}
/* Staggered fade-in — matches the reference cascade (~70ms steps). Hover uses
   background (not opacity) so it stays snappy and never fights the reveal. */
.pill.open .pill-nav a { opacity: 1; }
.pill.open .pill-nav a:nth-child(1) { transition-delay: 0.05s; }
.pill.open .pill-nav a:nth-child(2) { transition-delay: 0.12s; }
.pill.open .pill-nav a:nth-child(3) { transition-delay: 0.19s; }
.pill.open .pill-nav a:nth-child(4) { transition-delay: 0.26s; }
.pill-nav a:hover { background: var(--pill-item-h); }

.pill-social {
  display: flex;
  gap: 16px;
  margin-bottom: 12.8px;
}

.pill-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12.8px;
}
.pill-copy {
  font-family: var(--f-ui);
  font-size: 9.6px;
  font-weight: 300;
  line-height: 1.35;
  color: var(--black);
  opacity: 0.55;
}

/* Generic nav link fallback (used by the base rules elsewhere) */
nav a { transition: opacity 0.15s; }

/* Narrow screens: pill spans the padding box */
@media (max-width: 620px) {
  .pill { width: 100%; }
}

/* ─── Archive page — horizontal magnified strip ─────────────── */
/* A justified, vertically-scrolling gallery (Flickr-style): images keep their
   own aspect ratios, js/main.js scales each row to fill the width, and every
   gutter — between columns AND between rows — is identical. Items are shuffled
   once so the archive reads as dispersed rather than project-by-project.
   Captions reuse the homepage look (.hi-cap / .hi-name / .hi-year). */
.archive-main {
  padding: calc(var(--header-h) + 28px) var(--pad) 96px;
  min-height: 100vh;
}

.archive-grid {
  column-count: 4;
  column-gap: 18px;                 /* uniform medianiz */
}
@media (max-width: 1300px) { .archive-grid { column-count: 4; } }
@media (max-width: 1100px) { .archive-grid { column-count: 3; } }
@media (max-width: 700px)  { .archive-grid { column-count: 2; } }

.arch-item {
  display: block;
  width: 100%;
  margin: 0 0 18px;                 /* same gutter as column-gap */
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}
.arch-item img,
.arch-item video {
  width: 100%;
  height: auto;                     /* natural ratio — each block its own */
  display: block;
  border-radius: 2px;
}
.arch-item .hi-cap { margin-top: 9px; margin-bottom: 2px; }

/* ─── Homepage — horizontal project gallery (Oblica style) ────── */
/* Same horizontal loop + dock magnification as the Archive strip, but the
   items are cover-cropped project cards (fixed 4:5 box) that link to the
   project page, with the title + year captioned underneath. Driven by the
   shared strip engine in main.js. */
.home-main {
  height: 100vh;
  padding: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.home-gallery {
  display: flex;
  align-items: center;
  gap: 1.4vw;
  width: 100%;
  height: 100vh;
  overflow-x: scroll;
  overflow-y: hidden;
  overscroll-behavior: contain;
  scrollbar-width: none;
  cursor: grab;
}
.home-gallery::-webkit-scrollbar { display: none; }
.home-gallery.grabbing { cursor: grabbing; }
.home-gallery.grabbing .home-item { pointer-events: none; }

.home-item {
  flex: 0 0 auto;
  /* Each card keeps its own ratio (--ar), but a per-card size factor (--wmul)
     softens how much taller the 4:5 cards get vs the 5:4 ones — the size delta is
     split ~evenly between width and height instead of all in height.
     JS writes a per-frame transform (depth/rotation) — keep transition off. */
  width: calc(var(--aw, 300px) * var(--wmul, 1));
  display: block;
  color: var(--black);
  transform-origin: 50% 50%;
  will-change: transform;
}
/* Media frame clips the hover zoom (Oblica-style: image scales inside). */
.hi-media {
  display: block;
  overflow: hidden;
  border-radius: 2px;
  height: calc(var(--aw, 300px) * var(--wmul, 1) / var(--ar, 1.25));
}
.hi-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s cubic-bezier(0.12, 0.23, 0.5, 1);
}
.home-item:hover .hi-media img { transform: scale(1.05); }

/* Caption follows the project-page/list logic: name in Neue Haas, then a
   meta line with category (left) + year (right) in the UI face (Antonia). */
.hi-cap {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 11px;
}
.hi-name {
  font-family: var(--f);          /* Neue Haas Grotesk */
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--black);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hi-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.hi-cat,
.hi-year {
  font-family: var(--f-ui);       /* Antonia — matches .p-cat / .p-year */
  font-size: 13px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  white-space: nowrap;
}
.hi-cat { overflow: hidden; text-overflow: ellipsis; }
.hi-year { opacity: 0.55; flex: 0 0 auto; }

/* Pill slider toggle (knob left = light, knob right = dark) */
#theme-toggle {
  position: relative;
  width: 41.6px;
  height: 22.4px;
  flex: none;
  border: none;
  border-radius: 999px;
  padding: 0;
  background: var(--pill-bg);                 /* exactly the header bar's glass */
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
  cursor: pointer;
  transition: background 0.3s ease;
}

#theme-toggle::after {
  content: "";
  position: absolute;
  top: 2.4px;
  left: 2.4px;
  width: 17.6px;
  height: 17.6px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);  /* keeps the knob readable on glass */
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

html.dark #theme-toggle::after { transform: translateX(19.2px); }

/* ─── Main ──────────────────────────────────────────────────── */
main { padding-top: var(--header-h); }

.inner { padding: 0 var(--pad); }

/* ─── Index page ────────────────────────────────────────────── */
/* Hover preview fills the whole background; the grid sits right under the header. */

/* Extra projects revealed by "Show all" */
.project-row.extra { display: none; }
.project-list.show-all .project-row.extra { display: block; }

#show-all {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  background: none;
  border: none;
  padding: 14px 10px;
  cursor: pointer;
  transition: opacity 0.15s;
}

#show-all:hover { opacity: 0.5; }

/* Column headers */
.col-heads {
  display: grid;
  grid-template-columns: 108px 1fr 220px 88px;
  padding: 10px 10px 10px;
  border-bottom: 1px solid var(--black);
}

.col-head {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--black);
}

.col-head.right { text-align: right; }

/* Project rows */
.project-list { list-style: none; }

.project-row {
  border-bottom: 1px solid var(--border);
  transition: background 0.15s;
}

.project-row:last-child { border-bottom: none; }

.project-row:hover { background: var(--black); }

.project-row a {
  display: grid;
  grid-template-columns: 108px 1fr 220px 88px;
  align-items: center;
  padding: 10px 10px;
  cursor: pointer;
}

.p-num {
  font-size: 30px;
  font-weight: var(--fw);
  color: var(--black);
  line-height: 0.9;
  letter-spacing: -0.02em;
  transition: color 0.15s;
  position: relative;
}

/* number text hidden on hover, arrow shown */
.p-num .n-text { display: inline; }
.p-num .n-arr  { display: none; font-style: normal; }
.project-row:hover .p-num .n-text { display: none; }
.project-row:hover .p-num .n-arr  { display: inline; }

.p-name {
  font-size: 30px;
  font-weight: var(--fw);
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--black);
  transition: color 0.15s;
}

.project-row:hover .p-num,
.project-row:hover .p-name { color: var(--white); }

.p-cat {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--black);
  transition: color 0.15s;
}

.p-year {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  text-align: right;
  transition: color 0.15s;
}

.project-row:hover .p-cat,
.project-row:hover .p-year { color: var(--white); }

/* ─── Project page ──────────────────────────────────────────── */

/* Project header bar — logo | title (center) | category | year */

/* Main two-column layout — full height; images bleed under header & footer */
.proj-main {
  display: grid;
  grid-template-columns: var(--proj-col) 1fr;
  height: 100vh;
  overflow: hidden;
}

.proj-left {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100vh;
  padding-top: calc(var(--header-h) + 16px);
  padding-bottom: 40px;   /* small bottom gap so the content block sits lower */
  /* Above the entrance overlay so the title/meta/arrows stay sharp during the
     morph; the images (right column) sit behind it. */
  position: relative;
  z-index: 41;
}

/* Top section: intro + meta + body */
.proj-left-top {
  padding: 0 var(--pad);
  flex: 1;
  display: flex;
  flex-direction: column;
}

.proj-title {
  font-size: 22px;
  font-weight: var(--fw);
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.proj-intro { display: none; }

/* Meta grid */
.proj-meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 0 var(--pad);
}

.proj-meta-block {
  padding: 12px 0;
}

.proj-meta-block:nth-child(odd) {
}

.proj-meta-block:nth-child(even) {
  padding-left: 16px;
}

.proj-meta-block[style*="grid-column"] {
  border-right: none;
  padding-left: 0;
}

.proj-meta-label {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
  margin-bottom: 10px;
  display: block;
}

.proj-meta-val {
  font-family: var(--f);
  font-size: 15px;
  font-weight: var(--fw);
  line-height: 1.5;
  letter-spacing: 0;
}

/* Body text */
.proj-body {
  font-size: 22px;
  font-weight: var(--fw);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-top: auto;
  padding-bottom: 28px;
}

/* Prev / Next — two outline-circle arrows */
.proj-nav {
  display: flex;
  justify-content: space-between;
  padding: 24px var(--pad) 0;
}

.proj-arrow {
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pill-bg);                 /* same frosted glass as the header */
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
  transition: transform 0.18s ease;
}

.proj-arrow svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--pill-fg);                     /* white, like the header text */
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.proj-arrow:hover { transform: scale(1.06); }

/* Right image column — scrollable, full-bleed under header/footer */
.proj-right {
  overflow-y: scroll;
  height: 100vh;
  scrollbar-width: none;
}
.proj-right::-webkit-scrollbar { display: none; }

/* Clearly-horizontal images → 16:9 full width (cover crop for a uniform bleed). */
.pg-wide {
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

/* Everything else (4:5, 1:1, 9:16…) → a justified row: each cell grows in
   proportion to its image's aspect ratio (--ar = width/height), so every image
   in the row ends up the SAME height with NO crop. */
.pg-row {
  display: flex;
  align-items: flex-start;
}

.pg-cell {
  flex-grow: var(--ar, 1);
  flex-basis: 0;
  min-width: 0;
}

/* Spacer that keeps a lone trailing image from stretching to full width. */
.pg-empty { flex-grow: 1; background: transparent; }

.pg-wide img,
.pg-wide video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.pg-cell img,
.pg-cell video {
  width: 100%;
  height: auto;     /* natural aspect — no crop */
  display: block;
}

/* ─── About page ────────────────────────────────────────────── */
.about-main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: 100vh;
  /* Override the base main padding so the photo column bleeds to the very top
     under the header; the text column gets its own top padding below. */
  padding-top: 0;
}

.about-text {
  display: flex;
  flex-direction: column;
  padding: calc(var(--header-h) + 24px) var(--pad) 40px;  /* bottom 40px = project pages */
}

/* The info block (Clients / Collaborators / Public Speaking / Inquires) drops to
   the bottom of the column, mirroring the project-page layout. */
.about-info {
  margin-top: auto;                 /* push to the bottom */
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--pad);
  row-gap: 80px;
}

/* Photo bleeds top→bottom under the transparent header/footer */
.about-photo {
  width: 100%;
  height: 100vh;
  background: var(--placeholder);
  overflow: hidden;
}

.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  filter: grayscale(100%);
  display: block;
}

.about-cell {
  max-width: 360px;
}

.about-bio {
  font-size: 30px;
  font-weight: var(--fw);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--black);
}

.about-bio + .about-bio {
  margin-top: 1.2em;
}

/* Section titles match the homepage Category/Year label style + spacing */
.about-head {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--black);
  margin-bottom: 10px;
}

/* Bio spans both columns at the top */
.about-bio-cell { grid-column: 1 / -1; max-width: none; }
.about-bio-cell .about-bio { max-width: 760px; }

.about-list {
  list-style: none;
  font-size: 22px;
  font-weight: var(--fw);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--black);
}

.about-list a {
  color: inherit;
}

/* General text rule: no underline by default (the .u marker no longer draws
   one). Underline appears only on hover, and only on real hyperlinks. */
.u { text-decoration: none; }

a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Navigation chrome keeps its own hover (opacity / row invert) — never underlined. */
.logo:hover,
header nav a:hover,
.f-links a:hover,
.project-row a:hover,
.proj-arrow:hover,
.home-item:hover {
  text-decoration: none;
}
/* Homepage card: on hover underline only the project name, not the meta line. */
.home-item:hover .hi-name { text-decoration: underline; text-underline-offset: 3px; }

/* ─── Footer ────────────────────────────────────────────────── */
footer {
  border-top: none;
  padding: 20px var(--pad);
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* Above the transition overlay (z 1) so it never flashes during the morph */
  position: relative;
  z-index: 10;
}

.f-links { display: flex; gap: 24px; }

.f-links a {
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--black);
  transition: opacity 0.15s;
}

.f-links a:hover { opacity: 0.4; }

/* ─── Contact page (overlay) ─────────────────────────────────── */
/* Full-screen overlay built like a real site page: it reuses the site header
   (logo + nav) and footer (links), with the about-page typography. */
.contact-overlay {
  position: fixed;
  inset: 0;
  background: var(--white);
  z-index: 99990;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.contact-overlay.open {
  opacity: 1;
  pointer-events: all;
}

/* Body: two columns, bottom-aligned for the same editorial feel as the project
   pages. Top padding clears the fixed header. */
.contact-main {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  column-gap: var(--pad);
  padding: calc(var(--header-h) + 48px) var(--pad) 24px;
}

.contact-intro {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

/* Same look as the homepage project titles (30px / Neue Haas / -0.02em), but a
   comfortable line-height since these wrap over several lines. */
.contact-lead {
  font-size: 30px;
  font-weight: var(--fw);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--black);
}

.contact-note {
  font-family: var(--f);
  font-size: 30px;
  font-weight: var(--fw);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--black);
  margin-top: 28px;
  max-width: 460px;
}

/* Form — minimal underline fields, labels in the small UI font. */
.contact-form {
  display: flex;
  flex-direction: column;
}

.form-field { border-bottom: 1px solid var(--border); }

.form-field label {
  display: block;
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  padding-top: 18px;
  margin-bottom: 6px;
}

/* First field's label sits flush at the top, level with the "Good catch" lead. */
.contact-form .form-field:first-child label { padding-top: 0; }

.form-field input,
.form-field textarea {
  width: 100%;
  background: none;
  border: none;
  outline: none;
  font-family: var(--f);
  font-size: 18px;
  font-weight: var(--fw);
  color: var(--black);
  padding-bottom: 14px;
  resize: none;
}

.form-field textarea { min-height: 96px; }

.form-submit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-top: 24px;
  padding: 16px 0;
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  font-family: var(--f-ui);
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--black);
  cursor: pointer;
  transition: padding 0.18s ease, opacity 0.15s;
}
.form-submit:hover { padding-left: 8px; padding-right: 8px; opacity: 0.6; }

/* Stack on small screens. */
@media (max-width: 760px) {
  .contact-main {
    grid-template-columns: 1fr;
    align-items: start;
    row-gap: 40px;
    overflow-y: auto;
  }
  .contact-intro { height: auto; }
  .contact-lead { font-size: 32px; }
}


/* ─── Bouncing sphere (DVD-style) ────────────────────────────── */
/* Fixed-size frame; its translate(-50%,-50%) offset is constant so an image
   swap can't shift the position. JS moves left/top (bounce) and spins the inner
   image around its own centre. Click opens the contact modal. */
#dvd-dog {
  position: fixed;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9998;
  cursor: pointer;               /* clickable — opens Instagram (about page only) */
  transform: translate(-50%, -50%) scale(0.85);
  transform-origin: center center;
  transition: opacity 0.25s ease;
}

.dvd-img {
  width: 100%;
  height: 100%;
  display: block;
}

/* Soft inner shadow hugging the sphere's round edge (circular overlay so it
   follows the shape, not the square box). */
#dvd-dog::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset 0 0 8px 1px rgba(0, 0, 0, 0.3);
  pointer-events: none;
}

/* ─── Page transition: home → project ───────────────────────── */

/* Exit (homepage): header and footer stay; the grid sinks toward the
   footer, fading out in the lower zone — swallowed rather than thrown.
   Tiny per-row delay set in JS keeps it moving as one body. */
body.page-exit .col-heads,
body.page-exit .project-row,
body.page-exit #show-all {
  animation: fallFade 0.85s cubic-bezier(0.33, 0, 0.2, 1) both;
}

/* Clip the falling rows at main's bottom edge — they vanish exactly at the
   footer line, never over or behind it. pointer-events off so rows sweeping
   under the cursor can't fire hover swaps mid-transition. */
body.page-exit main {
  clip-path: inset(0);
  pointer-events: none;
}

/* The clicked row keeps its white box while falling — :hover dies the moment
   pointer-events go off, so the .row-active class carries the style. */
body.page-exit .project-row.row-active { background: #ffffff; }
body.page-exit .project-row.row-active .p-num,
body.page-exit .project-row.row-active .p-name,
body.page-exit .project-row.row-active .p-cat,
body.page-exit .project-row.row-active .p-year { color: #000000; }
body.page-exit .row-active .p-num .n-text { display: none; }
body.page-exit .row-active .p-num .n-arr  { display: inline; }

@keyframes fallFade {
  0%   { transform: translateY(0);    opacity: 1; }
  55%  { opacity: 1; }
  100% { transform: translateY(26vh); opacity: 0; }
}

/* Morphing layer: all structural styles + the transform-only FLIP animation
   are applied INLINE by js/transition.js (bulletproof against stylesheet
   load timing). This block is only a static fallback for the cover state. */
#transition-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--white);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  transform-origin: 0 0;
  z-index: 1;
  pointer-events: none;
}

/* Entrance (project page): info arrives late and hierarchically —
   title → synopsis → meta → prev/next */
body.page-enter .proj-title,
body.page-enter .proj-body,
body.page-enter .proj-meta-grid,
body.page-enter .proj-nav {
  animation: riseIn 1s cubic-bezier(0.16, 1, 0.3, 1) both;
}

body.page-enter .proj-title     { animation-delay: 0.75s; }
body.page-enter .proj-body      { animation-delay: 0.92s; }
body.page-enter .proj-meta-grid { animation-delay: 1.1s; }
body.page-enter .proj-nav       { animation-delay: 1.28s; }

@keyframes riseIn {
  from { transform: translateY(56px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

/* ─── Custom cursor ─────────────────────────────────────────── */
/* Only hide the native cursor once js/main.js confirms a precise pointer AND
   the animation lib loaded (it adds .custom-cursor). A CDN/JS failure then can
   never leave the user with no cursor, and touch devices keep their default. */
html.custom-cursor,
html.custom-cursor * { cursor: none !important; }

.cursor { pointer-events: none; display: none; }
html.custom-cursor .cursor { display: block; }

.cursor__circle {
  position: fixed;
  top: 0;
  left: 0;
  mix-blend-mode: difference;
  z-index: 999999;
}

.cursor__circle circle { fill: white; }

/* ─── Reduced motion ────────────────────────────────────────── */
/* Respect the OS "reduce motion" setting: neutralise every animation/transition
   (the morph, parallax and falling-grid are also skipped in JS). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── Fade in ───────────────────────────────────────────────── */
main, .proj-main, .about-main { animation: fade 0.3s ease both; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ─── Responsive ────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* Let the project & about pages scroll instead of locking to a 100vh grid.
     !important beats the per-page inline `html,body{overflow:hidden}`. */
  html, body { height: auto !important; min-height: 100vh; overflow-x: hidden; overflow-y: visible !important; }

  header { gap: 8px; }
  .clock-pill { font-size: 12px; }

  .p-name, .p-num { font-size: 26px; }
  .col-heads,
  .project-row a { grid-template-columns: 80px 1fr 160px 70px; }

  /* Project pages: stack the text column above the images; whole page scrolls. */
  .proj-main { grid-template-columns: 1fr; height: auto; overflow: visible; }
  .proj-left {
    height: auto;
    overflow: visible;
    padding-top: calc(var(--header-h) + 20px);   /* clear the fixed header */
    padding-bottom: 28px;
  }
  .proj-right { height: auto; overflow: visible; }

  /* About: stack text over photo, clear the fixed header. */
  .about-main { grid-template-columns: 1fr; height: auto; }
  .about-text { padding: calc(var(--header-h) + 20px) var(--pad) 40px; }
  .about-info { margin-top: 40px; row-gap: 40px; }   /* normal flow (page scrolls) */
  .about-photo {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 5;
  }
}

@media (max-width: 640px) {
  .col-heads,
  .project-row a { grid-template-columns: 60px 1fr 70px; }
  .col-head.right, .p-year { display: none; }
  .p-name, .p-num { font-size: 26px; }
  .proj-title { font-size: 32px; }
  .img-grid.cols-2 { grid-template-columns: 1fr; }
  .about-info { grid-template-columns: 1fr; row-gap: 32px; }
  .about-cell:empty { display: none; }
  footer { flex-direction: column; gap: 12px; }
}

/* ─── Phone header: keep the three pieces from crowding ─────────── */
@media (max-width: 600px) {
  header { padding: 0 16px; gap: 8px; }
}
@media (max-width: 460px) {
  /* On small phones drop the clock so the menu pill has room. */
  .clock-pill { display: none; }
}
