@font-face {
  font-family: "Bebas Neue";
  src: url(bebas-neue.woff2) format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url(space-grotesk.woff2) format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
/* Licensed file, served unmodified. Only downloaded on pages that use it. */
@font-face {
  font-family: Being;
  src: url(Being-VF.ttf) format("truetype");
  font-weight: 100 900;
  font-display: swap;
}

:root {
  --pad: clamp(16px, 3.33vw, 64px); /* logo, gallery and Instagram share this edge */
  --gap: 2px;
  --yellow: #f0c330; /* highlight; through the header's difference blend it reads blue on white */
  --ink: #05070c;
  --paper: #f7f7f2;
  --text: "Space Grotesk", system-ui, sans-serif;
  --bar-h: calc(3.5rem + clamp(44px, 3.4vw, 66px) * 1.11); /* header height: padding + logo */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  padding: 0 var(--pad) var(--pad);
  font: 400 clamp(1rem, .9rem + .3vw, 1.25rem) / 1.5 var(--text);
  color: #000;
  background: #fff;
  -webkit-text-size-adjust: 100%;
}
.dark { color: var(--paper); background: var(--ink); }

html { overflow-x: clip; } /* hides photos waiting off-screen to slide in, without cropping anything inside the page */
:is(p, li, h1, h2, h3) { text-wrap: pretty; } /* no lonely last words */
a { color: inherit; text-decoration: none; }
img { display: block; width: 100%; height: auto; }

/* Page transitions (cross-document View Transitions — Chrome, Edge, Safari 18.2+; others just change page).
   Forward: old page slides a little left and fades, new one slides in from the right. Back: reversed. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: page-out .26s cubic-bezier(.4, 0, 1, 1) both; }
  ::view-transition-new(root) { animation: page-in .32s cubic-bezier(0, 0, .2, 1) both; }
  html:active-view-transition-type(back)::view-transition-old(root) { animation-name: page-out-back; }
  html:active-view-transition-type(back)::view-transition-new(root) { animation-name: page-in-back; }
  /* the header stays put (only the page slides under it), still inverting against what's behind */
  .show { view-transition-name: header; }
  ::view-transition-group(header) { animation: none; mix-blend-mode: difference; }
  ::view-transition-old(header) { display: none; }
  ::view-transition-new(header) { animation: none; }
}
@keyframes page-out { to { opacity: 0; translate: -6% 0; } }
@keyframes page-in { from { opacity: 0; translate: 6% 0; } }
@keyframes page-out-back { to { opacity: 0; translate: 6% 0; } }
@keyframes page-in-back { from { opacity: 0; translate: -6% 0; } }

/* Header — two identical layers:
   .show  sticky, white + mix-blend-mode: difference → inverts against whatever scrolls under it
   .hit   invisible copy on top that takes the clicks/hover and holds the dropdowns,
          kept outside the blend so the menus stay solid black */
site-header { display: contents; }
.bar {
  display: grid;
  grid-template: "logo nav ig" / 1fr auto 1fr;
  align-items: center;
  padding-block: 1.75rem;
  font: clamp(1.125rem, 0.85rem + 0.8vw, 1.75rem) / 1.1 "Bebas Neue", Impact, sans-serif;
  text-transform: uppercase;
}
.show {
  position: sticky;
  top: 0;
  z-index: 10;
  margin-bottom: clamp(2rem, 5.5vw, 6.75rem);
  color: #fff;
  mix-blend-mode: difference;
  pointer-events: none;
}
.hit {
  position: fixed;
  top: 0;
  inset-inline: var(--pad);
  z-index: 9; /* under .show (which lets clicks through), so hover ovals sit behind the visible text */
  color: transparent;
  pointer-events: none;
}
.hit :is(a, ul) , .hit .drop > .drop-label, .hit .burger { pointer-events: auto; } /* beats the reset below */

/* Logo: the SVG used as a mask, painted in the text colour — so it follows the header (blend, menu, invisible twin) */
.logo {
  grid-area: logo;
  width: clamp(44px, 3.4vw, 66px);
  aspect-ratio: 343 / 381;
  background: currentColor;
  mask: url(logo.svg) center / contain no-repeat;
}
.social { grid-area: ig; justify-self: end; display: flex; align-items: center; gap: clamp(1rem, 1.6vw, 1.75rem); } /* email + Instagram; Instagram stays on the margin */
.ig svg:not(.oval) { display: block; width: 1.5rem; }

