/* ============================================================
   Studio Halvorsenn
   1  tokens + reset          5  portal / projects
   2  navbar                  6  project cover
   3  hero wordmark           7  editorial
   4  hero photograph         8  sequence states
   ============================================================ */

/* --- 1. tokens + reset ------------------------------------------- */

:root {
  --paper: #f7f6f3;   /* the white the sequence opens on */
  --ink:   #141614;   /* wordmark and editorial text */
  --ink-2: #5c5f5b;   /* secondary text */
  --rule:  #d8d5cd;   /* hairlines */
  --bone:  #f2efe9;   /* off-white on the photographs */

  --sans: Raleway, "Helvetica Neue", Arial, sans-serif;
  --serif: Merriweather, Georgia, serif;

  --nav-x: clamp(1.4rem, 4vw, 3.6rem);
  --nav-y: clamp(1.3rem, 3vw, 2.3rem);
  --ed-x:  clamp(1.5rem, 6vw, 7rem);

  --ease: cubic-bezier(.22, .61, .36, 1);
}

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

html {
  background: var(--paper);
  scrollbar-width: none;          /* the scroll is the interface here, not a bar */
  -ms-overflow-style: none;
  /* no rubber-band: the whole site is fixed layers driven by scroll position,
     and overscroll makes them lurch on iOS */
  overscroll-behavior-y: none;
}
html::-webkit-scrollbar { width: 0; height: 0; display: none; }
html.is-locked { overflow: hidden; }

body {
  background: var(--paper);
  font-family: var(--serif);
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; }

/* the only in-flow elements: they exist purely to give the page height */
.track { width: 100%; pointer-events: none; }

/* --- 2. navbar ---------------------------------------------------- */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: var(--nav-y) var(--nav-x);
  font-family: var(--sans);
  /* a touch lighter than the hero wordmark, so the title stays the brighter of
     the two rather than competing with the chrome */
  color: rgba(255, 255, 255, .76);
}
/* the duck sits on the children so it composes with, rather than fights,
   the navbar's own transitioned fade-in at the end of the intro */
.nav > * { opacity: var(--nav-o, 1); }

/* the editorial is on paper, so the navbar inverts there */
.at-ed .nav { color: var(--ink); }

.nav a { color: inherit; text-decoration: none; text-transform: uppercase; }

.nav__logo {
  font-weight: 200;
  font-size: clamp(.82rem, 1.4vw, 1.02rem);
  letter-spacing: .32em;
  margin-right: -.32em;
}

/* --- the navbar is the wordmark and the Menu button, nothing else --- */

.menu-btn {
  display: flex;
  align-items: center;
  gap: .7em;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(.6rem, .82vw, .72rem);
  letter-spacing: .3em;
  text-transform: uppercase;
  color: inherit;
  opacity: .85;
  transition: opacity 400ms var(--ease);
}
.menu-btn:hover { opacity: 1; }
.menu-btn__bars { display: block; width: 1.5rem; }
.menu-btn__bars i {
  display: block;
  height: 1px;
  background: currentColor;
  transition: transform 500ms var(--ease);
}
.menu-btn__bars i + i { margin-top: 5px; width: 65%; margin-left: auto; }
.menu-btn:hover .menu-btn__bars i + i { transform: translateX(-35%); }
.menu-btn__label { margin-right: -.3em; }

@media (max-width: 560px) {
  .nav__logo { font-size: .72rem; letter-spacing: .22em; margin-right: -.22em; }
  .menu-btn { font-size: .56rem; letter-spacing: .2em; }
  .menu-btn__bars { width: 1.2rem; }
}

/* --- 3. hero stage + wordmark ------------------------------------- */

/* The stage itself never scales. Scaling it would rasterise the whole thing
   once and stretch that texture 40x during the dive; instead the title and the
   photograph are scaled separately, each at its own rate. */
.hero {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  background: var(--paper);
}

.hero__word {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;

  display: none;                 /* JS turns this on; no-JS lands on the end state */
  white-space: nowrap;
  pointer-events: none;
  user-select: none;

  font-family: var(--sans);
  font-weight: 800;
  font-size: clamp(2.4rem, 11.2vw, 12.5rem);
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* each letter is a window; the glyph rises into it from underneath */
.hero__word .ltr,
.hero__word .o {
  display: inline-block;
  vertical-align: top;
  overflow: hidden;
  will-change: transform;
}
.hero__word.is-open .ltr,
.hero__word.is-open .o { overflow: visible; }

.hero__word .ltr__in { display: block; }

.hero__word .o {
  position: relative;
  text-align: left;
  letter-spacing: 0;   /* keep the O's box == its advance so the halves clip cleanly */
}

/* invisible sizer holds the O's advance width in the flow. it is never
   transformed, so it stays a reliable reference for measuring the counter. */
.hero__word .o__size { visibility: hidden; }

/* the rise lives here, one level below the measured box */
.hero__word .o__in {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

/* two stacked copies of the O, each clipped to one half, so the
   photograph can crack the letter open down the middle */
.hero__word .o__half {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
}
.hero__word .o__half--l { clip-path: inset(0 50% 0 0); }
.hero__word .o__half--r { clip-path: inset(0 0 0 50%); }

.hero__word .ltr__in,
.hero__word .o__in { transform: translate3d(0, 106%, 0); }

.is-playing .hero__word .ltr__in,
.is-playing .hero__word .o__in {
  animation: letter-rise 880ms cubic-bezier(.19, .9, .26, 1) both;
  animation-delay: calc(var(--i) * var(--stagger, 38ms));
}

@keyframes letter-rise { to { transform: translate3d(0, 0, 0); } }

/* --- 4. hero photograph + title ----------------------------------- */

.hero__reveal {
  position: absolute;
  inset: 0;
  z-index: 3;
  will-change: clip-path, transform;
  contain: layout paint;
}

.hero__img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  /* the crop that lands the roof apex just under the wordmark */
  background: #2a2724 url("Images/Hero.jpg") 50% 59.5% / cover no-repeat;
  will-change: width, height, left, top;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 88% at 50% 52%, rgba(10, 12, 11, 0) 34%, rgba(10, 12, 11, .34) 100%),
    linear-gradient(to bottom, rgba(10, 12, 11, .3) 0%, rgba(10, 12, 11, 0) 26%);
}

