/* ==========================================================================
   pages.css — everything behind the home

   The front page is a fixed surface you rearrange. These are the pages the
   cards open onto, and the conceit carries over: the same paper, the same
   card stock, the same three-drop shadow, the same tag straddling the trim.
   What changes is that here a card has been picked up, laid flat, and is
   being read — so nothing tilts, nothing magnets, and the page scrolls.

   Loads after foundation.css, which owns the @font-face declarations, the
   reset, the :root tokens, the tag component and the nav.
   Hand-authored CSS. No build step: edit this file directly.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Page
   -------------------------------------------------------------------------- */
:root {
  /* Two widths, one left edge. Every page is framed on the wide rail — the
     masthead, the heroes, the galleries, the grids — and the things you
     actually read are held back to the measure inside it. Nothing on this
     site is centred against something else's edge. */
  --measure: 43rem;
  --measure-wide: 68rem;

  /* The gutter, which is also the rhythm everything else is spaced on. */
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --rhythm: clamp(2.5rem, 7vw, 4.5rem);
}

html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: calc(16px * var(--type-scale));
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(41, 25, 19, .12); }

a { text-decoration-thickness: 1px; text-underline-offset: .18em; }

:focus-visible {
  outline: 1.5px solid rgba(41, 25, 19, .5);
  outline-offset: 4px;
  border-radius: 5px;
}

/* --------------------------------------------------------------------------
   2. Masthead
   The wordmark goes home; the nav is the same chip that sits pinned to the
   home, only here it has somewhere to sit.
   -------------------------------------------------------------------------- */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.75rem) var(--gutter) 0;
}

.masthead__mark {
  display: block;
  flex: 0 0 auto;
  line-height: 0;
}

.masthead__mark img {
  width: 3.25rem;
  height: auto;
  opacity: .92;
  transition: opacity 200ms var(--ease-magnet);
}

.masthead__mark:hover img { opacity: 1; }

/* Six padded items and the wordmark need about 36rem between them. Under
   that the nav takes a row of its own below the mark and the items share it
   out evenly, giving up the gap and most of their side padding to fit. Both
   layers take the same squeeze, so the plate stays under the type. The
   wordmark is centred over it, and the nav comes up closer under it, as
   they are on a phone's home. */
@media (max-width: 38rem) {
  .masthead {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: .625rem;
  }

  .masthead .nav {
    display: grid;
    flex: 1 1 100%;
  }

  .masthead .nav__layer {
    gap: 0;
    padding-inline: 4px;
  }

  .masthead .nav__item {
    flex: 1 0 auto;
    padding-inline: 2px;
  }
}

/* --------------------------------------------------------------------------
   3. Page frame
   -------------------------------------------------------------------------- */
.page {
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: var(--rhythm) var(--gutter) 0;
}

/* Held back to the measure inside the rail. */
.section-head,
.masthead-entry,
.leaf,
.stream,
.paginator { max-width: var(--measure); }

.section-head {
  margin-bottom: var(--rhythm);
}

.section-head__title {
  font-family: var(--font-serif);
  font-size: calc(clamp(2.5rem, 8vw, 4rem) * var(--type-scale));
  font-weight: 400;
  line-height: .98;
  letter-spacing: -.015em;
  color: var(--ink);
}

.section-head__blurb {
  max-width: 32rem;
  margin-top: 1rem;
  font-size: calc(.9375rem * var(--type-scale));
  line-height: 1.55;
  color: var(--warm-grey);
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   4. Entry heads
   -------------------------------------------------------------------------- */
.masthead-entry {
  margin-bottom: clamp(1.75rem, 5vw, 2.75rem);
}

.entry__title {
  font-family: var(--font-serif);
  font-size: calc(clamp(2rem, 6vw, 3.25rem) * var(--type-scale));
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -.015em;
  text-wrap: balance;
}

.entry__standfirst {
  margin-top: 1rem;
  font-family: var(--font-serif);
  font-size: calc(1.125rem * var(--type-scale));
  line-height: 1.45;
  color: var(--warm-grey);
  text-wrap: pretty;
}

/* The stamp: a date set in the mono cut, which is the one place on this site
   where numerals want to line up rather than read. */
.stamp {
  font-family: var(--font-mono);
  font-size: calc(1.0625rem * var(--type-scale));
  font-weight: 400;
  letter-spacing: .01em;
  color: var(--ink);
}

.stamp--small {
  margin-bottom: .875rem;
  font-size: calc(.8125rem * var(--type-scale));
  letter-spacing: .06em;
  text-transform: lowercase;
  color: var(--warm-grey);
}

.stamp--small a { text-decoration: none; border-bottom: .5px solid var(--hairline); transition: color 200ms var(--ease-magnet); }
.stamp--small a:hover { color: var(--ink); }

/* --------------------------------------------------------------------------
   5. The leaf — a card picked up and laid flat
   -------------------------------------------------------------------------- */
.leaf {
  position: relative;
  border-radius: 4px;
  background: var(--card);
  box-shadow: var(--shadow-rest);
  padding: clamp(1.75rem, 5vw, 3.25rem);
}

.leaf--note { padding-bottom: clamp(1.5rem, 4vw, 2.5rem); }

/* --------------------------------------------------------------------------
   6. Prose
   Louize sets the body. The markers between sections are set in the UI face
   instead, so a heading reads as a label on the writing rather than as more
   writing.
   -------------------------------------------------------------------------- */
.prose {
  font-family: var(--font-serif);
  font-size: calc(1.1875rem * var(--type-scale));
  line-height: 1.6;
  color: var(--ink);
  text-wrap: pretty;
}

.prose > * + * { margin-top: 1.1em; }

/* A note is one thought. It gets the lede size and no run-on. */
.prose--terse { font-size: calc(1.25rem * var(--type-scale)); line-height: 1.5; }
.prose--terse > p:first-child { font-size: inherit; }

.prose__lede,
.prose > p:first-child {
  font-size: calc(1.3125rem * var(--type-scale));
  line-height: 1.45;
}

.prose h2,
.prose h3 {
  margin-top: 2.25em;
  font-family: var(--font-ui);
  font-size: calc(.75rem * var(--type-scale));
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--warm-grey);
}