/* Hover: a hand-drawn yellow oval (ends overshoot instead of meeting), stroked on from start to end.
   The <svg class="oval"> is added by site.js; plain :hover, so it works in every browser. */
.hit nav > *, .hit .ig, .titles a { position: relative; isolation: isolate; }
.oval {
  position: absolute;
  z-index: -1; /* behind the text */
  left: -.55em;
  top: -.4em;
  width: calc(100% + 1.1em);
  height: calc(100% + .8em);
  overflow: visible;
  pointer-events: none;
  rotate: -2deg;
  fill: none;
  stroke: var(--yellow);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  transition: opacity .15s, stroke-dashoffset 0s .15s;
}
.titles .oval { left: -.3em; top: -.18em; width: calc(100% + .6em); height: calc(100% + .36em); stroke-width: 2.5; }
:is(.hit nav > *, .hit .ig, .titles a):is(:hover, :focus-within) .oval {
  opacity: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset .3s cubic-bezier(.3, .7, .3, 1);
}
/* Current section: the same circle, kept on (draws itself in once when the page loads) */
.hit nav > .is-current .oval { opacity: 1; stroke-dashoffset: 0; animation: draw .6s .2s cubic-bezier(.45, 0, .2, 1) backwards; }

.bar nav {
  grid-area: nav;
  display: flex;
  gap: clamp(1rem, 2.75vw, 3.25rem);
  -webkit-text-stroke: .025em; /* Bebas has one weight; a hairline stroke makes it a touch bolder */
}

/* Dropdowns open on hover (mouse) or focus (tap / keyboard) — no JS */
.drop { position: relative; }
.drop > .drop-label {
  all: unset;
  display: flex;
  align-items: center;
  gap: .35em;
  cursor: pointer;
}
.drop > .drop-label:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }

/* chevron, reused by the lightbox arrows */
.drop > .drop-label::after, .lightbox button:not(.close)::after {
  content: "";
  width: .35em;
  height: .35em;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  rotate: 45deg;
  translate: 0 -.1em;
  transition: rotate .2s;
}
/* flip the visible chevron when its invisible twin is open */
site-header:has(.hit .drop:nth-of-type(1):is(:hover, :focus-within)) .show .drop:nth-of-type(1) > .drop-label::after,
site-header:has(.hit .drop:nth-of-type(2):is(:hover, :focus-within)) .show .drop:nth-of-type(2) > .drop-label::after {
  rotate: -135deg;
  translate: 0 .1em;
}