/* full-bleed box so transform-origin can be given in plain viewport pixels —
   the dive needs to scale about the counter of the O, not the element centre */
.hero__title {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 15vh;         /* sits above centre, giving the building room */
  white-space: nowrap;
  pointer-events: none;
  /* no will-change: the dive scales this ~45x, and a promoted layer would be
     rasterised once and stretched. unpromoted, Chrome re-rasterises the type. */

  font-family: var(--sans);
  font-weight: 500;
  font-size: clamp(1.5rem, 6.4vw, 5.6rem);
  line-height: 1;
  letter-spacing: .21em;
  padding-left: .21em;          /* balance the trailing tracking */
  text-transform: uppercase;
  color: var(--bone);
  text-shadow: 0 1px 40px rgba(8, 10, 9, .28);
}

/* --- 5. portal + projects ----------------------------------------- */

.portal {
  position: fixed;
  inset: 0;
  z-index: 5;
  opacity: 0;
  will-change: clip-path;
}
/* deliberately unpromoted and unscaled: this is what you look at *through* the
   counter, and any transform on it would resample the photographs and the type */
.portal__inner { position: absolute; inset: 0; }

.projects {
  position: absolute;
  inset: 0;
  background: #0e100f;
}

/* every edge is written by site.js so the three can be columns on a desktop
   and stacked rows on a phone without changing the push logic */
.panel {
  position: absolute;
  overflow: hidden;
  cursor: pointer;
  display: block;
  text-align: center;
  will-change: left, top, width, height;
  transition: left 780ms var(--ease), top 780ms var(--ease),
              width 780ms var(--ease), height 780ms var(--ease);
}
.panel + .panel { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .22); }
.projects--stacked .panel + .panel { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22); }
.is-pushing .panel + .panel { box-shadow: none; }
/* the push drives the edges per frame, so the hover easing must stand down */
.is-pushing .panel { transition: none; }

.panel__img {
  position: absolute;
  background-position: 50% 50%;
  background-size: cover;
  transition: left 780ms var(--ease), top 780ms var(--ease);
}
.is-pushing .panel__img { transition: none; }

.panel__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(8, 10, 9, .42) 0%, rgba(8, 10, 9, .12) 42%, rgba(8, 10, 9, .55) 100%);
  transition: opacity 700ms var(--ease);
}
.panel:hover .panel__veil { opacity: .72; }
/* rows are shallow, so the label sits in the bright middle of the picture */
.projects--stacked .panel__veil {
  background: linear-gradient(to bottom,
    rgba(8, 10, 9, .5) 0%, rgba(8, 10, 9, .38) 50%, rgba(8, 10, 9, .58) 100%);
}

.panel__label {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .9em;
  padding: 0 1.2rem;
  color: var(--bone);
  opacity: var(--label, 1);
}

.panel__name {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1rem, 2.05vw, 1.9rem);
  letter-spacing: .17em;
  margin-right: -.17em;
  text-transform: uppercase;
  line-height: 1.25;
  text-shadow: 0 1px 30px rgba(8, 10, 9, .4);
  transition: letter-spacing 800ms var(--ease);
}
.panel:hover .panel__name { letter-spacing: .24em; margin-right: -.24em; }

.panel__place {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.56rem, .82vw, .74rem);
  letter-spacing: .2em;
  margin-right: -.2em;
  text-transform: uppercase;
  opacity: .72;
}

/* stacked rows are full width, so the names get their proper size back */
.projects--stacked .panel__name { font-size: clamp(1.05rem, 5.6vw, 1.6rem); }
.projects--stacked .panel__place { font-size: clamp(.6rem, 2.6vw, .72rem); }

/* --- 6. project cover --------------------------------------------- */

.proj__stage {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
}
.proj__rail {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: flex-start;
  width: 200vw;
  will-change: transform;
}