.prose h2 + *,
.prose h3 + * { margin-top: .75em; }

.prose h3 { letter-spacing: .07em; text-transform: none; font-size: calc(.8125rem * var(--type-scale)); }

.prose em { font-style: italic; }

.prose blockquote {
  margin-left: 0;
  padding-left: 1.25rem;
  border-left: 1.5px solid var(--hairline);
  color: var(--warm-grey);
}

.prose code {
  font-family: var(--font-mono);
  font-size: .875em;
  padding: .1em .35em;
  border-radius: 3px;
  background: var(--chip-wash);
}

.prose ul,
.prose ol { padding-left: 1.25em; }
.prose li + li { margin-top: .35em; }

.prose img {
  width: 100%;
  height: auto;
  border-radius: 3px;
  box-shadow: var(--shadow-rest);
}

/* The home's link underline: a hairline that steps around descenders. */
.prose a,
.colophon a,
.section-head__blurb a,
.about__bio a,
.lost__line a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-position: 0 calc(100% - .09em);
  background-repeat: no-repeat;
  text-shadow:
     .035em 0 var(--card), -.035em 0 var(--card),
     0 .035em var(--card), 0 -.035em var(--card);
  transition: background-size 240ms var(--ease-magnet), color 240ms var(--ease-magnet);
}

.prose a:hover,
.colophon a:hover,
.section-head__blurb a:hover,
.about__bio a:hover,
.lost__line a:hover {
  color: var(--red);
  background-size: 100% 2px;
}

/* Off the card stock, the knockout has to match the home instead. */
.colophon a,
.section-head__blurb a,
.about__bio a,
.lost__line a {
  text-shadow:
     .035em 0 var(--paper), -.035em 0 var(--paper),
     0 .035em var(--paper), 0 -.035em var(--paper);
}

/* --------------------------------------------------------------------------
   7. The stream — the journal index
   Twenty slips in a drawer. A note is one line and nothing else; an article
   or a trip earns a title, an excerpt, and in the trip's case the first
   photograph off the roll.
   -------------------------------------------------------------------------- */
