/* Sabryna Evans Photography. One stylesheet, no build step.
   White paper and ink, the way her printed gift certificate looks: a
   lowercase serif voice, a letterspaced sans for small working text, and a
   hand script used sparingly, only ever large. No accent colour; the
   photographs bring the colour.

   Motion follows one idea: her monogram is written in ink, then becomes the
   window her work is seen through. Everything else moves like ink or paper:
   words rise out of a line, lines are drawn, pages slide over pages. */

@font-face { font-family: "Cormorant"; src: url("/assets/fonts/cormorant.woff2") format("woff2"); font-weight: 300 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Cormorant"; src: url("/assets/fonts/cormorant-italic.woff2") format("woff2"); font-weight: 300 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Jost"; src: url("/assets/fonts/jost.woff2") format("woff2"); font-weight: 300 600; font-display: swap; }
@font-face { font-family: "Script"; src: url("/assets/fonts/script.woff2") format("woff2"); font-display: swap; }

:root {
  --paper: #fbfaf8;
  --white: #ffffff;
  --ink: #1c1b19;
  --ink-2: #5d5850;
  --ink-3: #787269; /* small text: 4.5:1 on paper and on white */
  --ink-4: #958f85; /* large text only: 3:1 on paper */
  --line: #e7e3dc;
  --mist: #f3f1ec;

  --serif: "Cormorant", Georgia, "Times New Roman", serif;
  --sans: "Jost", "Helvetica Neue", Arial, sans-serif;
  --script: "Script", "Brush Script MT", cursive;

  --gutter: clamp(18px, 1rem + 2.4vw, 56px);
  --section: clamp(96px, 5rem + 7vw, 200px);
  --measure: 1240px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);

  /* The hero: how much scrolling the zoom takes, and how far the page
     slides up over the photograph once it is open. */
  --zoom-run: 170vh;
  --sheet: 92vh;
  --r-sheet: clamp(22px, 2.6vw, 44px);

  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--paper); color: var(--ink); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  font-weight: 350;
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.1rem);
  line-height: 1.7;
  background: var(--paper);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}
/* Width and height attributes reserve space before an image loads; as
   presentational hints they also set a CSS height, which beats
   aspect-ratio. height: auto undoes it. */
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
p, h1, h2, h3 { margin: 0; }
h1, h2, h3 { font-weight: 400; }
em { font-style: italic; }
::selection { background: var(--ink); color: var(--paper); }
:focus-visible { outline: 1.5px solid var(--ink); outline-offset: 4px; }
main:focus { outline: none; }

/* Smooth scrolling (Lenis, wheel only). Its own scroll replaces the
   browser's smooth behaviour, which would fight it frame by frame. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
.lenis.lenis-stopped { overflow: clip; }

/* Page to page: a soft cross-fade where the browser supports it. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.45s; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: fixed; left: var(--gutter); top: -80px; z-index: 300; background: var(--ink); color: var(--paper); padding: 12px 18px; font: 500 12px var(--sans); letter-spacing: 0.14em; text-transform: uppercase; transition: top 0.2s; }
.skip:focus { top: var(--gutter); }

.wrap { width: min(var(--measure), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: var(--section); }

/* Type */
.kicker { font: 500 11px var(--sans); letter-spacing: 0.32em; text-transform: uppercase; color: var(--ink-3); }
.script { font-family: var(--script); font-weight: 400; line-height: 1; color: var(--ink); }
.h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(2.6rem, 1.4rem + 4.4vw, 6rem); line-height: 1.02; letter-spacing: -0.015em; }
.h2 em, .about__hi h2 em { font-weight: 400; letter-spacing: -0.01em; }