.cover {
  position: relative;
  flex: 0 0 100vw;
  width: 100vw;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.cover__img {
  position: absolute;
  inset: 0;
  background-position: 50% 50%;
  background-size: cover;
}
.cover__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(8, 10, 9, .42) 0%, rgba(8, 10, 9, .12) 42%, rgba(8, 10, 9, .55) 100%);
}
.cover__label {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .9em;
  padding: 0 1.2rem;
  text-align: center;
  color: var(--bone);
}
.cover__name {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1rem, 2.05vw, 1.9rem);
  letter-spacing: .17em;
  margin-right: -.17em;
  text-transform: uppercase;
  line-height: 1.25;
  text-shadow: 0 1px 30px rgba(8, 10, 9, .4);
}
.cover__place {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.56rem, .82vw, .74rem);
  letter-spacing: .2em;
  margin-right: -.2em;
  text-transform: uppercase;
  opacity: .72;
}

.cover__cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.6rem, 4vh, 3rem);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: .8em;
  font-family: var(--sans);
  font-size: clamp(.54rem, .74vw, .66rem);
  font-weight: 300;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--bone);
  opacity: 0;
  transition: opacity 900ms var(--ease) 700ms;
}
.cover__cue span { width: 1px; height: 2.6em; background: currentColor; }
.at-cover .cover__cue { opacity: .8; }
.at-ed .cover__cue { opacity: 0; transition-delay: 0ms; }

/* --- 7. editorial -------------------------------------------------- */

/* the editorial panel of the rail: article on paper, then the footer */
.edwrap {
  flex: 0 0 100vw;
  width: 100vw;
  background: var(--paper);
}

.ed {
  width: 100%;
  min-height: 100vh;
  padding: clamp(6rem, 15vh, 11rem) var(--ed-x) clamp(4rem, 10vh, 8rem);
}

.ed__eyebrow {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .68rem);
  letter-spacing: .34em;
  margin-right: -.34em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.ed__eyebrow span { opacity: .45; margin: 0 .4em; }

.ed__title {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 6vw, 6rem);
  margin-top: clamp(2rem, 5vh, 3.4rem);
}
.ed__ta, .ed__tb {
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.9rem, 4.4vw, 4.2rem);
  line-height: 1.06;
  letter-spacing: -.005em;
}
.ed__tb { text-align: right; align-self: end; }

.ed__credit {
  margin-top: clamp(1.4rem, 3vh, 2.2rem);
  max-width: 34ch;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.66rem, .82vw, .76rem);
  line-height: 1.9;
  letter-spacing: .04em;
  color: var(--ink-2);
}

/* segmented plates — staggered, sized by their own aspect ratio */
.plates {
  display: flex;
  align-items: flex-start;
  gap: clamp(1rem, 2.6vw, 2.8rem);
  margin-top: clamp(3.5rem, 11vh, 8rem);
}
.plate { flex: 1 1 0; min-width: 0; }
.plate:nth-child(1) { flex-grow: 1.12; margin-top: 0; }
.plate:nth-child(2) { flex-grow: .82; margin-top: clamp(2rem, 8vh, 6rem); }
.plate:nth-child(3) { flex-grow: 1.08; margin-top: clamp(.8rem, 3vh, 2.2rem); }
.plate:nth-child(4) { flex-grow: .78; margin-top: clamp(2.6rem, 10vh, 7.5rem); }

.plate__n {
  display: block;
  margin-bottom: .9em;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .68rem);
  letter-spacing: .3em;
  color: var(--ink-2);
}
.plate__frame {
  display: block;
  width: 100%;
  overflow: hidden;
  background: #e6e3dc;
}
.plate__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1200ms var(--ease);
}
.plate:hover .plate__frame img { transform: scale(1.035); }
.plate figcaption {
  margin-top: 1.1em;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.62rem, .76vw, .72rem);
  line-height: 1.8;
  letter-spacing: .03em;
  color: var(--ink-2);
}

.ed__body { margin-top: clamp(4.5rem, 14vh, 10rem); }

.ed__lead {
  max-width: 30ch;
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1.15rem, 2.1vw, 2rem);
  line-height: 1.42;
  letter-spacing: -.002em;
}

.ed__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 5vw, 5rem);
  margin-top: clamp(2.4rem, 7vh, 4.5rem);
  margin-left: auto;
  width: min(100%, 62ch);
}
.ed__cols p {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.76rem, .92vw, .88rem);
  line-height: 2.05;
  letter-spacing: .012em;
  color: #2f322e;
}

.ed__facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.2rem, 3vw, 3rem);
  margin-top: clamp(4rem, 12vh, 8rem);
  padding-top: clamp(1.6rem, 4vh, 2.6rem);
  border-top: 1px solid var(--rule);
}
.ed__facts dt {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.54rem, .7vw, .64rem);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.ed__facts dd {
  margin-top: .9em;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.74rem, .9vw, .86rem);
  line-height: 1.8;
}

.ed__foot {
  margin-top: clamp(4rem, 12vh, 8rem);
  padding-top: clamp(1.6rem, 4vh, 2.6rem);
  border-top: 1px solid var(--rule);
}
.ed__back {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.58rem, .76vw, .7rem);
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  padding-bottom: .5em;
  border-bottom: 1px solid var(--rule);
  transition: border-color 400ms var(--ease);
}
.ed__back:hover { border-color: var(--ink); }