.stream {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

.slip {
  display: block;
  text-decoration: none;
  color: inherit;
  --label-x: 22;
}

.slip__paper {
  position: relative;
  display: flex;
  gap: 1.25rem;
  border-radius: 4px;
  background: var(--card);
  box-shadow: var(--shadow-rest);
  padding: 1.25rem 1.5rem 1.5rem;
  transition: box-shadow 280ms var(--ease-magnet);
}

@media (hover: hover) and (pointer: fine) {
  .slip:hover .slip__paper,
  .slip:focus-visible .slip__paper { box-shadow: var(--shadow-lift); }
}

.slip__thumb {
  flex: 0 0 auto;
  width: 5.5rem;
  align-self: flex-start;
  overflow: hidden;
  border-radius: 3px;
  background: var(--emulsion);
}

.slip__thumb img {
  width: 100%;
  height: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.slip__body {
  display: flex;
  flex: 1 1 auto;
  gap: 1.25rem;
  min-width: 0;
}

.slip__date {
  flex: 0 0 auto;
  width: 3.75rem;
  padding-top: .18em;
  font-family: var(--font-mono);
  font-size: calc(.75rem * var(--type-scale));
  letter-spacing: .02em;
  color: var(--warm-grey);
  font-variant-numeric: tabular-nums;
}

.slip__text { min-width: 0; }

.slip__line {
  display: block;
  font-family: var(--font-serif);
  font-size: calc(1.0625rem * var(--type-scale));
  line-height: 1.45;
  color: var(--ink);
  text-wrap: pretty;
}

.slip__title {
  display: block;
  font-family: var(--font-serif);
  font-size: calc(1.3125rem * var(--type-scale));
  line-height: 1.2;
  letter-spacing: -.008em;
  color: var(--ink);
  text-wrap: balance;
}

.slip__excerpt {
  display: block;
  margin-top: .45rem;
  font-size: calc(.875rem * var(--type-scale));
  line-height: 1.5;
  color: var(--warm-grey);
  text-wrap: pretty;
}

.slip__label {
  font-size: calc(12px * var(--type-scale));
  text-transform: lowercase;
}

@media (max-width: 34rem) {
  .slip__body { flex-direction: column; gap: .5rem; }
  .slip__date { width: auto; padding-top: 0; }
}

/* --------------------------------------------------------------------------
   7b. The garden — a canvas, not a page

   Everything else behind the home is a column you read down. The garden is a
   surface you move around: wider and taller than the window, scrolled in both
   directions, with the quotes scattered across it.

   The scatter is a multi-column box with a height and no column count, so the
   browser flows the quotes down one column and on into the next, and the ones
   that don't fit become the canvas waiting off to the right. lib/garden.js
   hands it four numbers — the column width, the canvas height, and per card
   how wide it is and how far it drifts — and spends none of them itself.

   Without JavaScript this is already finished: the frame scrolls natively in
   both axes, by trackpad, by wheel, by touch, and by the arrow keys once it
   has focus. garden.js only adds dragging.
   -------------------------------------------------------------------------- */
/* The garden takes the home's framing: the surface is the window, edge to
   edge, with nothing above or below it. Everything that would have been page
   furniture — the wordmark, the nav, the title — is out on the surface with
   the quotes, so there is no masthead to leave room for and no footer to stay
   clear of. Fixed rather than tall, for the same reason the home is: the page
   behind it does not scroll, the surface inside it does. */
body.canvas {
  overflow: hidden;
  overscroll-behavior: none;
}

.garden {
  position: fixed;
  inset: 0;
  /* The frame is its own stacking context, so the nav's blend stops here.
     It needs the paper in here with it. */
  background: var(--paper);
  overflow: auto;
  /* Sideways never reaches the browser: a two-finger swipe left on a canvas
     means pan, not go back a page. Down still hands off to the document once
     the garden runs out, so the page doesn't trap the wheel. */
  overscroll-behavior-x: contain;
  overscroll-behavior-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}

.garden:focus-visible {
  outline: 1.5px solid var(--ink);
  outline-offset: -2px;
}

/* Only once garden.js has said so — without it there is nothing to grab. */
.garden.is-grabbable { cursor: grab; }

.garden.is-held {
  cursor: grabbing;
  user-select: none;
  /* Held, the canvas is being moved, not read. */
  scroll-behavior: auto;
}

.garden.is-held .sprig { pointer-events: none; }

/* The canvas itself. Two states, and the markup is the same in both: the
   wordmark, the nav, the title, and then the quotes.

   Unpacked is what ships and what a browser without JavaScript keeps — the
   title is a heading and the quotes wrap beneath it, which is a page. Packed
   is what dist/scripts/garden.js makes of it: the title set down in the
   middle of a surface and every quote placed around it, with the field sized
   to whatever came out. Both are held back with visibility until the packing
   has run, so nobody watches one become the other; garden.js reveals them
   whatever happens, including if it throws. */
.garden__field {
  padding: var(--gutter);
}

.garden.is-packing .garden__field { visibility: hidden; }
.garden.is-ready .garden__field { visibility: visible; }

/* Packed, the field is a surface and every seat has a place on it. */
.garden.is-packed .garden__field {
  display: block;
  position: relative;
  padding: 0;
}

.garden__crop {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The plate — the wordmark, the nav and the title as one object, drawn at
   node 250:2472. A hairline card holding the type, with the wordmark and the
   nav straddling its top edge the way a postcard's tag straddles its trim.
   432 wide with the card flush to its right, so the wordmark overhangs on the
   left by 39 and both break the line of the card's top.

   Drawn sizes times --type-scale, like the rest of the site. The nav is the
   shared component and keeps the 14px the site holds it at — the artboard
   draws it at 12, the same step the meta chips are drawn at and held above.
   ------------------------------------------------------------------------ */
.garden__plate {
  position: relative;
  width: 432px;
  padding-top: 23.37px;
}

.garden__mark {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  line-height: 0;
}

.garden__mark img {
  width: 77.477px;
  height: auto;
  opacity: .92;
  transition: opacity 200ms var(--ease-magnet);
}

.garden__mark:hover img { opacity: 1; }

/* Hung off the card's right edge, 12 in, as the artboard has it. Five padded
   items at the held size only clear the wordmark with the gap between them
   given up. Placed with right/top and nothing else — a transform here would
   close the nav off from the paper its type blends against. */
.garden__nav {
  position: absolute;
  right: 12px;
  top: 11px;
}

.garden__nav .nav__layer { gap: 0; }

/* No stock: a hairline round the type with the paper showing through, so the
   plate reads as a label on the garden rather than another card in it. */
.garden__card {
  margin-left: 39px;
  width: 393px;
  padding: 32px;
  border: 1px solid var(--hairline);
  border-radius: 4px;
}

/* The drawn title carries a progressive layer blur — radius 2.9466 ramping
   from 0 along x, node 250:2342 — and it is deliberately not built. If you
   come back from Figma wondering why the ramp is missing, this is why: it was
   implemented, looked at, and taken out. Set the type and leave it sharp. */
.garden__heading {
  font-family: var(--font-serif);
  font-size: calc(29.466px * var(--type-scale));
  font-weight: 400;
  line-height: 1.41;
  color: var(--ink);
}

.garden__blurb {
  margin: 11px 0 0;
  max-width: 284px;
  font-size: calc(16px * var(--type-scale));
  line-height: 1.28;
  color: #000;
  text-wrap: pretty;
}

.garden__note {
  margin: 23px 0 0;
  font-family: var(--font-mono);
  font-size: calc(10px * var(--type-scale));
  line-height: 1.28;
  text-transform: uppercase;
  color: var(--warm-grey);
  text-wrap: pretty;
}

/* Sown, the plate and every quote have a place on the surface. */
.garden.is-packed .garden__seat,
.garden.is-packed .garden__plate {
  position: absolute;
  left: var(--px, 0px);
  top: var(--py, 0px);
}

/* Packed, the list has nothing left to lay out — every seat is placed on the
   field above it. */
.garden.is-packed .garden__crop { display: block; }

.sprig {
  display: block;
  width: var(--w, 340px);
  text-decoration: none;
  color: inherit;
}

/* The card itself — the same stock, radius and three-drop shadow as a slip in
   the journal or a plate in the grid, because it is the same postcard. */
.sprig__paper {
  display: block;
  position: relative;
  border-radius: 4px;
  background: var(--card);
  box-shadow: var(--shadow-rest);
  padding: 1.25rem 1.375rem 1.125rem;
  transition: box-shadow 280ms var(--ease-magnet);
}

@media (hover: hover) and (pointer: fine) {
  .sprig:hover .sprig__paper,
  .sprig:focus-visible .sprig__paper { box-shadow: var(--shadow-lift); }
}

/* Below the measure the canvas stops being one. A phone can hold a 440px
   column only by making you scroll sideways to finish reading a card, which
   is the opposite of what the sideways scroll is for — so the garden gives up
   the conceit and becomes what every other page here is: one column, read
   down. The drift, the fall, the hang and the fixed card widths all go with
   it; they were placement on a surface, and there is no surface. */
@media (max-width: 40rem) {
  .garden,
  .garden.is-packed {
    height: auto;
    overflow: visible;
    cursor: auto;
  }

  .garden__field,
  .garden.is-packed .garden__field {
    display: block;
    position: static;
    width: auto !important;
    height: auto !important;
    min-height: 0;
    padding: var(--gutter) 0;
  }

  .garden.is-packed .garden__seat,
  .garden.is-packed .garden__plate {
    position: static;
  }

  .garden.is-packed .garden__seat { margin-bottom: 1.25rem; }

  body.canvas { overflow: visible; }

  .garden,
  .garden.is-packed {
    position: static;
    inset: auto;
  }

  /* The plate stops straddling and simply stacks: wordmark, nav, then the
     card, each on its own line and the card no longer inset. */
  .garden__plate {
    width: auto;
    padding-top: 0;
    margin-bottom: var(--rhythm);
  }

  .garden__mark,
  .garden__nav {
    position: static;
    transform: none;
    margin: 0 0 1rem;
  }

  /* The same squeeze the masthead takes: one row, shared out evenly. */
  .garden__nav { display: grid; }

  .garden__nav .nav__layer { padding-inline: 4px; }

  .garden__nav .nav__item {
    flex: 1 0 auto;
    padding-inline: 2px;
  }

  .garden__card {
    margin-left: 0;
    width: auto;
    padding: 1.5rem;
  }

  .sprig { width: auto; }
}

/* The passage. Louize, as close as the pages get to the quote card on the
   home — which is the same card, before it was planted. The marks, the
   paragraph spacing and the cut mechanics are shared with the home's own
   copy; only the size is drawn differently here, in foundation.css. */
.passage {
  font-size: calc(1.375rem * var(--type-scale));
  line-height: 1.32;
  color: var(--ink);
}

.passage--card {
  font-size: calc(1rem * var(--type-scale));
  line-height: 1.34;
  max-height: calc(var(--lines, 7) * 1.34em);
}

/* Open, the card gives up the cut: script writes the full height over this
   max-height, and garden.js runs the height between the two itself.

   Never as a CSS transition. The cut is a max-height built out of var(), and
   a transition between two var()-derived values is one Chrome will not run:
   it opens the transition and leaves it at currentTime 0 forever, so the
   card stays shut with the class on and every measurement of it lies.
   Pinning plain lengths either side of the change did not hold either. The
   script animates height in px from a measured start to a measured end,
   which is nothing CSS ever has to resolve.

   A seat shoved aside by an opening neighbour is moved the same way: its
   left/top jump to where it is going, and garden.js plays a translate from
   where it was back to nothing, so the move is on the compositor rather than
   a layout every frame. */

.garden__seat.is-open {
  /* Above its neighbours while they are getting out of its way. */
  z-index: 2;
}

.garden__seat.is-open .sprig__paper { box-shadow: var(--shadow-lift); }


/* Where it came from: under the passage on the card, and again on its own
   page. The chips wrap here, which they never do on the home — a source can
   be a whole book title and the card is only so wide. */
.credit {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 1.125rem 0 0;
}

.credit .chip { white-space: normal; }

.leaf .credit { margin-top: clamp(1.5rem, 4vw, 2.25rem); }

/* --------------------------------------------------------------------------
   8. Plates — the work and photo grids
   The matte frame off the home, tiled: 12px of card stock around a cover,
   the title straddling the trim.
   -------------------------------------------------------------------------- */
.plates {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: clamp(2.25rem, 5vw, 3.5rem) clamp(1.5rem, 3vw, 2.5rem);
  /* A featured plate takes two columns; dense packing lets the single-column
     ones fall into the hole it leaves rather than leaving the row half empty. */
  grid-auto-flow: dense;
}

@media (min-width: 46rem) {
  .plates__cell--wide { grid-column: span 2; }
}

.plate {
  display: block;
  text-decoration: none;
  color: inherit;
  --label-x: 20;
}

.plate__paper {
  position: relative;
  display: block;
  border-radius: 4px;
  background: var(--card);
  box-shadow: var(--shadow-rest);
  padding: 12px;
  transition: box-shadow 280ms var(--ease-magnet);
}

/* The shape lives on the frame, not only on the photograph, so a project
   that has not been given a cover yet still sits in the grid as a blank card
   with its title on the tag. */
.plate__media {
  display: block;
  overflow: hidden;
  border-radius: 3px;
  background: var(--emulsion);
  aspect-ratio: 4 / 5;
}

.plates__cell--wide .plate__media { aspect-ratio: 3 / 2; }

.plate__media img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: var(--media-pos, 50% 42%);
}

.plates__cell--wide .plate__media img { aspect-ratio: 3 / 2; }

/* A long project title truncates rather than running off the stock. The cap is
   on the inner span because the tag itself is an inline-flex box. */
.plate__label { max-width: calc(100% - 40px); }

.plate__label > span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}

.plate__note {
  display: block;
  margin-top: 1.75rem;
  font-size: calc(.75rem * var(--type-scale));
  letter-spacing: .06em;
  text-transform: lowercase;
  color: var(--warm-grey);
  transition: color 200ms var(--ease-magnet);
}

@media (hover: hover) and (pointer: fine) {
  .plate:hover .plate__paper,
  .plate:focus-visible .plate__paper { box-shadow: var(--shadow-lift); }
  .plate:hover .plate__note { color: var(--ink); }
}

.empty {
  padding: 2rem 0;
  font-size: calc(.9375rem * var(--type-scale));
  color: var(--warm-grey);
}

/* --------------------------------------------------------------------------
   9. Photographs — heroes and galleries
   Prints laid out on the home: natural proportions, a hairline radius, and
   the same shadow every other object here carries.
   -------------------------------------------------------------------------- */
.hero {
  margin-bottom: clamp(2rem, 6vw, 3.5rem);
}

.hero img {
  width: 100%;
  height: auto;
  border-radius: 4px;
  background: var(--emulsion);
  box-shadow: var(--shadow-lift);
}

.hero__caption,
.gallery__caption {
  margin-top: .875rem;
  font-size: calc(.75rem * var(--type-scale));
  line-height: 1.5;
  color: var(--warm-grey);
  text-wrap: pretty;
}

.gallery {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

/* Landscape frames take the row; portraits pair up. Orientation is read off
   the file in the template, so nothing has to be declared per photograph. */
.gallery__frame--wide { grid-column: 1 / -1; }

.gallery__frame img {
  width: 100%;
  height: auto;
  border-radius: 3px;
  background: var(--emulsion);
  box-shadow: var(--shadow-rest);
}

@media (max-width: 40rem) {
  .gallery { grid-template-columns: 1fr; }
  .gallery__frame--tall { grid-column: 1 / -1; }
}

/* --------------------------------------------------------------------------
   10. Docket — the metadata on a project
   -------------------------------------------------------------------------- */
.docket {
  margin: clamp(2rem, 5vw, 3rem) 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1px;
  background: var(--hairline);
  border-block: .5px solid var(--hairline);
}

.docket__row {
  padding: 1rem 0 1.1rem;
  background: var(--paper);
}

.docket dt {
  font-size: calc(.6875rem * var(--type-scale));
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--warm-grey);
}

.docket dd {
  margin: .4rem 0 0;
  font-size: calc(.9375rem * var(--type-scale));
  line-height: 1.35;
  color: var(--ink);
}

/* One collaborator to a line, with what they did set quieter beside the name. */
.docket__credit { display: block; }
.docket__credit-role { color: var(--warm-grey); }

.docket dd a { color: inherit; text-decoration: none; border-bottom: .5px solid var(--hairline); transition: border-bottom-color 200ms var(--ease-magnet); }
.docket dd a:hover { border-bottom-color: var(--ink); }

/* --------------------------------------------------------------------------
   11. Chips in the wild — tags, filters, page counts
   -------------------------------------------------------------------------- */
.tagrow {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
}

.chip--tag { background: var(--chip-wash); }
.chip--tag .chip__value { color: var(--warm-grey); }

.filters {
  margin-top: 1.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
}

.filters__chip {
  text-decoration: none;
  transition:
    background 200ms var(--ease-magnet),
    border-color 200ms var(--ease-magnet),
    color 200ms var(--ease-magnet);
}

.filters__chip .chip__value { text-transform: lowercase; }
.filters__chip .chip__key { font-variant-numeric: tabular-nums; }

.filters__chip.is-on {
  background: var(--ink);
  border-color: var(--ink);
}

.filters__chip.is-on .chip__value { color: var(--card); }

/* The blend needs a light ground to invert against. Inverted, it has none —
   so the count just sits in the stock colour at half strength. */
.filters__chip.is-on .chip__key {
  mix-blend-mode: normal;
  color: rgba(255, 247, 237, .5);
}

@media (hover: hover) and (pointer: fine) {
  .filters__chip:not(.is-on):hover {
    background: var(--meta-wash);
    border-color: var(--warm-grey);
  }
}

/* Pressed, a chip sinks back toward the wash, or the ink one lets a little
   of the paper through — fast, so the press is felt before the page turns. */
.filters__chip:active { transition-duration: 80ms; }
.filters__chip:not(.is-on):active { background: var(--chip-wash); }
.filters__chip.is-on:active { background: color-mix(in srgb, var(--ink) 82%, transparent); }

/* --------------------------------------------------------------------------
   12. Pagers
   -------------------------------------------------------------------------- */
.pager {
  max-width: var(--measure-wide);
  margin: clamp(3rem, 8vw, 5rem) auto 0;
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding-top: 1.75rem;
  border-top: .5px solid var(--hairline);
}

.pager__step {
  display: block;
  max-width: 18rem;
  text-decoration: none;
  color: var(--warm-grey);
  transition: color 200ms var(--ease-magnet), opacity 160ms var(--ease-magnet);
}

.pager__step--on { text-align: right; }

.pager__key {
  display: block;
  font-size: calc(.6875rem * var(--type-scale));
  letter-spacing: .1em;
  text-transform: uppercase;
}

.pager__title {
  display: block;
  margin-top: .3rem;
  font-family: var(--font-serif);
  font-size: calc(1.0625rem * var(--type-scale));
  line-height: 1.25;
  color: var(--ink);
}

.pager__step:hover { color: var(--ink); }

/* A step gives a little under the press, and comes back as it lets go. */
.pager__step:active,
.paginator__step[href]:active {
  opacity: .55;
  transition-duration: 80ms;
}

.paginator {
  margin-top: clamp(3rem, 8vw, 4.5rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.paginator__step {
  font-size: calc(.8125rem * var(--type-scale));
  letter-spacing: .04em;
  text-decoration: none;
  color: var(--ink);
  transition: color 200ms var(--ease-magnet), opacity 160ms var(--ease-magnet);
}

.paginator__step.is-spent {
  color: var(--warm-grey);
  opacity: .45;
}

.paginator__count .chip__value { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   13. Colophon
   -------------------------------------------------------------------------- */
.colophon {
  max-width: var(--measure-wide);
  margin: clamp(4rem, 10vw, 7rem) auto 0;
  padding: 2rem var(--gutter) clamp(3rem, 8vw, 5rem);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem 1.25rem;
  border-top: .5px solid var(--hairline);
}

.colophon__line {
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
}

.colophon a { color: var(--ink); }

.colophon__note {
  flex: 1 1 18rem;
  font-size: calc(.75rem * var(--type-scale));
  line-height: 1.55;
  color: var(--warm-grey);
  text-wrap: pretty;
}

.colophon__note a { color: var(--warm-grey); }

/* --------------------------------------------------------------------------
   14. About
   Drawn at node 268:85, and laid out as a spread rather than a page: no
   masthead row and no footer. The wordmark and the nav open exactly where
   they open on Home, the collage sits under them, the title is set into it,
   and everything below hangs off one 855px column.

   Every horizontal offset is the artboard's, as a share of that column, so
   the spread narrows as one piece rather than reflowing until the phone
   layout takes over. The collage is in shares of its own 676 × 603 frame.
   -------------------------------------------------------------------------- */
/* Full width, with the 855px column made of its side padding: the nav
   below has to measure from the window's left edge, as the home does. The
   collage opens 19px above the nav, as drawn, wherever the nav has landed. */
.about {
  position: relative;
  padding:
    max(var(--gutter), calc(var(--nav-y) - 19px))
    max(var(--gutter), calc(50% - 427.5px))
    clamp(4rem, 12vw, 209px);
  /* The blends need a ground painted in their own context. */
  background: var(--paper);
  /* Home can open the nav a little past the window's edge; that must not
     become a sideways scroll here. Clip, not hidden: no scroll container. */
  overflow-x: clip;
}

/* The wordmark and the nav, placed where Home opens them: --logo-* and
   --nav-* are the home's on-load screen positions and --home-s its scale,
   written by the script at the top of about.njk. The nav is not a stacking
   context — no z-index, transform or opacity on it — so its difference
   blend reaches the collage under it, as it reaches the cards on the home.
   Its two layers carry the z-index instead, as on the home. */
.about__mark,
.lost__mark {
  position: absolute;
  left: var(--logo-x);
  top: var(--logo-y);
  line-height: 0;
}

.about__mark img,
.lost__mark img {
  width: calc(77.477px * var(--home-s));
  height: auto;
  opacity: .92;
  transition: opacity 200ms var(--ease-magnet);
}

.about__mark:hover img,
.lost__mark:hover img { opacity: 1; }

/* The nav is placed by this wrapper rather than by itself, because zoom
   would scale its own left and top along with everything else. */
.about__spot,
.lost__spot {
  position: absolute;
  left: var(--nav-x);
  top: var(--nav-y);
}

/* The home's type, at the home's scale. Zoom rather than a transform: a
   transform would make the nav a stacking context of its own. */
.about__nav,
.lost__nav {
  --type-scale: var(--type-home);
  zoom: var(--home-s);
}

.lost__nav > .nav__layer { z-index: 3; }

/* Over every piece of the collage, which on About can be carried up under
   them (see the stack below). The wordmark can take a z-index of its own,
   since nothing in it blends. */
.about__nav > .nav__layer { z-index: 7; }
.about__mark { z-index: 6; }

.about__art {
  position: relative;
  width: 79.06%;                    /* 676 of 855 */
  margin-left: .47%;
  aspect-ratio: 676 / 603;
}

.about__art img {
  position: absolute;
  display: block;
  max-width: none;
  object-fit: cover;
}

.about__map      { left: 0;       top: 9.453%;  width: 100%;    height: 78.275%; }
.about__cliff    { left: 56.953%; top: 0;       width: 39.053%; height: 70.481%; border-radius: 2px; }
.about__fire     { left: 26.627%; top: 59.204%; width: 62.870%; height: 30.348%; border-radius: 2px; object-position: 50% 58%; }
.about__portrait { left: 12.278%; top: 32.504%; width: 15.680%; height: auto; aspect-ratio: 1; border-radius: 50%; object-position: 11% 50%; }
.about__route    { left: 5.325%;  top: 15.755%; width: 84.320%; height: 84.411%; object-fit: fill; }

.about__title {
  position: absolute;
  left: 3.55%;
  top: 30.514%;
  font-family: var(--font-serif);
  font-size: calc(32px * var(--type-scale));
  line-height: 1;
  text-transform: uppercase;
  color: var(--paper);
  mix-blend-mode: difference;
}

/* Parallax, below a desktop. about.js writes --par-x and --par-y onto the
   collage, each -1 to 1: the cursor's eased offset from the collage's centre
   in a narrow window, or on a touch screen, how far the page and the collage
   have been scrolled; every layer moves
   by its own --depth in px, nearer layers further. The transform goes on each
   layer and never on .about__art: the collage must stay out of the stacking
   context business, or the title's blend would stop at its edge. The title
   is the one layer that is a blend, and a transform on the blending element
   itself is harmless. Unset, both are 0 and nothing moves. */
.about__map      { --depth: 6; }
.about__route    { --depth: 12; }
.about__cliff    { --depth: 16; }
.about__fire     { --depth: 24; }
.about__portrait { --depth: 32; }
.about__title    { --depth: 40; }

.about__art img,
.about__title {
  transform: translate3d(
    calc(var(--par-x, 0) * var(--depth, 0) * -1px),
    calc(var(--par-y, 0) * var(--depth, 0) * -1px),
    0
  );
}

.about__art.is-parallax img,
.about__art.is-parallax .about__title { will-change: transform; }

/* The stack, which is the drawn order: the map at the bottom with no
   z-index, then the three photographs, whose order about.js rewrites as each
   is picked up, then the route and the title over all of them, always. The
   route is drawn over the photographs and takes no pointer, so a photograph
   under it can still be picked up. Five in all, under the wordmark and nav. */
.about__cliff    { z-index: var(--z, 1); }
.about__fire     { z-index: var(--z, 2); }
.about__portrait { z-index: var(--z, 3); }
.about__route    { z-index: 4; pointer-events: none; }
.about__title    { z-index: 5; }

/* Loose. On a desktop the collage doesn't follow the cursor, it comes apart
   under it: about.js marks it .is-loose, and every .about__piece can be
   picked up and carried, as a card is on the home. Position is --dx / --dy,
   in shares of the piece's own size so a moved piece stays where it was put
   on the collage as the collage scales; --swing and --lift are the home's.
   Separate properties from the parallax transform, which is idle here. */
.about__art.is-loose .about__piece {
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  translate: calc(var(--dx, 0) * 100%) calc(var(--dy, 0) * 100%);
  rotate: calc(var(--swing, 0) * 1deg);
  scale: var(--lift, 1);
  transition:
    scale 140ms var(--ease-settle),
    box-shadow 240ms var(--ease-magnet);
}

/* Flat as drawn until the cursor is on one: a photograph under it lifts a
   little off the map, which is the only sign it can be taken. */
.about__art.is-loose img.about__piece:hover { box-shadow: var(--shadow-lift); }

.about__art.is-loose .about__piece.is-dragging {
  --lift: 1.028;
  cursor: grabbing;
}

.about__art.is-loose img.about__piece.is-dragging { box-shadow: var(--shadow-drag); }

.about__art.is-loose .about__piece.is-settling {
  transition:
    translate 460ms var(--ease-settle),
    rotate 460ms var(--ease-settle),
    scale 460ms var(--ease-settle),
    box-shadow 460ms var(--ease-settle);
}

@media (prefers-reduced-motion: reduce) {
  .about__art.is-loose .about__piece,
  .about__art.is-loose .about__piece.is-settling { transition-duration: 1ms; }
}

.about__hello {
  /* Borrows the gutter on the right, the way the artboard lets it run past
     the column, so "director," keeps to the first line. */
  width: calc(100% - 17.076% + var(--gutter));
  max-width: 855px;
  margin: 30px 0 0 17.076%;         /* 146 of 855 */
  font-family: var(--font-serif);
  font-size: calc(clamp(2rem, 4.6vw, 48px) * var(--type-scale));
  line-height: 1.1;
  color: var(--ink);
  text-wrap: pretty;
}

.about__body {
  display: grid;
  grid-template-columns: minmax(0, 270fr) minmax(0, 563fr);
  column-gap: 20px;
  margin-top: 58px;
}

/* The roles and the CV note at the top, the book at the foot of the bio. */
.about__side {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2.5rem;
}

.about__roles {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;                        /* the reset leaves a dl its 1em */
}

/* The key keeps its width; the value takes whatever the sidebar has left
   and wraps inside it, with the key centred against however many lines it
   runs to. */
.about__role {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 3px 0;
}

.about__role dt {
  flex: 0 0 auto;
  white-space: nowrap;
}

.about__role dd {
  flex: 1 0 0;
  min-width: 1px;
  margin: 0;                        /* the browser indents a dd by 40px */
  font-size: calc(12px * var(--type-scale));
  line-height: 1.28;
}

/* The eyebrow: the small caps key on every label of this page. */
.about__key,
.about__role dt {
  font-size: calc(10px * var(--type-scale));
  line-height: 1.28;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: .62;                            /* 4.6:1 on the paper; .5 was 3.2 */
}

.about__cv {
  margin-top: 31px;
  padding: 3px 0;
}

/* A way out under the CV note: the eyebrow and the home's carat, 10px apart
   and 10px below it. The carat is drawn in Warm Grey at full strength rather
   than inheriting the eyebrow's half-ink. Under the cursor both go Red. */
.about__out {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 10px;
  margin-top: 7px;                  /* 10 from the CV's type, less its padding */
  color: var(--warm-grey);
  text-decoration: none;
  transition: color 240ms var(--ease-magnet);
}

.about__out .about__key { transition: color 240ms var(--ease-magnet), opacity 240ms var(--ease-magnet); }
.about__out svg { flex: none; }

.about__out:hover { color: var(--red); }
.about__out:hover .about__key { color: var(--red); opacity: 1; }

.about__reading {
  display: flex;
  flex-direction: column;
  align-self: flex-start;
  width: 162px;
  font-size: calc(12px * var(--type-scale));
  line-height: 1.28;
  text-align: center;
}

.about__cover {
  width: 100%;
  height: auto;
  aspect-ratio: 162 / 241;
  margin: 15px 0;
  object-fit: cover;
  border-radius: 4px;
  box-shadow: var(--shadow-rest);
}

.about__author {
  margin-top: 6px;
  color: var(--warm-grey);
}

.about__bio {
  font-size: calc(18px * var(--type-scale));
  line-height: 1.36;
  color: var(--ink);
}

.about__bio p { text-wrap: pretty; }
.about__bio p + p { margin-top: 1em; }

.about__recognition { margin-top: 94px; }

.about__ribbon {
  font-family: var(--font-serif);
  font-size: calc(14px * var(--type-scale));
  font-style: italic;
  line-height: 1.28;
  text-align: center;
  color: #000;
}

.about__logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 18px;
  list-style: none;
}

.about__logos li {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 1 143.334px;
  height: 77.9px;
}

.about__logos img {
  width: calc(var(--w) * 1px);
  height: auto;
}

.about__colophon {
  max-width: 560px;
  margin: 94px 0 0 17.25%;          /* 147.5 of 855 */
}

.about__colophon .about__key { padding: 3px 0; }
.about__colophon .about__bio { margin-top: 9px; }

/* The phone: the conceit stays — the collage, the title set in it — but the
   offsets go, and the sidebar follows the bio instead of standing beside it.
   The wordmark and nav still open where Home opens them. */
@media (max-width: 40rem) {
  /* Below the nav rather than under it: the collage is the full width here,
     and would otherwise sit beneath the whole row. */
  .about { padding-top: calc(var(--nav-y) + 2.5rem); }

  .about__hello,
  .about__colophon { margin-left: 0; }

  /* The collage runs a tenth wider than the window and is swiped across,
     from edge to edge of the window rather than the gutters. about.js opens
     it in the middle. The padding is room for the layers' parallax, so a
     layer leaning out of the frame isn't cut off; the margin takes it back
     out of the layout. Overflow is not a stacking context, so the title's
     blend still reaches the layers. */
  .about__head {
    --lean: 48px;
    margin: calc(-1 * var(--lean)) calc(-1 * var(--gutter));
    padding: var(--lean) 0;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .about__head::-webkit-scrollbar { display: none; }

  .about__art {
    width: 110vw;
    margin-left: 0;
  }

  /* The map is the plane the swipe moves, so it holds still and everything
     over it leans off it. Otherwise its edge would lean in off the window's
     edge at either end of the swipe and show paper. */
  .about__map { --depth: 0; }

  .about__hello { width: auto; }

  .about__body {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 3rem;
    margin-top: 2.5rem;
  }

  /* The wordmark over the middle of the window, where the nav is centred
     too (partials/home-frame.njk). By its left edge, not a transform. */
  .about__mark { left: calc(50% - 77.477px * var(--home-s) / 2); }

  /* The sidebar as two narrow columns side by side: the roles and the CV
     on the left, the book on the right. Too narrow for a key beside its
     value, so each role stacks its key over it. */
  .about__side {
    order: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 20px;
    align-items: start;
  }

  .about__role {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .about__reading { width: 100%; }

  .about__recognition,
  .about__colophon { margin-top: 4rem; }

  /* Three to a row leaves a cell about as wide as the widest logo, so each
     cell keeps a margin of its own and a logo too wide for it shrinks
     rather than running into its neighbour. */
  .about__logos li {
    flex-basis: 33.333%;
    padding-inline: 12px;
  }

  .about__logos img { max-width: 100%; }
}

/* --------------------------------------------------------------------------
   15. Not here — the 404
   Drawn at node 311:440, and framed like About: the wordmark and the nav
   where Home opens them, then three photographs and one line under them.
   The row is the artboard's 1219.857px at the home's scale (--home-s, from
   partials/home-frame.njk), centred in the window rather than on the
   artboard, and hung closer under the nav than drawn so the line still lands
   in the first screen.
   -------------------------------------------------------------------------- */
.lost {
  --body-w: min(calc(1219.857px * var(--home-s)), 100% - 2 * var(--gutter));
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: max(var(--gutter), calc(var(--nav-y) + 88px * var(--home-s)));
  padding-bottom: clamp(4rem, 10vw, 140px);
  background: var(--paper);
  overflow-x: clip;
}

.lost__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 60px;
  width: var(--body-w);
  margin-inline: auto;
}

.lost__pan { width: 100%; }

.lost__figs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 7px;
  width: 100%;
}

.lost__fig {
  display: flex;
  flex-direction: column;
  gap: 11px;
  margin: 0;
}

.lost__cap {
  display: flex;
  align-items: center;
  gap: 12px;
  line-height: 1.28;
  color: var(--ink);
  white-space: nowrap;
}

.lost__cap span {
  font-family: var(--font-ui);
  font-size: calc(10px * var(--type-scale));
  letter-spacing: .1em;
  text-transform: uppercase;
  opacity: .62;                            /* 4.6:1 on the paper; .5 was 3.2 */
}

.lost__cap i {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: calc(12px * var(--type-scale));
}

.lost__frame {
  aspect-ratio: 401.952 / 514.338;
  border-radius: 3px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow-rest);
}

.lost__frame picture { display: contents; }

.lost__frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.lost__line {
  /* The drawn measure, grown with the type so it still breaks in two. */
  max-width: calc(677px * var(--type-scale));
  font-family: var(--font-serif);
  font-weight: normal;
  font-size: calc(clamp(1.75rem, 4.6vw, 48px) * var(--type-scale));
  line-height: 1.1;
  text-align: center;
  text-wrap: pretty;
  color: var(--ink);
}

@media (max-width: 40rem) {
  .lost__body { gap: 2.5rem; }
  /* The row runs a tenth past the window at either side, so the window's
     edges crop the outer two, and is swiped across; the script in 404.njk
     opens it in the middle. The scroller is the window's width, whatever
     the column; the padding is room for the frames' shadows, which a
     scroller would otherwise clip, and the margin takes it back out. */
  .lost__pan {
    --lean: 40px;
    width: 100vw;
    margin: calc(-1 * var(--lean)) 0;
    padding: var(--lean) 0;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .lost__pan::-webkit-scrollbar { display: none; }

  .lost__figs {
    width: 120vw;
    column-gap: 5px;
  }

  .lost__line { text-wrap: balance; }

  /* Over the middle of the window, like the nav — as on About. */
  .lost__mark { left: calc(50% - 77.477px * var(--home-s) / 2); }
}

/* --------------------------------------------------------------------------
   16. Preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .slip__paper,
  .plate__paper,
  .sprig__paper,
  .postcard__label,
  .credit .chip,
  .masthead__mark img,
  .about__mark img,
  .lost__mark img,
  .filters__chip,
  .pager__step,
  .paginator__step,
  .plate__note,
  .stamp--small a,
  .docket dd a { transition-duration: 1ms; }
}