/* Links that underline as if drawn. */
.ink-link { background: linear-gradient(currentColor, currentColor) left bottom / 0% 1px no-repeat; padding-bottom: 3px; transition: background-size 0.6s var(--ease); }
.ink-link:hover, .ink-link:focus-visible { background-size: 100% 1px; }
.ink-link--under { background-image: linear-gradient(var(--line), var(--line)), linear-gradient(currentColor, currentColor); background-size: 100% 1px, 0% 1px; background-position: left bottom, left bottom; }
.ink-link--under:hover, .ink-link--under:focus-visible { background-size: 100% 1px, 100% 1px; }
.arrow { display: inline-block; vertical-align: 1px; margin-left: 8px; transition: transform 0.5s var(--ease); }
a:hover .arrow, button:hover .arrow, a:focus-visible .arrow { transform: translateX(4px); }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  height: 50px; padding: 0 30px; border-radius: 999px;
  font: 500 12px var(--sans); letter-spacing: 0.22em; text-transform: uppercase; white-space: nowrap;
  transition: background 0.35s, color 0.35s, border-color 0.35s, transform 0.5s var(--ease), opacity 0.35s, box-shadow 0.35s;
}
.btn--ink { background: var(--ink); color: var(--paper); }
.btn--ink:hover, .btn--ink:focus-visible { background: #3a3833; }
.btn--line { border: 1px solid var(--ink); color: var(--ink); }
.btn--line:hover, .btn--line:focus-visible { background: var(--ink); color: var(--paper); }

/* Headings split into words: each word rises out of its own line. */
.split .w { display: inline-block; overflow: hidden; vertical-align: top; padding-block: 0.12em; margin-block: -0.12em; }
.split .w > span { display: inline-block; }
html.js [data-reveal].split, html.js [data-reveal] .split { opacity: 1; transform: none; }
html.js [data-reveal].split .w > span, html.js [data-reveal] .split .w > span { transform: translateY(110%); transition: transform 1.15s var(--ease); transition-delay: calc(var(--delay, 0s) + var(--wi) * 70ms); }
html.js [data-reveal].split.is-in .w > span, html.js [data-reveal].is-in .split .w > span { transform: none; }

/* Script written on: a wipe from the left at the pace of a hand. The
   negative insets keep the swashes, which reach outside the box. */
html.js .write { clip-path: inset(-40% 100% -40% -8%); transition: clip-path 1.7s var(--ease-io); transition-delay: var(--write-delay, 0.25s); }
html.js .is-in .write, html.js .write.is-in { clip-path: inset(-40% -12% -40% -8%); }

/* ---------------------------------------------------------------- header */
.hd {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 18px var(--gutter);
  transition: background 0.4s, box-shadow 0.4s, padding 0.4s, transform 0.7s var(--ease);
}
html.scrolled .hd { background: rgb(251 250 248 / 0.86); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); box-shadow: 0 1px 0 var(--line); padding-block: 12px; }
/* Out of the way while reading down the page, back on the way up. */
html.hd-hide .hd:not(:focus-within) { transform: translateY(-110%); }
.brand { display: inline-flex; align-items: center; gap: 12px; }
.brand svg { height: 36px; width: auto; }
.brand__name { font: 500 1.3rem/1 var(--serif); letter-spacing: 0.01em; }
/* The header's name waits until the hero's name has scrolled away. */
html.at-top[data-page="home"] .brand__name { opacity: 0; transform: translateY(6px); }
.brand__name { transition: opacity 0.4s, transform 0.5s var(--ease); }
.nav { display: flex; align-items: center; gap: clamp(20px, 2.4vw, 40px); padding-right: 150px; }
.nav a { font: 500 11.5px var(--sans); letter-spacing: 0.24em; text-transform: uppercase; }
.menu-btn { display: none; font: 500 11.5px var(--sans); letter-spacing: 0.24em; text-transform: uppercase; }

.menu { position: fixed; inset: 0; z-index: 70; background: var(--paper); display: grid; align-content: center; justify-items: center; gap: 10px; padding: var(--gutter); opacity: 0; visibility: hidden; clip-path: inset(0 0 100% 0); transition: opacity 0.5s, visibility 0.5s, clip-path 0.7s var(--ease-io); }
/* Visible at once on open, so focus can land in it; the hide is what waits. */
.menu.is-open { opacity: 1; visibility: visible; clip-path: inset(0 0 0 0); transition: opacity 0.3s, visibility 0s, clip-path 0.7s var(--ease-io); }
.menu a { font: 400 clamp(2.2rem, 1.6rem + 4vw, 3.4rem)/1.2 var(--serif); opacity: 0; transform: translateY(24px); transition: opacity 0.5s, transform 0.7s var(--ease); }
.menu.is-open a { opacity: 1; transform: none; transition-delay: calc(0.2s + var(--i) * 70ms); }
.menu .kicker { margin-top: 28px; }

/* The floating Enquire button: top right on desktop, a pill at the foot of
   the screen on phones. site.js hides it while the hero's own button, the
   form or the footer is on screen. */