@media (max-width: 860px) {
  .ed__title { grid-template-columns: 1fr; gap: .4rem; }
  .ed__tb { text-align: left; }
  .plates { flex-wrap: wrap; gap: clamp(1rem, 4vw, 2rem) }
  .plate { flex: 0 0 calc(50% - 1rem); }
  .plate:nth-child(n) { margin-top: 0; }
  .plate:nth-child(2), .plate:nth-child(4) { margin-top: clamp(1.5rem, 6vh, 4rem); }
  .ed__cols { grid-template-columns: 1fr; }
  .ed__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2rem; }
}

/* --- 8. about (rides up over the projects) ------------------------- */

.overlay {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  z-index: 6;
  transform: translate3d(0, 100vh, 0);
  will-change: transform;
}

/* deliberately the dark room of the site: the project pages are on paper,
   this one is not, and the navbar stays white the whole way down */
.ab {
  background: #101211;
  color: var(--bone);
  padding: clamp(5rem, 13vh, 9rem) var(--ed-x) clamp(5rem, 13vh, 9rem);
}

.ab__eyebrow {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .68rem);
  letter-spacing: .34em;
  margin-right: -.34em;
  text-transform: uppercase;
  color: #8d918b;
}
.ab__eyebrow span { opacity: .45; margin: 0 .4em; }

.ab__shout {
  margin-top: clamp(2rem, 5vh, 3.4rem);
  max-width: 21ch;
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.8rem, 5.4vw, 5rem);
  line-height: 1.04;
  letter-spacing: -.012em;
}
.ab__shout em { font-style: normal; opacity: .42; }

/* the funky bit: a photograph set inline in the sentence */
.ab__chip {
  display: inline-block;
  vertical-align: baseline;
  width: 1.55em;
  height: .78em;
  margin: 0 .1em -.02em;
  background-position: 50% 44%;
  background-size: cover;
  transform: rotate(-2.5deg);
}

.ab__say {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 5vw, 5rem);
  margin-top: clamp(2.6rem, 8vh, 5rem);
  margin-left: auto;
  width: min(100%, 64ch);
}
.ab__say p {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.76rem, .92vw, .88rem);
  line-height: 2.05;
  letter-spacing: .012em;
  color: #c4c7c2;
}

/* two plates that refuse to line up */
.ab__stack {
  position: relative;
  margin-top: clamp(4rem, 13vh, 9rem);
  padding-bottom: clamp(3rem, 12vh, 8rem);
}
.ab__fig { margin: 0; }
.ab__fig img { width: 100%; height: 100%; object-fit: cover; }
.ab__fig figcaption {
  margin-top: 1.1em;
  max-width: 26ch;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.62rem, .76vw, .72rem);
  line-height: 1.8;
  color: #8d918b;
}
.ab__fig--a { width: 58%; transform: rotate(-1.4deg); }
.ab__fig--b {
  position: absolute;
  right: 0;
  top: clamp(4rem, 16vh, 11rem);
  width: 38%;
  transform: rotate(1.8deg);
}
.ab__fig--b figcaption { margin-left: auto; text-align: right; }

.ab__nums {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.2rem, 4vw, 4rem);
  margin-top: clamp(3rem, 9vh, 6rem);
  padding-top: clamp(1.6rem, 4vh, 2.6rem);
  border-top: 1px solid #2b2e2c;
  list-style: none;
}
.ab__n {
  display: block;
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(2.6rem, 7.5vw, 7rem);
  line-height: .9;
  letter-spacing: -.03em;
}
.ab__nl {
  display: block;
  margin-top: .9em;
  max-width: 18ch;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.64rem, .78vw, .74rem);
  line-height: 1.8;
  color: #8d918b;
}
/* the dogs get a credit every time the eleven do */
.ab__dogs {
  display: block;
  margin-top: .5em;
  font-family: var(--sans);
  font-weight: 400;
  font-size: .52rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #6d716c;
}

/* --- pictures we like --- */

.ab__gallery { margin-top: clamp(3.5rem, 11vh, 7rem); }
.ab__gh {
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.3rem, 3vw, 2.6rem);
  letter-spacing: -.005em;
}
.ab__gnote {
  margin-top: .9em;
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(.66rem, .8vw, .76rem);
  color: #8d918b;
}
.ab__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.8rem, 2vw, 1.8rem);
  margin-top: clamp(1.8rem, 5vh, 3rem);
}
.ab__grid figure { margin: 0; overflow: hidden; }
.ab__grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1200ms var(--ease);
}
.ab__grid figure:hover img { transform: scale(1.04); }

.ab__likes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 5vw, 5rem);
  margin-top: clamp(3.5rem, 11vh, 7rem);
}
.ab__likes h3 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.54rem, .7vw, .64rem);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: #8d918b;
}
.ab__likes ul { margin-top: 1.6em; list-style: none; }
.ab__likes li {
  padding: .85em 0;
  border-bottom: 1px solid #232625;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.74rem, .9vw, .86rem);
  line-height: 1.7;
}

.ab__sign {
  margin-top: clamp(3.5rem, 11vh, 7rem);
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.1rem, 2.4vw, 2.1rem);
  line-height: 1.4;
  max-width: 24ch;
}
.ab__sign span {
  display: block;
  margin-top: 1.2em;
  font-family: var(--serif);
  font-size: clamp(.66rem, .8vw, .76rem);
  letter-spacing: .06em;
  color: #8d918b;
}