.drop ul {
  display: none;
  position: absolute;
  top: 100%;
  left: -.75em;
  min-width: 10em;
  padding: .6em .75em;
  list-style: none;
  white-space: nowrap;
  color: #fff;
  background: #000;
  -webkit-text-stroke: .025em #fff;
}
.drop:is(:hover, :focus-within) ul { display: block; }
.drop ul a:hover { opacity: .6; }
/* Current page in a submenu: an arrow on the left edge, yellow on the black dropdown (black on the yellow mobile menu) */
:is(.drop, .menu) ul [aria-current] { display: inline-flex; align-items: center; gap: .3em; } /* arrow sits on the left edge */
:is(.drop, .menu) ul [aria-current]::before {
  content: "";
  width: .75em;
  height: .75em;
  flex: none;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.drop ul [aria-current] { color: var(--yellow); -webkit-text-stroke-color: currentColor; } /* the bolding stroke follows the yellow, no white edge */

/* Burger → X: the three lines slide into one, then turn into an X (and back in reverse) */
.burger { display: none; grid-area: ig; justify-self: end; position: relative; width: 2.5rem; height: 1.6rem; padding: 0; border: 0; color: inherit; background: none; cursor: pointer; }
/* Menu open: drop the blend so logo and X sit plain black on the yellow */
.menu-open .show { mix-blend-mode: normal; color: #000; }
.burger i, .burger::before, .burger::after { content: ""; position: absolute; left: 0; right: 0; height: 3px; background: currentColor; }
.burger::before { top: 0; }
.burger::after { bottom: 0; }
.burger i { top: calc(50% - 1.5px); transition: opacity 0s .2s; }
.burger::before, .burger::after { transition: translate .2s .2s, rotate .2s; }
.menu-open .burger::before, .menu-open .burger::after { transition: translate .2s, rotate .2s .2s; }
.menu-open .burger::before { translate: 0 calc(.8rem - 1.5px); rotate: 45deg; }
.menu-open .burger::after { translate: 0 calc(-.8rem + 1.5px); rotate: -45deg; }
.menu-open .burger i { opacity: 0; }

/* Mobile menu panel */
.menu {
  position: fixed;
  inset: 0;
  z-index: 8; /* under both bar layers, so the burger stays visible and clickable */
  display: none;
  flex-direction: column;
  align-items: center;
  padding: 7rem var(--pad) 2.5rem;
  overflow-y: auto;
  font: 13vw / 1.05 "Bebas Neue", Impact, sans-serif;
  text-transform: uppercase;
  color: #000;
  background: var(--yellow);
  visibility: hidden;
  opacity: 0;
  transition: opacity .3s, visibility .3s;
}
.menu-open .menu { visibility: visible; opacity: 1; }
.menu-open body { overflow: hidden; }
.menu nav { display: flex; flex-direction: column; align-items: flex-start; margin-block: auto; } /* block centred, lines left-aligned */
.menu summary { display: flex; align-items: center; gap: .25em; padding-right: .6em; list-style: none; cursor: pointer; } /* the space after the word (chevron) expands */
.menu summary::-webkit-details-marker { display: none; }
.menu summary::after { content: ""; width: .3em; height: .3em; border: solid; border-width: 0 1.5px 1.5px 0; rotate: -45deg; transition: rotate .2s; }
.menu [open] summary::after { rotate: 45deg; }
.menu ul { padding-bottom: .4em; list-style: none; font-size: .55em; line-height: 1.2; }
.menu-social { display: flex; gap: 2rem; margin-top: 2rem; }
.menu-ig svg { display: block; width: 2.25rem; }

@media (max-width: 640px) {
  .bar { grid-template: "logo ig" / 1fr auto; padding-top: 1rem; }
  .bar :is(nav, .social) { display: none; }
  .burger { display: block; }
  .menu { display: flex; }
  .menu[hidden] { display: none; } /* fully removed once closed, so Safari stops tinting its bars yellow */
  :root { --bar-h: calc(2.75rem + 49px); }
}

/* Gallery — CSS columns without JS; site.js swaps in left-to-right masonry columns */
.gallery { columns: 3; gap: var(--gap); }
.gallery:has(> div) { display: flex; align-items: flex-start; }
.gallery > div { flex: 1; min-width: 0; }
.gallery a { display: block; margin-bottom: var(--gap); background: #f2f2f2; transition: opacity .8s, translate .8s; }
.gallery a.hide { opacity: 0; translate: 0 2rem; } /* below the fold until loaded + on screen (site.js) */
@media (max-width: 640px) { .gallery { columns: 2; } }
@media (prefers-reduced-motion: reduce) { .gallery a { transition: none; } }

/* Photo page cover — full-bleed photo at 50% over ink, full-strength grain, big title + subtitle.
   Starts at the very top, behind the menu. */
body:has(.cover) .show { margin-bottom: 0; }
.cover {
  display: grid;
  place-content: center;
  justify-items: center;
  height: 60svh; /* 30% shorter than before */
  min-height: 20rem;
  margin: calc(-1 * var(--bar-h)) calc(-1 * var(--pad)) clamp(2.5rem, 6vw, 6rem);
  padding: var(--bar-h) var(--pad) 0;
  text-align: center;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
}
.cover img { position: absolute; inset: 0; height: 100%; object-fit: cover; opacity: .5; }
.cover.grain::after { opacity: 1; }
.cover :is(h1, p) { position: relative; z-index: 3; } /* above photo and grain */
.cover h1 {
  max-width: 100%;
  font: 900 clamp(2.75rem, 1rem + 9vw, 11rem) / .85 Being, Impact, sans-serif; /* sized so the longest word (BARNAPOLIS) fits a phone */
  color: var(--yellow);
  text-wrap: balance;
}
.cover p { max-width: 30em; margin-top: 1em; font: clamp(1.5rem, 1.1rem + 1.4vw, 2.5rem) / 1.1 "Bebas Neue", Impact, sans-serif; text-wrap: balance; }

/* Diary index — 16:9 covers in 4 columns; hover darkens and shows the title (always shown on touch) */
.diary { --cols: 4; display: grid; grid-template-columns: repeat(var(--cols), 1fr); gap: 3px; } /* --cols: set by the Columns menu */
.diary a { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #111; }
.diary img { height: 100%; object-fit: cover; transition: scale .6s cubic-bezier(.2, .8, .2, 1); }
.diary a::after { content: ""; position: absolute; inset: 0; background: rgb(0 0 0 / .55); opacity: 0; transition: opacity .25s; }
.diary span {
  position: absolute;
  z-index: 1;
  inset: clamp(.75rem, 1.6vw, 1.75rem) auto auto clamp(.75rem, 1.6vw, 1.75rem);
  max-width: 7em;
  font: 900 clamp(1.25rem, 2.2vw, 2.75rem) / .85 Being, Impact, sans-serif;
  text-transform: uppercase;
  color: var(--yellow);
  opacity: 0;
  translate: 0 .3em;
  transition: opacity .25s, translate .3s cubic-bezier(.2, .8, .2, 1);
}
.diary a:is(:hover, :focus-visible)::after, .diary a:is(:hover, :focus-visible) span { opacity: 1; translate: 0 0; }
.diary a:hover img { scale: 1.04; }
@media (hover: none) { .diary a::after, .diary span { opacity: 1; translate: 0 0; } .diary a::after { background: linear-gradient(rgb(0 0 0 / .6), transparent 70%); } }
@media (max-width: 1024px) { .diary { --cols: 2; } }
@media (max-width: 640px) { .diary { --cols: 1; } }

/* Gallery toolbar — view switch left, shuffle right, 16px above the first photo */
.tools { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin-bottom: 16px; }
.tools > .view { justify-self: start; }
.tools > .shuffle { justify-self: end; }
.tools button {
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem;
  font: 1.125rem / 1 "Bebas Neue", Impact, sans-serif;
  text-transform: uppercase;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  transition: opacity .2s, color .2s;
}
.tools svg { width: 1.25rem; height: 1.25rem; }
.tools button { white-space: nowrap; }
@media (max-width: 640px) { .tools .wide { display: none; } } /* "Grid" / "Polaroid" on phones */

/* View switch: one button showing the view you'll go to; the two icons swap with a quarter turn + fade */
.view .icons { display: grid; }
.view svg { grid-area: 1 / 1; transition: opacity .3s, rotate .45s cubic-bezier(.2, .8, .2, 1), scale .45s cubic-bezier(.2, .8, .2, 1); }
/* shows the view you're in */
.view .to-pile, .is-pile .view .to-grid { opacity: 0; rotate: -90deg; scale: .6; }
.is-pile .view .to-pile { opacity: 1; rotate: 0deg; scale: 1; }
.view .icons { transition: scale .25s cubic-bezier(.2, .8, .2, 1); }
.view:hover .icons { scale: 1.1; }

/* Shuffle — hover: the two arrowheads nudge forward. Click: the icon flips on its horizontal axis, so the arrows swap top and bottom */
.shuffle path:is(:nth-child(2), :nth-child(5)) { transform-box: fill-box; transition: translate .3s cubic-bezier(.2, .8, .2, 1); }
.shuffle:hover path:is(:nth-child(2), :nth-child(5)) { translate: 2px 0; }
.shuffle.draw svg { animation: shuffle-flip .5s cubic-bezier(.3, 1.3, .5, 1); }
@keyframes shuffle-flip { from { transform: perspective(60px) rotateX(0); } to { transform: perspective(60px) rotateX(360deg); } }
@keyframes draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .tools .shuffle svg { animation: none; } }
.tools button:focus-visible { outline: 2px solid; outline-offset: 2px; }

/* Polaroid pile — paper-framed prints, tilted and scattered; drag them around */
.gallery.pile, .diary.pile {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0;
  padding: 1.5rem 0 4rem;
}
.pile > a {
  position: relative;
  width: clamp(150px, 19vw, 300px);
  aspect-ratio: auto;
  margin: -.75rem -.4rem;
  padding: .55rem .55rem 2.2rem;
  overflow: visible;
  background: #fbfaf6;
  box-shadow: 0 .4rem 1.4rem rgb(0 0 0 / .2);
  rotate: var(--r, 0deg);
  translate: var(--x, 0) var(--y, 0);
  cursor: grab;
  user-select: none;
  transition: rotate .5s cubic-bezier(.2, .8, .2, 1.3), translate .5s cubic-bezier(.2, .8, .2, 1), scale .2s, box-shadow .2s, opacity .8s;
}
.pile > a:hover { scale: 1.04; rotate: calc(var(--r, 0deg) * .4); }
.pile > a.lift { scale: 1.08; rotate: 0deg; cursor: grabbing; box-shadow: 0 1.5rem 3rem rgb(0 0 0 / .3); transition: scale .2s, rotate .2s, box-shadow .2s; } /* follows the pointer */
.diary.pile > a { width: clamp(200px, 24vw, 380px); }
.diary.pile img { aspect-ratio: 16 / 9; height: auto; }
.diary.pile a::after { inset: 0; } /* hover overlay covers the whole print, frame included */
.diary.pile img { clip-path: inset(0); transition: scale .6s cubic-bezier(.2, .8, .2, 1), clip-path .6s cubic-bezier(.2, .8, .2, 1); }
.diary.pile a:hover img { clip-path: inset(1.923%); } /* zooms 4% but crops the grown edge back off, so it never covers the frame: (1 - 1/1.04) / 2 */
@media (pointer: fine) { .pile > a { touch-action: none; } } /* touch screens keep normal scrolling */
@media (max-width: 640px) { .pile > a, .diary.pile > a { width: 46vw; } }

/* Columns dropdown (grid view only) — white menu on light pages, black on dark */
.cols { position: relative; z-index: 5; transition: opacity .25s, translate .45s cubic-bezier(.3, 1.35, .5, 1), visibility 0s; } /* rises in with a soft overshoot */
.is-pile .cols { visibility: hidden; opacity: 0; translate: 0 .75rem; transition: opacity .18s, translate .22s cubic-bezier(.4, 0, 1, 1), visibility 0s .22s; } /* slides down and out */
.cols-btn b { font-weight: inherit; min-width: .6em; text-align: right; }
.cols .caret { width: 1rem; height: 1rem; transition: rotate .25s cubic-bezier(.2, .8, .2, 1); }
.cols.open .caret { rotate: 180deg; }
.cols ul {
  position: absolute;
  top: calc(100% + .4rem);
  left: 50%;
  min-width: 100%;
  padding: .35rem;
  list-style: none;
  color: #000;
  background: #fff;
  box-shadow: 0 .6rem 2rem rgb(0 0 0 / .18);
  translate: -50% -.4rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s, translate .25s cubic-bezier(.2, .8, .2, 1), visibility .2s;
}
.dark .cols ul { color: var(--paper); background: #000; box-shadow: 0 .6rem 2rem rgb(0 0 0 / .5), 0 0 0 1px rgb(255 255 255 / .1); }
.cols.open ul { opacity: 1; visibility: visible; translate: -50% 0; }
.cols ul::before { content: ""; position: absolute; inset: -.8rem 0 100%; } /* invisible bridge over the gap, so hovering down into the menu keeps it open */
.tools .cols li button { width: 100%; justify-content: center; padding: .45rem .9rem; white-space: nowrap; opacity: .45; }
.tools .cols li button:hover, .tools .cols li [aria-checked="true"] { opacity: 1; }
.tools .cols li [aria-checked="true"] { color: inherit; text-decoration: underline .08em; text-underline-offset: .2em; }

/* Previous / next project pager (photo sub-pages) — each half is one big hover target */
.pager { --inset: 1rem; --rule: #d9d9d9; /* flat light grey for the lines and the hover tint (no overlap shading) */ display: grid; grid-template-columns: 1fr 1fr; margin-top: clamp(3rem, 8vw, 7rem); border-top: 1px solid var(--rule); }
.pager a { position: relative; display: flex; align-items: center; padding: clamp(4rem, 8vw, 6.5rem) 0 clamp(2.5rem, 6vw, 5rem); }
.pager .prev { justify-content: flex-start; padding-right: var(--inset); } /* name flush left */
.pager .next { justify-content: flex-end; padding-left: var(--inset); border-left: 1px solid var(--rule); } /* name flush right */
.dark .pager { --rule: #2a2c2f; } /* dark pages: the same 15% step, from the ink background toward the paper colour */
body:has(.pager) { padding-bottom: 0; } /* the pager sits flush with the bottom of the page (desktop and phones) */
/* hover: a faint tint fills the half, out to the screen edge (so the names keep their alignment) */
.pager a { isolation: isolate; }
.pager a:hover { z-index: 1; } /* the hovered half (and its sliding image) sits above the other half's divider line */
.pager a::before { content: ""; position: absolute; z-index: -1; inset: -1px 0 0; /* starts level with the top of the 1px line */ background: var(--rule); opacity: 0; transition: opacity .35s; }
.pager .prev::before { left: calc(-1 * var(--pad)); }
.pager .next::before { right: calc(-1 * var(--pad)); }
.pager a:hover::before { opacity: 1; }
/* labels pair up at the centre line, the same distance from the top rule and from the divider */
.pager a small { position: absolute; top: var(--inset); }
.pager .prev small { right: var(--inset); }
.pager .next small { left: var(--inset); }
.pager small { font: clamp(1rem, .9rem + .4vw, 1.375rem) / 1 "Bebas Neue", Impact, sans-serif; text-transform: uppercase; letter-spacing: .02em; }
.pager strong { display: flex; align-items: center; gap: .3em; font: 900 clamp(1.75rem, 1rem + 3.5vw, 5rem) / .9 Being, Impact, sans-serif; text-transform: uppercase; }
.pager svg { width: .7em; height: .7em; flex: none; transition: translate .35s cubic-bezier(.2, .8, .2, 1); }
.pager .prev:hover svg { translate: -.2em 0; }
.pager .next:hover svg { translate: .2em 0; }
.pager a:hover strong { color: #0f3ccf; } /* the yellow inverted — the blue the menu shows on white */
.dark .pager a:hover strong { color: var(--yellow); }
/* the cover that slides in and follows the pointer */
.peek {
  position: fixed;
  z-index: 20;
  width: clamp(200px, 22vw, 360px);
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  pointer-events: none;
  translate: var(--from) -50%;
  margin-left: calc(clamp(200px, 22vw, 360px) / -2);
  opacity: 0;
  box-shadow: 0 1.5rem 3rem rgb(0 0 0 / .25);
  transition: translate .55s cubic-bezier(.2, .8, .2, 1), opacity .15s .4s;
}
.prev .peek { --from: -60vw; }
.next .peek { --from: 60vw; }
.pager a:hover .peek { translate: 0 -50%; opacity: 1; transition: translate .55s cubic-bezier(.2, .8, .2, 1), opacity 0s; }
@media (pointer: coarse) { .peek { display: none; } }
@media (max-width: 640px) { .pager strong { font-size: clamp(1.5rem, 7vw, 2.25rem); } }

/* Lightbox */
.lightbox {
  width: 100%;
  height: 100dvh;
  max-width: none;
  max-height: none;
  border: 0;
  outline: 0;
  background: #fff;
}
.lightbox::backdrop { background: none; } /* the dialog itself fades white in/out */
.lightbox { overflow: hidden; touch-action: none; } /* site.js handles swipe / pinch */
.lightbox img { height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; } /* fills the full width or full height, whichever the photo's shape allows */
.lightbox button {
  position: absolute;
  inset-block: 0;
  width: 15%;
  display: grid;
  place-items: center;
  font: inherit;
  font-size: 5rem; /* sizes the arrow chevrons */
  text-transform: inherit;
  color: #fff;
  mix-blend-mode: difference; /* black on the white margins, inverted over the photo */
  background: none;
  border: 0;
  cursor: pointer;
}
/* arrows sit on the page margin, so their tips line up with the X (and the logo / Instagram edge) */
.lightbox :is(.prev, .next) { --edge: calc(var(--pad) + .37rem + .0725em); } /* X lines end .37rem inside their box; the chevron tip pokes .0725em out of its box */
.lightbox .prev { left: 0; justify-items: start; padding-left: var(--edge); }
.lightbox .next { right: 0; justify-items: end; padding-right: var(--edge); }
.lightbox button.prev::after { rotate: 135deg; }
.lightbox button.next::after { rotate: -45deg; }
.lightbox button:not(.close)::after { border-width: 0 3px 3px 0; }
/* Close: the same X as the open mobile menu */
.lightbox .close { inset: 1.75rem var(--pad) auto auto; width: 2.5rem; height: 1.6rem; }
.lightbox .close::before, .lightbox .close::after { content: ""; position: absolute; left: 0; right: 0; top: calc(50% - 1.5px); height: 3px; background: currentColor; rotate: 45deg; }
.lightbox .close::after { rotate: -45deg; }
/* Hover (mouse only): turn blue (yellow through the difference blend) and grow 15% */
.lightbox button, .lightbox button::after { transition: color .2s, scale .2s; }
@media (hover: hover) {
  .lightbox button:hover { color: var(--yellow); }
  .lightbox .close:hover, .lightbox button:not(.close):hover::after { scale: 1.15; }
}
@media (max-width: 640px) {
  .lightbox button:not(.close) { width: 3.25rem; font-size: 3.5rem; }
}
body:has(.lightbox[open]) { overflow: hidden; }

/* Film grain — add class="grain" to any image wrapper.
   One small SVG noise tile, jittered with transform only (GPU, no per-pixel JS) */
.grain { position: relative; overflow: hidden; }
.grain::after {
  content: "";
  position: absolute;
  z-index: 2;
  inset: -100px;
  opacity: .6;
  mix-blend-mode: overlay;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain .5s steps(1) infinite;
}
@keyframes grain {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-60px, 40px); }
  50%  { transform: translate(50px, -70px); }
  75%  { transform: translate(-30px, -50px); }
}
@media (prefers-reduced-motion: reduce) { .grain::after { animation: none; } }

/* Home */
/* Full-screen photo; the whole thing is a link to People */
.hero { position: absolute; top: 0; left: 0; width: 100%; height: 100lvh; background: var(--ink); } /* not fixed: Safari then lets it run under its top and bottom bars */
/* Homepage: exactly one (large) screen tall, and nothing fixed or sticky at the edges —
   Safari colours its top/bottom bars from fixed/sticky elements instead of showing the photo under them */
body.home { height: 100lvh; padding-bottom: 0; }
body.home .show { position: relative; }
body.home .hit { position: absolute; }
html:has(> body.home) { background: var(--ink); } /* explicit root colour, Safari's fallback for its bars */

/* Phones: Safari only draws the page behind its clock and URL bar when that's content the page has scrolled under them.
   So the photo bleeds past both edges and the page starts scrolled down by the top bleed (site.js). */
@media (max-width: 760px) {
  :root { --bleed-top: 62px; --bleed-bottom: 136px; }
  body.home { height: auto; min-height: calc(100dvh + var(--bleed-top)); padding-top: var(--bleed-top); }
  html:has(> body.home) { overscroll-behavior: none; } /* no rubber-band bounce */
  body.home .hit { top: var(--bleed-top); }
  .hero { height: calc(100lvh + var(--bleed-top) + var(--bleed-bottom)); }
  .titles { inset: calc(var(--bleed-top) + 86svh) 0 auto; translate: 0 -100%; }
}
.hero img { position: absolute; inset: 0; height: 100%; object-fit: cover; }
.js .hero:not(.ready) img { opacity: 0; } /* hold until the frames are ready */

/* 25% black over the photos */
.hero::before { content: ""; position: absolute; inset: 0; z-index: 1; background: rgb(0 0 0 / .25); }

.titles {
  position: absolute;
  z-index: 1;
  inset: auto 0 calc(100lvh - 100svh + 14svh); /* 14% above the bottom of the visible screen, even with Safari's bars showing */
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 3vw;
  font: 900 5.9vw / 1 Being, Impact, sans-serif;
  text-transform: uppercase;
}
.titles a:hover { color: var(--yellow); }
.titles i {
  width: .36em;
  aspect-ratio: 3 / 4;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 16'%3E%3Cpath d='M8 0 1 9h4.5L3.5 16 11 6.5H6.5Z' fill='%23f7f7f2'/%3E%3C/svg%3E") center / contain no-repeat;
}

@media (max-width: 640px) {
  .titles { flex-direction: column; gap: .25em; font-size: 15vw; top: calc(var(--bleed-top) + 90svh); bottom: auto; }
  .titles i { display: none; }
}

/* About — headline left, top-aligned with the photo on the right (slides in from the right); text below the photo;
   then a row of tilted photo/video cards that slide in from alternating sides when they scroll into view */
.about {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  column-gap: clamp(1.5rem, 3vw, 3.5rem);
  align-items: start;
  margin-top: calc(-1 * clamp(1rem, 4.5vw, 5rem)); /* up into the space under the menu, so the cards peek above the fold */
}
.about h1 {
  grid-row: 1 / 3;
  align-self: center; /* vertically centred against the photos + paragraphs */
  max-width: 11em;
  font-size: clamp(2.25rem, 2rem + 1.5vw, 4.25rem); /* stays large and wraps onto more lines instead of shrinking */
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -.035em;
  isolation: isolate; /* lets the ring sit behind the words */
  text-wrap: balance; /* even line lengths */
}
.about h1 b { font-weight: 700; color: var(--yellow); }

/* Hand-drawn ring around "impactful": draws itself once on load, then stays */
.ring { position: relative; white-space: nowrap; }
.ring svg {
  position: absolute;
  z-index: -1;
  left: -.3em;
  top: -.14em;
  width: calc(100% + .6em);
  height: calc(100% + .28em);
  overflow: visible;
  rotate: -2deg;
  opacity: .5;
  fill: none;
  stroke: var(--yellow);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: draw 1.1s .5s cubic-bezier(.45, 0, .2, 1) forwards;
}
@media (prefers-reduced-motion: reduce) { .ring svg { animation: none; stroke-dashoffset: 0; } }
.about figure :is(img, video) { display: block; width: 100%; height: 100%; object-fit: cover; }
.about > figure {
  position: relative;
  z-index: 1;
  grid-area: 1 / 2; /* both photos share the top-right cell */
  width: 70%;
  max-width: 460px; /* the source is only 540px wide — kept below that so it stays sharp */
  aspect-ratio: 16 / 10;
  rotate: -3deg;
  animation: slide-r 1.2s cubic-bezier(.2, .8, .2, 1) both;
}
.about > figure img { object-position: 50% 35%; }
/* Second photo: right of the portrait, lower and behind it — overlaps more as the window narrows */
.about > .back {
  z-index: 0;
  justify-self: end;
  width: 46%;
  max-width: 380px;
  margin-top: 5%;
  aspect-ratio: 3 / 2;
  rotate: 4deg;
  animation-delay: .15s;
}
@keyframes slide-r { from { translate: 120vw 0; } }
@keyframes slide-l { from { translate: -120vw 0; } }

.about .text { columns: 2 14rem; column-gap: clamp(1.5rem, 3vw, 3rem); margin-top: clamp(1rem, 1.5vw, 1.75rem); }
.about p { margin-bottom: 1em; break-inside: avoid; }
.about mark { padding: .1em .3em; font-weight: 500; color: #000; background: var(--yellow); }
.about mark:hover { background: var(--paper); }

/* Card row */
.cards {
  grid-column: 1 / -1;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  margin-top: clamp(1.5rem, 2.5vw, 3rem);
}
.cards figure { height: clamp(200px, 21vw, 380px); animation: slide-l 1.1s cubic-bezier(.2, .8, .2, 1) both; }
.cards figure:nth-child(odd) { rotate: 3deg; }
.cards figure:nth-child(even) { rotate: -2.5deg; animation-name: slide-r; translate: 0 2rem; }
.cards figure:nth-child(2) { animation-delay: .12s; }
.cards figure:nth-child(3) { animation-delay: .24s; }
.cards .tall { aspect-ratio: 2 / 3; }
.cards .wide { aspect-ratio: 16 / 9; }
.js .cards figure:not(.in) { animation: none; opacity: 0; } /* waits in place, invisible; site.js adds .in when it's on screen */

@media (prefers-reduced-motion: reduce) { .about figure { animation: none; } }

@media (max-width: 1024px) { /* phones + tablets: stacked */
  .about { grid-template-columns: 1fr; margin-top: 0; }
  .about h1 { grid-row: auto; max-width: none; }
  .about > figure { grid-area: auto; width: 100%; margin: 1rem 0 2.5rem; }
  .about > .back { order: 1; justify-self: center; width: 90%; max-width: none; margin: 4rem 0 0; } /* below the text, with the cards */
  .cards { order: 2; }
  .cards { flex-direction: column; gap: 3rem; margin-top: 4rem; }
  .cards figure { width: 90%; height: auto; }
  .cards .tall { width: 65%; }
}