.book { position: fixed; z-index: 60; top: 13px; right: var(--gutter); height: 44px; padding: 0 26px; box-shadow: 0 10px 30px rgb(28 27 25 / 0.14); }
html.scrolled .book { top: 8px; }
html.book-hidden .book { opacity: 0; transform: translateY(-12px); pointer-events: none; }

/* ------------------------------------------------------------------ hero */
.hero { position: relative; }
.hero__stage { position: relative; min-height: 100vh; min-height: 100svh; display: grid; place-items: center; text-align: center; padding: 110px var(--gutter) 90px; overflow: hidden; }
.hero__inner { position: relative; z-index: 2; display: grid; justify-items: center; }
.mono { width: auto; height: clamp(150px, 26vh, 270px); color: var(--ink); overflow: visible; }
.hero__words { display: grid; justify-items: center; will-change: transform, opacity; }
.hero__name { margin-top: clamp(22px, 3vh, 36px); font: 500 clamp(2.6rem, 1.6rem + 3.4vw, 4.8rem)/1 var(--serif); letter-spacing: 0.005em; }
.hero__sub { margin-top: 12px; font: 500 clamp(0.95rem, 0.85rem + 0.3vw, 1.15rem)/1 var(--serif); letter-spacing: 0.52em; margin-right: -0.52em; color: var(--ink-2); }
.hero__tag { margin-top: clamp(22px, 3vh, 34px); font: italic 400 clamp(1.15rem, 1rem + 0.6vw, 1.55rem)/1.4 var(--serif); color: var(--ink-2); max-width: 30ch; }
.hero__ctas { margin-top: clamp(28px, 4vh, 44px); display: flex; gap: 22px; align-items: center; flex-wrap: wrap; justify-content: center; }
.hero__ctas .ink-link { font: 500 12px var(--sans); letter-spacing: 0.22em; text-transform: uppercase; }
.hero__chrome { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.hero__chrome a { pointer-events: auto; }
.hero__corner { position: absolute; bottom: 28px; margin: 0; font-size: 10.5px; }
.hero__corner--l { left: var(--gutter); }
.hero__corner--r { right: var(--gutter); }
.scroll-cue { position: absolute; z-index: 2; left: 50%; bottom: 26px; width: 1px; height: 54px; background: var(--line); overflow: hidden; }
.scroll-cue::after { content: ""; position: absolute; left: 0; top: -50%; width: 1px; height: 50%; background: var(--ink); animation: cue 2.4s var(--ease-io) infinite; }
@keyframes cue { to { top: 100%; } }

/* The logo writes itself. Each stroke of the monogram sits under a mask
   whose pen path is drawn along its own centreline, in the order the pen
   would make it. The hero's draws on load; the others when they come into
   view. Without JS, or with reduced motion, they are simply there. */
.pen { stroke-dasharray: 1 1; stroke-dashoffset: 0; }
html.js [data-draw] .pen { stroke-dashoffset: 1.001; }
html.js .hero [data-draw] .pen, html.js [data-draw].is-in .pen { animation: draw var(--t) var(--ease-io) var(--d) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* After the pen, the name and the rest settle in, one after another. */
html.js .hero [data-after] { opacity: 0; transform: translateY(12px); animation: settle 0.9s var(--ease) var(--after) forwards; }
@keyframes settle { to { opacity: 1; transform: none; } }

/* The lens. With motion allowed the hero pins, and scrolling turns the
   inked monogram into a window: the ink gives way to the lavender photo
   inside the letters, then the camera flies through the thickest stroke of
   the S until the photograph fills the screen. site.js sets every value. */
.lens { position: absolute; inset: 0; width: 100%; height: 100%; display: none; pointer-events: none; opacity: 0; }
.lens__shade { fill: var(--ink); opacity: 0.3; }
.hero__cap { position: absolute; z-index: 2; left: var(--gutter); bottom: 26px; display: none; font: 500 10.5px var(--sans); letter-spacing: 0.28em; text-transform: uppercase; color: #fff; text-shadow: 0 1px 12px rgb(0 0 0 / 0.4); opacity: 0; }
html.lens-on .hero { height: calc(100vh + var(--zoom-run) + var(--sheet)); }
html.lens-on .hero__stage { position: sticky; top: 0; height: 100vh; min-height: 0; }
html.lens-on .lens, html.lens-on .hero__cap { display: block; }
html.lens-on .hero__still { display: none; }

/* The plain hero, for reduced motion: the logo, then the photograph. */
.hero__still { position: relative; margin: 0; height: clamp(360px, 62vw, 92vh); overflow: hidden; }
.hero__still img { width: 100%; height: 100%; object-fit: cover; }
.hero__still-cap { position: absolute; left: var(--gutter); bottom: 18px; font: 500 10.5px var(--sans); letter-spacing: 0.28em; text-transform: uppercase; color: #fff; text-shadow: 0 1px 10px rgb(0 0 0 / 0.35); }

/* Everything after the hero is one sheet of paper. Once the photo is open
   the sheet slides up over it, rounded at the top like a page. */
.sheet { position: relative; z-index: 2; background: var(--paper); }
html.lens-on .sheet { margin-top: calc(var(--sheet) * -1); border-radius: var(--r-sheet) var(--r-sheet) 0 0; box-shadow: 0 -30px 70px rgb(28 27 25 / 0.14); }

/* ------------------------------------------------------------------ intro */
.intro { text-align: center; }
.intro p { font: 400 clamp(1.9rem, 1.1rem + 2.8vw, 3.7rem)/1.2 var(--serif); max-width: 22ch; margin-inline: auto; letter-spacing: -0.01em; }
/* Words darken one at a time as the paragraph scrolls through; --p runs 0
   to 1 from site.js and is 1 (all ink) without it. */
.scrub span { opacity: clamp(0.14, calc(var(--p, 1) * (var(--n) + 6) - var(--i)), 1); transition: opacity 0.3s linear; }

/* -------------------------------------------------------------- chapters */
/* The six chapters as an index on the left, which stays put while the
   photographs go by on the right. The one in front is written in ink and
   opens to its line and its link; the rest wait in pencil. */
.chapters { padding-bottom: clamp(40px, 6vw, 100px); }
.chapters__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(32px, 6vw, 120px); align-items: start; }
.chapters__index { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; justify-content: center; padding-block: 96px 40px; }
.chapters__head { margin-bottom: clamp(18px, 3.4vh, 44px); }
.chapters__head .script { font-size: clamp(3.4rem, 2.2rem + 3vw, 5.6rem); margin-left: -0.08em; }
.chapters__head .kicker { margin-top: 6px; }
.toc { list-style: none; margin: 0; padding: 0; }
.toc__title { display: flex; align-items: baseline; gap: 16px; padding-block: 3px; font: 400 clamp(1.9rem, 0.9rem + 2.2vw, 3.2rem)/1.08 var(--serif); letter-spacing: -0.01em; color: var(--ink-4); transition: color 0.6s, transform 0.8s var(--ease); }
.toc__n { flex: 0 0 2.4rem; font: italic 400 1.15rem/1 var(--serif); letter-spacing: 0; color: inherit; transition: color 0.6s; }
.toc__title:hover { color: var(--ink-2); }
.toc__item.is-active .toc__title { color: var(--ink); transform: translateX(10px); }
.toc__item.is-active .toc__n { color: var(--ink-3); }
.toc__more { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.8s var(--ease); }
.toc__more > div { overflow: hidden; min-height: 0; padding-left: calc(2.4rem + 26px); }
.toc__more > div > * { opacity: 0; transform: translateY(10px); transition: opacity 0.4s, transform 0.6s var(--ease); }
.toc__item.is-active .toc__more { grid-template-rows: 1fr; }
.toc__item.is-active .toc__more > div > * { opacity: 1; transform: none; transition-delay: 0.25s; }
.toc__line { padding-top: 10px; font: italic 400 clamp(1.1rem, 0.95rem + 0.45vw, 1.4rem)/1.45 var(--serif); color: var(--ink-2); max-width: 30ch; }
.toc__note { margin-top: 12px; }
.toc .chapter__link { margin: 16px 0 16px; }
.toc__count { margin-top: clamp(16px, 3vh, 36px); font-variant-numeric: tabular-nums; }
.toc__cur { color: var(--ink); }
.chapter__link { display: inline-block; font: 500 12px var(--sans); letter-spacing: 0.22em; text-transform: uppercase; }

.chapters__photos { display: grid; gap: 16vh; padding-block: 20vh 22vh; }
.chapter { margin: 0; }
.chapter__media { position: relative; aspect-ratio: 4 / 5; overflow: hidden; background: var(--mist); }
.chapter:nth-child(odd) .chapter__media { width: 86%; }
.chapter:nth-child(even) .chapter__media { width: 70%; margin-left: auto; }
/* The photo sits in a slightly taller layer that drifts inside its frame. */
.par { position: absolute; left: 0; right: 0; top: -7%; height: 114%; will-change: transform; }
.par img { width: 100%; height: 100%; object-fit: cover; }
.chapter__label { margin-top: 16px; transition: color 0.6s; }
.chapter:nth-child(even) .chapter__label { text-align: right; }
.chapter.is-active .chapter__label { color: var(--ink); }
.chapter__text { display: none; }
.chapter__n { font: italic 400 clamp(1.4rem, 1.1rem + 1vw, 2rem)/1 var(--serif); color: var(--ink-3); }
.chapter__text h3 { margin-top: 12px; font: 400 clamp(2.3rem, 1.5rem + 3vw, 4.4rem)/1 var(--serif); letter-spacing: -0.01em; }
.chapter__line { margin-top: 18px; font: italic 400 clamp(1.2rem, 1rem + 0.7vw, 1.6rem)/1.45 var(--serif); color: var(--ink-2); max-width: 30ch; margin-inline: auto; }
.chapter__note { margin-top: 16px; }
.chapter__text .chapter__link { margin-top: 24px; }

/* Photos develop: they rise out of their frame as they come into view. A
   paper curtain lifts off them rather than a clip-path on the image,
   because Chrome will not lazy-load an image its own clip-path hides, so
   every photo would only start downloading once it began to show. */
html.js [data-develop] { position: relative; }
html.js [data-develop]::before { content: ""; position: absolute; inset: -1px; z-index: 2; background: var(--paper); transform-origin: center top; transition: transform 1.5s var(--ease); pointer-events: none; }
html.js [data-develop].is-in::before { transform: scaleY(0); }
html.js [data-develop] img { transform: scale(1.12); transition: transform 2.2s var(--ease); }
html.js [data-develop].is-in img { transform: scale(1); }

/* --------------------------------------------------------------- gallery */
.gallery__head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; margin-bottom: clamp(36px, 4vw, 60px); }
.cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; align-items: start; padding-block: 40px; }
.col { display: grid; gap: 18px; will-change: transform; }
.shot { display: block; width: 100%; overflow: hidden; background: var(--mist); cursor: zoom-in; position: relative; }
.shot img { width: 100%; }
.shot::after { content: ""; position: absolute; inset: 0; background: var(--ink); opacity: 0; transition: opacity 0.6s var(--ease); pointer-events: none; }
.shot:hover::after { opacity: 0.08; }
.shot:hover img, html.js .shot[data-develop].is-in:hover img { transform: scale(1.04); transition: transform 1.2s var(--ease); }
html.has-cursor .shot { cursor: none; }

/* A round label that follows the pointer over photographs. Pointer
   devices only; the real cursor is back everywhere else. */
.cursor { position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none; }
.cursor__dot { position: absolute; left: -46px; top: -46px; width: 92px; height: 92px; border-radius: 50%; background: rgb(28 27 25 / 0.9); color: var(--paper); display: grid; place-items: center; font: 500 10px var(--sans); letter-spacing: 0.26em; text-indent: 0.26em; text-transform: uppercase; transform: scale(0); transition: transform 0.5s var(--ease); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.cursor.is-on .cursor__dot { transform: scale(1); }

/* ----------------------------------------------------------------- steps */
/* A pen line runs through the three steps as they scroll in, and each one
   is written when the line reaches it. */
.how__track { position: relative; margin-top: 40px; --line: 1; }
.how__track::before, .how__rule { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--line); }
.how__rule { background: var(--ink); transform-origin: left center; transform: scaleX(var(--line)); }
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gutter); }
.step { position: relative; padding-top: 34px; }
.step__dot { position: absolute; left: 0; top: -5px; width: 11px; height: 11px; border-radius: 50%; background: var(--ink); border: 1px solid var(--ink); transition: background 0.4s, transform 0.6s var(--ease); }
.step__n { font: italic 400 2.6rem/1 var(--serif); color: var(--ink-3); }
.step h3 { margin-top: 16px; font: 400 clamp(1.7rem, 1.3rem + 1vw, 2.3rem)/1.1 var(--serif); }
.step p:last-child { margin-top: 12px; color: var(--ink-2); max-width: 32ch; }
html.js .how__track[data-armed] .step__dot { background: var(--paper); border-color: var(--ink-4); transform: scale(0.8); }
html.js .how__track[data-armed] .step.is-on .step__dot { background: var(--ink); border-color: var(--ink); transform: scale(1); }
html.js .how__track[data-armed] .step > :not(.step__dot) { opacity: 0; transform: translateY(16px); transition: opacity 0.7s, transform 0.9s var(--ease); }
html.js .how__track[data-armed] .step.is-on > :not(.step__dot) { opacity: 1; transform: none; }
html.js .how__track[data-armed] .step.is-on > h3 { transition-delay: 0.08s; }
html.js .how__track[data-armed] .step.is-on > p:last-child { transition-delay: 0.16s; }