@media (max-width: 860px) {
  .ab__say { grid-template-columns: 1fr; }
  .ab__stack { padding-bottom: 0; }
  .ab__fig--a { width: 78%; }
  .ab__fig--b { position: static; width: 78%; margin: clamp(2rem, 6vh, 4rem) 0 0 auto; }
  .ab__nums { grid-template-columns: 1fr; row-gap: 2.4rem; }
  .ab__likes { grid-template-columns: 1fr; row-gap: 2.6rem; }
  .ab__grid { grid-template-columns: 1fr; }
}

/* --- 9. footer ----------------------------------------------------- */

.foot {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  background: #1c4f86 url("Images/footer.jpg") 50% 50% / cover no-repeat;
  color: #fff;
  overflow: hidden;
}
/* --sky is the measured roofline, set by site.js from the photograph's own
   geometry, so the links land just above the building at any viewport. */
.foot__inner {
  position: relative;
  height: var(--sky, 68%);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;      /* the whole block hangs off the roofline */
  gap: clamp(.9rem, 2.2vh, 1.7rem);
  padding: clamp(4rem, 9vh, 7rem) var(--ed-x) clamp(1.2rem, 3vh, 2.4rem);
}

.foot__eyebrow {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .68rem);
  letter-spacing: .34em;
  margin-right: -.34em;
  text-transform: uppercase;
  opacity: .8;
}

.foot__word {
  margin-top: clamp(.6rem, 1.6vw, 1.6rem);
  font-family: var(--sans);
  font-weight: 300;
  /* capped by height as well as width — two lines this big eat a short screen */
  font-size: clamp(2rem, min(12.4vw, 13vh), 12rem);
  line-height: .88;
  letter-spacing: -.022em;
  text-transform: uppercase;
}
.foot__word span { display: block; }
.foot__word span:first-child { font-weight: 200; opacity: .72; }

.foot__phone {
  display: inline-block;
  margin-top: clamp(.9rem, 1.6vw, 1.7rem);
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(.86rem, 1.7vw, 1.5rem);
  letter-spacing: .14em;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .35);
  padding-bottom: .18em;
  transition: border-color 400ms var(--ease);
}
.foot__phone:hover { border-bottom-color: #fff; }

.foot__nav {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.2rem, 4vw, 4rem);
  max-width: 62rem;
}
.foot__col { display: flex; flex-direction: column; align-items: flex-start; }
.foot__col h3 {
  margin-bottom: 1.3em;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.52rem, .68vw, .62rem);
  letter-spacing: .28em;
  text-transform: uppercase;
  opacity: .62;
}
.foot__col a {
  padding: .34em 0;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.7rem, .86vw, .82rem);
  color: inherit;
  text-decoration: none;
  opacity: .88;
  transition: opacity 300ms var(--ease);
}
.foot__col a:hover { opacity: 1; text-decoration: underline; text-underline-offset: .35em; }
.foot__col--note p {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.7rem, .86vw, .82rem);
  line-height: 1.9;
  opacity: .8;
}
.foot__col--note p + p { margin-top: .9em; }
.foot__oops {
  margin-top: 1.1em;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(.66rem, .8vw, .76rem);
  opacity: .5;
  transition: opacity 300ms var(--ease);
}
.foot__oops:hover { opacity: .95; }

@media (max-width: 700px) {
  /* on a phone the sky band is too shallow to space things out into — fall
     back to flowing from the top and let the block find its own height */
  .foot__inner {
    height: auto;
    display: block;
    padding-top: clamp(4.5rem, 10vh, 7rem);
  }
  .foot__word { font-size: clamp(2rem, 13.5vw, 4rem); }
  .foot__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2rem; margin-top: 2.2rem; }
  .foot__col--note { grid-column: 1 / -1; }
}

/* --- 9b. flat routes: contact + 404 -------------------------------- */

.route--flat { position: fixed; inset: 0; z-index: 2; }

/* while pulling back out of the O, the page being left is the thing seen inside
   the letter, so it has to sit above the portal instead of behind it */
.is-reversing .portal,
.is-reversing .overlay { display: none; }
.is-reversing .route--flat,
.is-reversing .proj__stage { z-index: 5; }
.route--flat[hidden] { display: none; }
html.is-flat, html.is-flat body { overflow: hidden; }

.film { position: absolute; inset: 0; overflow: hidden; background: #0d1a2b; }
.film__v {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.film__v--m { display: none; }
@media (max-width: 820px) {
  .film__v--d { display: none; }
  .film__v--m { display: block; }
}
/* mirrored — which moves the open sky to the left, and the form with it */
.film__v--flip { transform: scaleX(-1); }

/* --- contact --- */

/* The desktop clip has the tower on the left and open sky on the right, so the
   panel is pinned right. The phone clip is a slot of sky between two towers,
   widest low down, so there the panel drops to the bottom and centres. */
.cx {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;     /* the panel stays put; only the clip is flipped */
  padding: clamp(4.5rem, 11vh, 8rem) clamp(1.5rem, 5vw, 5rem) clamp(2rem, 5vh, 4rem);
}
.cx__panel {
  width: min(30rem, 46%);
  color: #fff;
  text-shadow: 0 1px 26px rgba(6, 22, 40, .45);
}

.cx__eyebrow {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .68rem);
  letter-spacing: .34em;
  margin-right: -.34em;
  text-transform: uppercase;
  opacity: .85;
}
.cx__title {
  margin-top: .7em;
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.7rem, 3.4vw, 3rem);
  line-height: 1.08;
  letter-spacing: -.01em;
}