/* ----------------------------------------------------------------- about */
/* Her monogram ghosted behind the words, the way it sits behind her name on
   her printed gift certificates, written on as the section arrives. */
.about { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: clamp(32px, 6vw, 110px); align-items: center; isolation: isolate; }
.about__ghost { position: absolute; z-index: -1; left: 50%; top: 50%; height: 125%; width: auto; transform: translate(-50%, -50%); color: var(--ink); opacity: 0.06; pointer-events: none; overflow: visible; }
.about__hi .script { font-size: clamp(4rem, 2.6rem + 5vw, 8rem); display: block; margin-bottom: -0.15em; }
.about__hi h2 { font: 400 clamp(2.6rem, 1.5rem + 3.8vw, 5.4rem)/1 var(--serif); letter-spacing: -0.01em; }
.about__body p { font: 400 clamp(1.25rem, 1.05rem + 0.6vw, 1.6rem)/1.5 var(--serif); color: var(--ink-2); max-width: 34ch; }
.about__body p + p { margin-top: 18px; }
/* Outranks .about__body p, which would otherwise set the serif on it. */
.about__body .about__sign { margin-top: 24px; font: 400 clamp(2.6rem, 2rem + 2vw, 3.6rem)/1 var(--script); color: var(--ink); --write-delay: 0.9s; width: max-content; }
.about__links { margin-top: 28px; display: flex; gap: 24px; flex-wrap: wrap; font: 500 12px var(--sans); letter-spacing: 0.22em; text-transform: uppercase; }