.cx__form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(.9rem, 2vw, 1.6rem);
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
}
.cx__f { display: block; }
.cx__f--wide { grid-column: 1 / -1; }
.cx__f span {
  display: block;
  margin-bottom: .6em;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.5rem, .66vw, .6rem);
  letter-spacing: .26em;
  text-transform: uppercase;
  opacity: .8;
}
.cx__f input,
.cx__f textarea {
  width: 100%;
  padding: .45em 0;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.78rem, .92vw, .88rem);
  color: #fff;
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .45);
  border-radius: 0;
  outline: none;
  resize: none;
  transition: border-color 300ms var(--ease);
}
.cx__f input:focus,
.cx__f textarea:focus { border-bottom-color: #fff; }
.cx__f input:-webkit-autofill { -webkit-text-fill-color: #fff; }

.cx__send {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: .4rem;
  padding: .8em 1.9em;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .66rem);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .55);
  transition: background 400ms var(--ease), border-color 400ms var(--ease);
}
.cx__send:hover { background: rgba(255, 255, 255, .14); border-color: #fff; }

.cx__note {
  min-height: 1.2em;
  margin-top: 1.1rem;
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(.68rem, .82vw, .78rem);
  line-height: 1.7;
  opacity: 0;
  transition: opacity 400ms var(--ease);
}
.cx__note.is-on { opacity: .92; }

.cx__alt {
  margin-top: clamp(1.4rem, 4vh, 2.4rem);
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.68rem, .82vw, .78rem);
  line-height: 2;
  opacity: .82;
}
.cx__alt a { color: inherit; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .4); }

/* The phone clip is a slot of sky between two towers that only opens up low
   down, so the panel is compressed and narrowed to stay inside it. */
@media (max-width: 820px) {
  .cx {
    align-items: flex-end;
    justify-content: center;
    padding: 0 1.25rem clamp(.9rem, 2.5vh, 1.8rem);
  }
  .cx__panel { width: 100%; max-width: 17rem; }
  .cx__eyebrow { font-size: .52rem; letter-spacing: .28em; margin-right: -.28em; }
  .cx__title { margin-top: .5em; font-size: clamp(1.2rem, 5.4vw, 1.6rem); }
  .cx__form { grid-template-columns: 1fr; gap: .5rem; margin-top: .95rem; }
  .cx__f span { margin-bottom: .3em; font-size: .46rem; letter-spacing: .22em; }
  .cx__f input, .cx__f textarea { padding: .28em 0; font-size: .78rem; }
  .cx__f textarea { height: 2.6em; }
  .cx__send { margin-top: .15rem; padding: .62em 1.4em; font-size: .52rem; letter-spacing: .22em; }
  .cx__note { margin-top: .7rem; font-size: .66rem; }
  .cx__alt { margin-top: .8rem; font-size: .66rem; line-height: 1.7; }
}

/* --- 404 --- */

.nf {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: .9rem;
  padding: clamp(4.5rem, 11vh, 8rem) clamp(1.5rem, 6vw, 7rem);
  color: #fff;
  text-shadow: 0 1px 30px rgba(0, 0, 0, .55);
}
.nf__code {
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(3.5rem, 13vw, 11rem);
  line-height: .86;
  letter-spacing: -.03em;
  opacity: .92;
}
.nf__title {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1.4rem, 3.6vw, 3rem);
  letter-spacing: -.005em;
}
.nf__body {
  max-width: 34ch;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.76rem, .92vw, .88rem);
  line-height: 1.95;
  opacity: .88;
}
.nf__links { display: flex; flex-wrap: wrap; gap: 1.4rem; margin-top: 1rem; }
.nf__links button {
  padding-bottom: .45em;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(.56rem, .74vw, .66rem);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, .45);
  transition: border-color 400ms var(--ease);
}
.nf__links button:hover { border-bottom-color: #fff; }

/* --- 9c. cursor ----------------------------------------------------- */

/* A dot that trails the pointer, inverting whatever it happens to be over. */
.dot {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 9000;
  width: 11px;
  height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: #fff;
  mix-blend-mode: difference;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: opacity 260ms var(--ease), width 320ms var(--ease),
              height 320ms var(--ease), margin 320ms var(--ease);
}
.dot.is-on { opacity: 1; }
.dot.is-over {
  width: 38px; height: 38px; margin: -19px 0 0 -19px;
  background: rgba(255, 255, 255, .82);
}
.dot.is-down { width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; }

/* the dot replaces the arrow, but text fields keep their caret */
html.has-dot,
html.has-dot a,
html.has-dot button,
html.has-dot .panel { cursor: none; }
html.has-dot input,
html.has-dot textarea { cursor: text; }

@media (hover: none), (pointer: coarse) {
  .dot { display: none; }
  html.has-dot, html.has-dot a, html.has-dot button, html.has-dot .panel { cursor: auto; }
}

/* --- 9d. arriving at the 404 --------------------------------------- */

/* the page you were on drops away while the sky rises over it on a slant */
.is-falling { animation: nf-fall 780ms cubic-bezier(.42, 0, .7, 1) both; }
@keyframes nf-fall {
  to { transform: translate3d(0, 7vh, 0); opacity: 0; }
}

/* above the page it is replacing, which is still on screen falling away */
#notfound { z-index: 3; }
#notfound.is-entering { animation: nf-rise 1000ms cubic-bezier(.16, 1, .3, 1) both; }
@keyframes nf-rise {
  from { clip-path: polygon(0 134%, 100% 118%, 100% 150%, 0 150%); }
  to   { clip-path: polygon(0 0%, 100% -18%, 100% 150%, 0 150%); }
}

#notfound.is-entering .nf > * {
  animation: nf-line 620ms cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: calc(440ms + var(--i, 0) * 95ms);
}
@keyframes nf-line {
  from { clip-path: inset(105% 0 0 0); transform: translate3d(0, .3em, 0); }
  to   { clip-path: inset(0 0 0 0); transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .is-falling, #notfound.is-entering,
  #notfound.is-entering .nf > * { animation-duration: 1ms; animation-delay: 0ms; }
  .dot { transition: none; }
}

/* --- 10. menu overlay ---------------------------------------------- */

.menu {
  position: fixed;
  inset: 0;
  z-index: 200;
  /* the angled leading edge: the bottom of the quad is slanted and sweeps
     down across the viewport, so the black wipes on a diagonal */
  clip-path: polygon(0 -40%, 100% -40%, 100% -16%, 0 0%);
}
.menu[hidden] { display: none; }

.menu__panel {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 50% 50%;
  background: #0a0a0a;
  transform-origin: 50% 0;
  transform: rotate(-4deg) skewY(2.2deg) scale(1.16);
}

.menu__media { position: relative; overflow: hidden; }
.menu__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: rotate(3.4deg) scale(1.22);
}

.menu__nav {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(2rem, 6vh, 4rem);
  padding: clamp(3rem, 6vh, 5rem) clamp(2rem, 5vw, 5rem) clamp(3rem, 6vh, 5rem) clamp(2.5rem, 7vw, 7rem);
  overflow-y: auto;
}

.menu__list { list-style: none; }
.menu__row { overflow: hidden; }
.menu__row + .menu__row { margin-top: clamp(.15rem, .8vh, .5rem); }

.menu__link,
.menu__label {
  display: block;
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(2rem, 3.9vw, 3.5rem);   /* ~56px at 1440 */
  line-height: 1.16;
  letter-spacing: -.01em;
  color: #fff;
  text-decoration: none;
}
.menu__link { transition: opacity 350ms var(--ease); }
.menu__link:hover,
.menu__link:focus-visible { opacity: .55; }

.menu__label { color: #6f716f; cursor: default; }

.menu__sub { list-style: none; margin: .5em 0 .3em; padding-left: clamp(1rem, 2.4vw, 2.2rem); }
.menu__sub li { overflow: hidden; }
.menu__sublink {
  display: block;
  padding: .18em 0;
  font-family: var(--sans);
  font-weight: 200;
  font-size: clamp(1.15rem, 2.1vw, 1.875rem);   /* ~30px at 1440 */
  line-height: 1.3;
  color: #e8e8e6;
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: 0;
  text-align: left;
  transition: opacity 350ms var(--ease);
}
.menu__sublink:hover,
.menu__sublink:focus-visible { opacity: .55; }

.menu__foot {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 2.4vw, 2.2rem);
  padding-top: clamp(1.2rem, 3vh, 2rem);
  border-top: 1px solid #262726;
}
.menu__foot a {
  overflow: hidden;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(.66rem, .8vw, .76rem);
  color: #858784;
  text-decoration: none;
  transition: color 350ms var(--ease);
}
.menu__foot a:hover { color: #d8d9d6; }

.menu__close {
  position: absolute;
  top: var(--nav-y);
  right: var(--nav-x);
  z-index: 2;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(.6rem, .82vw, .72rem);
  letter-spacing: .3em;
  margin-right: -.3em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0;
  text-shadow: 0 1px 22px rgba(0, 0, 0, .7);   /* it sits over the photo on phones */
}

@media (max-width: 820px) {
  .menu__panel { grid-template-columns: 1fr; }
  .menu__media { height: 32vh; }
  .menu__nav { justify-content: flex-start; padding-top: clamp(2rem, 5vh, 3rem); }
}

/* --- the open sequence --- */

.menu.is-open { animation: menu-sweep 1250ms cubic-bezier(.2, .92, .28, 1) both; }
.menu.is-open .menu__panel { animation: menu-land 1250ms cubic-bezier(.2, .92, .28, 1) both; }
.menu.is-open .menu__media img { animation: menu-media 1350ms cubic-bezier(.2, .92, .28, 1) both; }

.menu.is-open .menu__row,
.menu.is-open .menu__sub li {
  animation: menu-wipe 620ms cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: calc(620ms + var(--i, 0) * 90ms);
}
.menu.is-open .menu__foot a {
  animation: menu-wipe 420ms cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: calc(1240ms + var(--i, 0) * 55ms);
}
.menu.is-open .menu__close { animation: menu-fade 460ms var(--ease) 980ms both; }

@keyframes menu-sweep {
  from { clip-path: polygon(0 -40%, 100% -40%, 100% -16%, 0 0%); }
  to   { clip-path: polygon(0 -40%, 100% -40%, 100% 124%, 0 140%); }
}
@keyframes menu-land {
  from { transform: rotate(-4deg) skewY(2.2deg) scale(1.16); }
  to   { transform: rotate(0) skewY(0) scale(1); }
}
@keyframes menu-media {
  from { transform: rotate(3.4deg) scale(1.22); }
  to   { transform: rotate(0) scale(1); }
}
@keyframes menu-wipe {
  from { clip-path: inset(0 0 100% 0); transform: translate3d(0, .22em, 0); }
  to   { clip-path: inset(0 0 0 0); transform: none; }
}
@keyframes menu-fade { to { opacity: .85; } }

/* --- the close sequence, the same moves run backwards --- */

/* These must be *differently named* keyframes, not `direction: reverse` on the
   opening ones. Swapping is-open for is-closing leaves the animation-name list
   unchanged, so the browser keeps the finished animation rather than starting a
   new one — it simply filled with its end value and the menu snapped shut. */
.menu.is-closing { animation: menu-sweep-out 760ms cubic-bezier(.4, 0, .25, 1) both; }
.menu.is-closing .menu__panel { animation: menu-land-out 760ms cubic-bezier(.4, 0, .25, 1) both; }
.menu.is-closing .menu__media img { animation: menu-media-out 760ms cubic-bezier(.4, 0, .25, 1) both; }
.menu.is-closing .menu__row,
.menu.is-closing .menu__sub li,
.menu.is-closing .menu__foot a {
  animation: menu-wipe-out 260ms cubic-bezier(.4, 0, .7, 1) both;
  animation-delay: calc(var(--i, 0) * 26ms);
}
.menu.is-closing .menu__close { animation: menu-fade-out 200ms var(--ease) both; }

@keyframes menu-sweep-out {
  from { clip-path: polygon(0 -40%, 100% -40%, 100% 124%, 0 140%); }
  to   { clip-path: polygon(0 -40%, 100% -40%, 100% -16%, 0 0%); }
}
@keyframes menu-land-out {
  from { transform: rotate(0) skewY(0) scale(1); }
  to   { transform: rotate(-4deg) skewY(2.2deg) scale(1.16); }
}
@keyframes menu-media-out {
  from { transform: rotate(0) scale(1); }
  to   { transform: rotate(3.4deg) scale(1.22); }
}
@keyframes menu-wipe-out {
  from { clip-path: inset(0 0 0 0); transform: none; }
  to   { clip-path: inset(0 0 100% 0); transform: translate3d(0, .22em, 0); }
}
@keyframes menu-fade-out { from { opacity: .85; } to { opacity: 0; } }

/* --- leaving through a counter: the panel dollies into one letter's hole,
       and the destination is already waiting underneath --- */

.menu.is-zooming { clip-path: none; animation: none; }
.menu.is-zooming .menu__panel,
.menu.is-zooming .menu__media img,
.menu.is-zooming .menu__row,
.menu.is-zooming .menu__sub li,
.menu.is-zooming .menu__foot a,
.menu.is-zooming .menu__close { animation: none; }
.menu.is-zooming .menu__close,
.menu.is-zooming .menu__foot { opacity: 0; transition: opacity 200ms linear; }
/* deliberately NOT will-change: transform — promoting the panel would rasterise
   it once and stretch that texture, and the type has to stay crisp as it grows */
.menu.is-zooming .menu__panel { will-change: auto; }


@media (prefers-reduced-motion: reduce) {
  .menu.is-open,
  .menu.is-open .menu__panel,
  .menu.is-open .menu__media img,
  .menu.is-open .menu__row,
  .menu.is-open .menu__sub li,
  .menu.is-open .menu__foot a,
  .menu.is-open .menu__close { animation-duration: 1ms; animation-delay: 0ms; }
  .menu.is-closing,
  .menu.is-closing * { animation-duration: 1ms; animation-delay: 0ms; }
}

/* --- 11. sequence states ------------------------------------------ */

.nav, .hero__scrim { transition: opacity 1200ms var(--ease); }

/* the title's intro rise uses `translate`, not `transform` — `transform` is
   owned by the dive, and a transition on it would make the letter lag the
   hole cut through it */
.hero__title { transition: opacity 1200ms var(--ease), translate 1500ms var(--ease); }

.is-armed .nav,
.is-armed .hero__scrim,
.is-armed .hero__title { opacity: 0; }

.is-armed .hero__title { translate: 0 18px; }
.is-armed .nav { transition-delay: 320ms; }
.is-armed .hero__word { display: block; }

.is-revealed .nav,
.is-revealed .hero__scrim,
.is-revealed .hero__title { opacity: 1; }
.is-revealed .hero__title { translate: none; }

.is-done .hero__word { display: none; }
.is-done .hero__reveal { clip-path: none; will-change: auto; }
.is-done .hero__img { will-change: auto; }

/* once the dive lands, the hero is out of the way for good */
.at-projects .hero { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .nav, .hero__scrim, .hero__title,
  .panel__img, .panel__name, .panel__veil,
  .plate__frame img, .cover__cue { transition: none; }
  .hero__word { display: none !important; }
}