/* ------------------------------------------------------------------ band */
.band { background: var(--ink); color: var(--paper); overflow: hidden; padding-block: clamp(20px, 2.4vw, 32px); font: italic 400 clamp(1.6rem, 1.1rem + 2vw, 3rem)/1 var(--serif); }
.band__track { display: flex; align-items: center; width: max-content; animation: band 70s linear infinite; }
.band__track span { white-space: nowrap; padding-inline: clamp(22px, 3vw, 48px); }
.band__mark { height: 1.05em; width: auto; flex: none; color: var(--paper); opacity: 0.8; }
@keyframes band { to { transform: translateX(-50%); } }

/* --------------------------------------------------------------- contact */
.contact { background: var(--white); border-bottom: 1px solid var(--line); }
.contact__head { text-align: center; max-width: 820px; margin: 0 auto; }
.contact__head .h2 { margin-top: 16px; }
.contact__lede { margin-top: 20px; font: italic 400 clamp(1.15rem, 1rem + 0.5vw, 1.45rem)/1.5 var(--serif); color: var(--ink-2); }
.form { margin: clamp(40px, 5vw, 70px) auto 0; max-width: 860px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px 32px; }
.field { position: relative; display: grid; gap: 6px; }
.field--full { grid-column: 1 / -1; }
.field label, .chips legend { font: 500 10.5px var(--sans); letter-spacing: 0.26em; text-transform: uppercase; color: var(--ink-3); }
.field input, .field textarea {
  font: 400 1.2rem/1.4 var(--serif); color: var(--ink); background: transparent;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: 8px 0 10px; outline: none; width: 100%;
}
/* The ink line draws across under the field being written in. */
.field:not(.chips)::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--ink); transform: scaleX(0); transform-origin: left center; transition: transform 0.8s var(--ease); }
.field:not(.chips):focus-within::after { transform: scaleX(1); }
.field textarea { min-height: 130px; resize: vertical; }
.field ::placeholder { color: var(--ink-3); opacity: 1; font-style: italic; }
/* Session: a row of pills rather than a dropdown, so every kind of session
   is in view while someone decides. Real radio buttons underneath. */
.chips { border: 0; margin: 0; padding: 0; min-width: 0; }
.chips legend { padding: 0; margin-bottom: 14px; }
.chips__row { display: flex; flex-wrap: wrap; gap: 10px; }
.chip { position: relative; display: block; }
.chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.chip span { display: inline-flex; align-items: center; height: 44px; padding: 0 20px; border: 1px solid var(--line); border-radius: 999px; font: 400 1.12rem/1 var(--serif); color: var(--ink-2); transition: background 0.35s, color 0.35s, border-color 0.35s; pointer-events: none; }
.chip input:hover + span { border-color: var(--ink-3); color: var(--ink); }
.chip input:checked + span { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.chip input:focus-visible + span { outline: 1.5px solid var(--ink); outline-offset: 3px; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__foot { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 18px; margin-top: 8px; }
.btn--go { height: 56px; padding: 0 40px; }
.form__alt { font: 500 11.5px var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-2); }
.form__status { font: italic 400 1.1rem var(--serif); color: var(--ink-2); min-height: 1.4em; text-align: center; }
.form__status.is-error { color: #a33a2a; }
.btn[disabled] { opacity: 0.5; pointer-events: none; }

/* ---------------------------------------------------------------- footer */
.ft { position: relative; z-index: 2; background: var(--paper); padding: clamp(72px, 8vw, 120px) 0 26px; overflow: hidden; }
.ft__top { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(32px, 7vw, 140px); align-items: start; }
.ft__mono { height: clamp(78px, 8vw, 116px); width: auto; color: var(--ink); overflow: visible; }
.ft__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.ft__cols ul { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 6px; }
.ft__cols a, .ft__area { font: 400 1.2rem/1.35 var(--serif); }
.ft__area { margin-top: 16px; color: var(--ink-2); max-width: 18ch; }
/* Her name, as wide as the page. site.js fits it exactly; the vw size is
   the fallback. */
.ft__word { margin-top: clamp(56px, 8vw, 120px); padding-inline: var(--gutter); font: 400 17vw/0.86 var(--serif); letter-spacing: -0.025em; white-space: nowrap; text-align: center; overflow: hidden; padding-bottom: 0.1em; }
.ft__fit { display: inline-block; }
.ft__fit span { display: inline-block; }
html.js .ft__word[data-inview] .ft__fit span { transform: translateY(105%); transition: transform 1.3s var(--ease); transition-delay: calc(var(--li) * 45ms); }
html.js .ft__word[data-inview].is-in .ft__fit span { transform: none; }
.ft__small { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); display: flex; gap: 18px; justify-content: space-between; flex-wrap: wrap; font: 400 12px var(--sans); color: var(--ink-3); letter-spacing: 0.06em; }
.ft__small a { color: var(--ink-2); }

/* -------------------------------------------------------------- lightbox */
.lb { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: var(--paper); color: var(--ink); }
.lb::backdrop { background: transparent; }
.lb[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; animation: lb-in 0.4s var(--ease); }
@keyframes lb-in { from { opacity: 0; } }
.lb__bar { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 18px var(--gutter); font: 500 11px var(--sans); letter-spacing: 0.22em; text-transform: uppercase; }
.lb__stage { display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; min-height: 0; overflow: hidden; padding: 0 var(--gutter); touch-action: pan-y; }
.lb__stage img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.lb__stage img[data-dir="next"] { animation: lb-next 0.7s var(--ease); }
.lb__stage img[data-dir="prev"] { animation: lb-prev 0.7s var(--ease); }
@keyframes lb-next { from { opacity: 0; transform: translateX(40px); } }
@keyframes lb-prev { from { opacity: 0; transform: translateX(-40px); } }
.lb button { font: inherit; letter-spacing: inherit; text-transform: inherit; padding: 8px 4px; }
.lb__nav { display: flex; gap: 24px; }
.lb__cap { font: italic 400 1.05rem var(--serif); letter-spacing: 0; text-transform: none; color: var(--ink-2); }
/* A photo opens out of its place in the grid and folds back into it. */
::view-transition-group(lb-photo) { animation-duration: 0.7s; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
::view-transition-old(lb-photo), ::view-transition-new(lb-photo) { animation: none; mix-blend-mode: normal; height: 100%; object-fit: cover; }

/* Simple pages */
.page { min-height: 100svh; display: grid; place-items: center; text-align: center; padding: 120px var(--gutter); }
.page .script { margin: 0 auto; width: max-content; font: 400 clamp(4rem, 3rem + 4vw, 7rem)/1.1 var(--script); color: var(--ink); }
html.js .page .write { animation: write 1.8s var(--ease-io) 0.3s both; transition: none; }
@keyframes write { from { clip-path: inset(-40% 100% -40% -8%); } to { clip-path: inset(-40% -12% -40% -8%); } }
.page p { margin-top: 18px; font: italic 400 1.3rem var(--serif); color: var(--ink-2); }
.page .btn { margin-top: 30px; }

/* Generic reveal */
html.js [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity 1s var(--ease), transform 1.2s var(--ease); transition-delay: var(--delay, 0s); }
html.js [data-reveal].is-in { opacity: 1; transform: none; }

/* ------------------------------------------------------------ in between */
@media (max-width: 1100px) and (min-width: 861px) {
  .chapters__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; }
  .toc__title { font-size: clamp(1.7rem, 1rem + 1.6vw, 2.4rem); }
}
/* A short laptop: the index has to fit in the height it has. */
@media (max-height: 820px) and (min-width: 861px) {
  .chapters__index { padding-block: 84px 24px; }
  .chapters__head .script { font-size: clamp(3rem, 2rem + 2.4vw, 4.2rem); }
  .toc__title { font-size: clamp(1.7rem, 0.9rem + 1.7vw, 2.5rem); }
  .toc__line { font-size: 1.15rem; }
}

/* ----------------------------------------------------------------- phone */
@media (max-width: 860px) {
  :root { --zoom-run: 140vh; --sheet: 80vh; }
  .nav { display: none; }
  .menu-btn { display: inline-block; }
  .brand__name { display: none; }
  .book { top: auto; right: auto; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); height: 50px; padding: 0 30px; transform: translateX(-50%); }
  html.scrolled .book { top: auto; }
  html.book-hidden .book { transform: translate(-50%, 24px); }
  .hero__corner { display: none; }
  .hero__cap { bottom: 22px; }

  .chapters__grid { display: block; }
  .chapters__index { position: static; height: auto; padding: 0; display: block; text-align: center; }
  .chapters__head { margin-bottom: 0; }
  .toc, .toc__count, .chapter__label { display: none; }
  .chapters__photos { gap: 84px; padding-block: 48px 0; }
  .chapter:nth-child(n) .chapter__media { width: 100%; margin-left: 0; }
  .chapter__text { display: block; margin-top: 26px; text-align: center; }

  .cols { display: block; columns: 2; column-gap: 10px; padding: 0; }
  .col { display: contents; }
  .shot { margin-bottom: 10px; break-inside: avoid; }

  .how__track::before, .how__rule { left: 5px; right: auto; top: 0; bottom: 0; width: 1px; height: auto; }
  .how__rule { transform-origin: center top; transform: scaleY(var(--line)); }
  .steps { grid-template-columns: 1fr; gap: 48px; }
  .step { padding: 0 0 0 40px; }
  .step__dot { top: 8px; }

  .about { grid-template-columns: 1fr; text-align: center; }
  .about__body p { margin-inline: auto; }
  .about__body .about__sign { margin-inline: auto; }
  .about__links { justify-content: center; }
  .form { grid-template-columns: 1fr; }
  .chips__row { justify-content: center; }
  .chips legend { text-align: center; width: 100%; }

  .ft__top { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .ft__cols { grid-template-columns: 1fr 1fr; width: 100%; }
  .ft__cols > div:last-child { grid-column: 1 / -1; }
  .ft__area { margin-inline: auto; }
  .ft__small { justify-content: center; padding-bottom: 70px; }
}

/* --------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Animations keep a hair of duration so their end state still lands.
     Transitions get none at all: a 1ms one on every property makes any
     script that sets a size and reads it back read the old one. */
  *, *::before, *::after { animation-duration: 0.001s !important; animation-delay: 0s !important; transition-duration: 0s !important; transition-delay: 0s !important; }
  html.js [data-draw] .pen { stroke-dashoffset: 0; animation: none; }
  html.js .hero [data-after], html.js [data-reveal] { opacity: 1; transform: none; animation: none; }
  html.js [data-develop]::before { display: none; }
  html.js [data-develop] img { transform: none; }
  html.js [data-reveal].split .w > span, html.js [data-reveal] .split .w > span, html.js .ft__word[data-inview] .ft__fit span { transform: none; }
  html.js .write, html.js .page .write { clip-path: none; animation: none; }
  .scroll-cue::after, .band__track { animation: none; }
  .menu { clip-path: none; }
}
