/* The place carries it. The home is a dark room where the photographs play one at a time;
   the Gallery and About are pages of a book on paper, or on night when the visitor asks. */
:root {
  --night: #0a0d14;
  --night-ink: #e9edf3;
  --night-muted: #a3abb9;
  --margin: clamp(16px, 2.2vw, 32px);
  --bar-h: 76px;

  /* Degular, through Adobe Fonts (web project plh3hjz, Creative Cloud Photography plan) */
  --face: "degular-text", "Helvetica Neue", Arial, sans-serif;
  --display: "degular-display", "degular-text", "Helvetica Neue", Arial, sans-serif;
  --step-small: clamp(0.8125rem, 0.79rem + 0.1vw, 0.875rem);
  --step-body: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  --step-lead: clamp(1.25rem, 1.1rem + 0.7vw, 1.625rem);
  --step-head: clamp(2.5rem, 1.4rem + 3.6vw, 4.5rem);
  --step-display: clamp(3.5rem, 1.6rem + 7vw, 8.5rem);

  --ease: cubic-bezier(.16, 1, .3, 1);
  /* the curtain: slow to start, long to settle */
  --curtain: cubic-bezier(.76, 0, .18, 1);
  --scrim: rgb(5 7 11 / 0.62);
  --slide-time: 6500ms;
}

/* grounds */
body {
  --bg: var(--night); --ink: var(--night-ink); --muted: var(--night-muted);
  --focus: #5a9bfc; --viewer-bg: var(--night); --viewer-ink: var(--night-ink); --viewer-muted: var(--night-muted);
  color-scheme: dark;
}
/* paper for the Gallery and About; night on request (html[data-theme="dark"]) */
html:not([data-theme="dark"]) body:not([data-page="home"]) {
  --bg: #ebeae6; --ink: #1a1b1d; --muted: #56585d; --focus: #1d5fd0; color-scheme: light;
}
/* a photograph opened from the paper still opens into the night: these low-light pictures
   go grey and muddy against a light ground */
.viewer { --focus: #5a9bfc; color-scheme: dark; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* on the pages that scroll, opening a photograph never shifts the page sideways */
html:has(body:not([data-page="home"])) { scrollbar-gutter: stable; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 var(--step-body) / 1.55 var(--face);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 600ms ease, color 600ms ease;
}
body[data-page="home"] { overflow: hidden; }
::selection { background: var(--ink); color: var(--bg); }
img { display: block; max-width: 100%; height: auto; }
p, h1, h2, figure, ol { margin: 0; }
ol { padding: 0; list-style: none; }
h1, h2 { font-family: var(--display); font-weight: 400; letter-spacing: -0.02em; line-height: 0.95; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
[hidden] { display: none !important; }

.skip {
  position: fixed; left: var(--margin); top: var(--margin); z-index: 40;
  padding: 10px 16px; background: var(--ink); color: var(--bg); text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.link {
  font-size: var(--step-small);
  text-decoration: underline; text-decoration-color: transparent;
  text-decoration-thickness: 1px; text-underline-offset: 0.3em;
  transition: text-decoration-color 200ms ease, opacity 200ms ease;
}
.link:focus-visible { text-decoration-color: currentColor; }
/* hover only where there is a pointer that hovers: on touch it would stick after a tap */
@media (hover: hover) { .link:hover { text-decoration-color: currentColor; } }
.link:active { opacity: 0.7; }

/* ---------- The bar: the logo and the name, three words ---------- */
.bar {
  position: fixed; inset: 0 0 auto; z-index: 20;
  display: flex; justify-content: space-between; align-items: center; gap: 24px;
  min-height: var(--bar-h);
  padding: env(safe-area-inset-top, 0px) var(--margin) 0;
  font-size: var(--step-small);
  color: var(--ink);
  background: var(--bg);
  transition: transform 450ms var(--ease), opacity 900ms ease 300ms, background-color 600ms ease, color 600ms ease;
  view-transition-name: bar;
}
body[data-page="home"] .bar { background: transparent; color: var(--night-ink); }
.bar__name { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.bar__title, .bar__name > span { font: inherit; letter-spacing: 0.01em; line-height: 1; }
.bar__title { display: inline-flex; align-items: center; gap: 12px; }
.bar__name > .mono { margin-right: 12px; }
.mono { width: 26px; height: 26px; fill: currentColor; flex: none; transition: transform 600ms var(--ease); }
@media (hover: hover) { .bar__name:hover .mono { transform: rotate(-90deg); } }
.bar__nav { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 32px); }
.bar__nav a {
  display: inline-flex; align-items: center; min-height: 44px;
  text-decoration: underline; text-decoration-color: transparent; transition: text-decoration-color 200ms ease;
}
.bar__nav a[aria-current="page"] { text-decoration-color: currentColor; }
@media (hover: hover) { .bar__nav a:hover { text-decoration-color: currentColor; } }
.is-bar-away .bar:not(:focus-within) { transform: translateY(-110%); }

.sound, .theme { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; }
body[data-page="home"] .theme { display: none; }
.theme__icon { width: 12px; height: 12px; }
.theme__icon circle { fill: none; stroke: currentColor; stroke-width: 1.2; }
.theme__icon path { fill: currentColor; transition: transform 500ms var(--ease); transform-origin: 6px 6px; }
html[data-theme="dark"] .theme__icon path { transform: rotate(180deg); }
.sound__bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; }
.sound__bars i { width: 2px; height: 4px; background: currentColor; }
.sound[aria-pressed="true"] { color: var(--focus); }
body[data-page="home"] .sound[aria-pressed="true"] { color: #8fb9ff; }
@media (prefers-reduced-motion: no-preference) { .sound[aria-pressed="true"] .sound__bars i { animation: bars 1.4s ease-in-out infinite alternate; } }
/* with less motion, playing shows as bars at different heights instead */
@media (prefers-reduced-motion: reduce) { .sound[aria-pressed="true"] .sound__bars i:nth-child(2) { height: 10px; } .sound[aria-pressed="true"] .sound__bars i:nth-child(3) { height: 7px; } }
.sound[aria-pressed="true"] .sound__bars i:nth-child(2) { animation-delay: -0.5s; }
.sound[aria-pressed="true"] .sound__bars i:nth-child(3) { animation-delay: -0.9s; }
@keyframes bars { from { height: 4px; } to { height: 12px; } }

/* ---------- Home: the slideshow ---------- */
.show {
  position: relative; overflow: hidden;
  height: 100vh; height: 100dvh; /* taste-skill-ignore: fallback before dvh */
  background: var(--night); color: var(--night-ink);
  touch-action: pinch-zoom;
  overscroll-behavior: none;
  cursor: pointer;
}
.slide { position: absolute; inset: 0; background: var(--c); overflow: hidden; visibility: hidden; }
.slide.is-active, .slide.is-leaving { visibility: visible; }
.slide.is-active { z-index: 2; }
.slide.is-leaving { z-index: 1; }
.slide picture, .slide img { width: 100%; height: 100%; }
.slide img { object-fit: cover; object-position: var(--fx, 50%) 50%; }
/* one set for each orientation of the screen; the other is not shown, so not fetched */
.slide[data-slide="tall"] { display: none; }
@media (orientation: portrait) {
  .slide[data-slide="wide"] { display: none; }
  .slide[data-slide="tall"] { display: block; }
}
/* only the photograph on screen and its neighbours are in the page; the rest load when they come near */
.slide:not(.is-active):not(.is-leaving):not(.is-near) { display: none; }
.slide::before, .slide::after { content: ""; position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none; }
.slide::before { top: 0; height: 160px; background: linear-gradient(var(--scrim), transparent); opacity: 0.75; } /* taste-skill-ignore: scrim under the bar */
.slide::after { bottom: 0; height: 42%; background: linear-gradient(transparent, var(--scrim)); } /* taste-skill-ignore: scrim under the caption */
/* upright photographs are often bright at the top: a deeper shade keeps the bar readable */
@media (orientation: portrait) { .slide::before { height: 200px; opacity: 1; } }
/* after Enter the slideshow itself holds the focus, so the arrows work without a ring on the name */
.show:focus { outline: none; }

.slide__cap {
  position: absolute; z-index: 3;
  left: var(--margin); bottom: calc(var(--margin) + env(safe-area-inset-bottom, 0px));
  max-width: calc(100% - 2 * var(--margin));
}
.mask { display: block; overflow: hidden; padding-bottom: 0.08em; }
.slide__title, .slide__meta { display: block; }
.slide__title { font-family: var(--display); font-size: var(--step-head); letter-spacing: -0.02em; line-height: 1; }
.slide__meta { margin-top: 10px; font-size: var(--step-body); }

.dots {
  position: absolute; z-index: 4;
  right: var(--margin); bottom: calc(var(--margin) + env(safe-area-inset-bottom, 0px) - 12px);
  display: flex; align-items: center; gap: 2px;
  cursor: default;
}
.dot { width: 34px; height: 44px; display: grid; place-items: center; }
.dot i { position: relative; display: block; width: 26px; height: 3px; background: rgb(233 237 243 / 0.42); overflow: hidden; transition: background-color 200ms ease; }
@media (hover: hover) { .dot:hover i { background: rgb(233 237 243 / 0.6); } }
.dot i::after { content: ""; position: absolute; inset: 0; background: var(--night-ink); transform: scaleX(0); transform-origin: left; }
.dot[aria-current="true"] i::after { transform: scaleX(1); }
.dot.is-done i::after { transform: scaleX(1); }
.play { margin-left: 14px; min-height: 44px; min-width: 44px; }
/* the last photograph of the round points on to the rest */
.slide__more { display: inline-flex; align-items: center; min-height: 44px; margin-top: 14px; font-size: var(--step-small); transition: opacity 700ms ease 900ms; }
/* not on the way in, and only once its photograph is on screen */
.is-entry .slide__more, .slide:not(.is-active) .slide__more { opacity: 0; transition: none; }
.slide__more span { margin-left: 8px; transition: transform 400ms var(--ease); }
@media (hover: hover) { .slide__more:hover span { transform: translateX(4px); } }

/* ---------- The way in: the photograph out of focus, sharp where you look ---------- */
.entry { display: none; }
.is-entry .entry, .entry.is-leaving {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  padding: var(--margin);
  color: var(--night-ink);
  text-align: center;
  cursor: pointer;
}
/* Focus as a lens has it: three copies of the photograph, each more out of focus and darker
   than the one under it, each with a wider soft hole. From the point of focus outwards the
   picture goes sharp, slightly soft, softer, fully blurred, instead of fading between two. */
.entry__blur { position: absolute; inset: 0; overflow: hidden; --x: 50%; --y: 50%; --r: 0px; }
/* nothing shows until the blurred copies are ready, so the sharp photograph never flashes
   first; then the photograph and its blur come in together */
.is-entry .slide, .is-entry .entry__blur { transition: opacity 900ms ease; }
.is-entry:not(.is-lens) .slide, .is-entry:not(.is-lens) .entry__blur { opacity: 0; }
.entry__layer {
  position: absolute; inset: 0;
  --lens: radial-gradient(circle at var(--x) var(--y), /* taste-skill-ignore: the focus mask, not a fill */
    transparent 0, transparent var(--a),
    rgb(0 0 0 / 0.08) calc(var(--a) + var(--f) * 0.15),
    rgb(0 0 0 / 0.25) calc(var(--a) + var(--f) * 0.32),
    rgb(0 0 0 / 0.5) calc(var(--a) + var(--f) * 0.5),
    rgb(0 0 0 / 0.75) calc(var(--a) + var(--f) * 0.68),
    rgb(0 0 0 / 0.92) calc(var(--a) + var(--f) * 0.85),
    #000 calc(var(--a) + var(--f))); /* taste-skill-ignore: the focus mask, not a fill */
  -webkit-mask-image: var(--lens);
  mask-image: var(--lens);
}
.entry__layer--1 { --a: var(--r); --f: 6vmax; }
.entry__layer--2 { --a: calc(var(--r) + 3vmax); --f: 8vmax; }
.entry__layer--3 { --a: calc(var(--r) + 7vmax); --f: 12vmax; }
.entry__layer picture, .entry__layer img { width: 100%; height: 100%; }
/* scaled like the sharp photograph beneath, which waits at the start of its settle */
.entry__layer img { object-fit: cover; object-position: var(--fx, 50%) 50%; transform: scale(1.14); }
.entry__layer--1 img { filter: blur(2.5px) brightness(0.86); }
.entry__layer--2 img { filter: blur(8px) brightness(0.66) saturate(1.04); }
.entry__layer--3 img { filter: blur(22px) brightness(0.42) saturate(1.05); }
.entry__inner { position: relative; z-index: 2; display: grid; justify-items: center; pointer-events: none;
  /* when the sharp spot of the lens passes behind the words, a soft shade keeps them readable */
  text-shadow: 0 1px 2px rgb(5 7 11 / 0.4), 0 2px 28px rgb(5 7 11 / 0.6); }
.entry__inner > * { pointer-events: auto; }
.entry__mono { width: 56px; height: 56px; margin-bottom: 36px; }
.entry__name { font-family: var(--display); font-size: var(--step-head); letter-spacing: -0.02em; line-height: 1; }
.entry__sub { margin-top: 14px; font-size: var(--step-lead); }
.entry__go {
  display: inline-flex; align-items: center; gap: 16px;
  margin-top: clamp(44px, 9vh, 88px); min-height: 48px; padding: 0 4px;
  font-size: var(--step-lead); letter-spacing: -0.01em;
}
.entry__arrow { width: 40px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.4; transition: transform 500ms var(--ease); }
.entry__go:focus-visible .entry__arrow { transform: translateX(8px); }
@media (hover: hover) { .entry__go:hover .entry__arrow { transform: translateX(8px); } }
.entry__go:active { opacity: 0.75; }
.entry__sound { position: absolute; z-index: 2; bottom: calc(var(--margin) + env(safe-area-inset-bottom, 0px)); font-size: var(--step-small); }
.entry__sound { right: var(--margin); }
.entry__sound[aria-pressed="true"] { color: #8fb9ff; }
/* while it is there, the slideshow waits and the bar stays out of sight */
.is-entry .bar { opacity: 0; pointer-events: none; animation: none !important; }
.is-entry .slide.is-active img, .is-entry .dot[aria-current="true"] i::after { animation-play-state: paused !important; }
.is-entry .dots { opacity: 0; }

/* ---------- Pages: Gallery and About ---------- */
.page-title { font-size: var(--step-display); line-height: 0.92; letter-spacing: -0.03em; }
.gallery, .about { padding: calc(var(--bar-h) + clamp(48px, 9vh, 120px)) var(--margin) 0; }
.gallery .page-title { margin-bottom: clamp(64px, 11vh, 140px); }

.work__link { display: block; text-decoration: none; }
.work__link picture, .about__photo picture { display: block; overflow: hidden; background: var(--c); }
.work__link img, .about__photo img { width: 100%; transition: transform 900ms var(--ease); }
@media (hover: hover) { .work__link:hover img { transform: scale(1.03); } }
.work__link:active img { transform: scale(1.01); }
.work__cap { margin-top: 12px; font-size: var(--step-small); }
.cap__title { color: var(--ink); }
.cap__meta { color: var(--muted); }
.cap__meta::before { content: " — "; }

/* ---------- The magazine: rows that share a height, in a changing rhythm ---------- */
.mag { display: grid; row-gap: clamp(56px, 9vh, 120px); }
/* after the last photograph, the way back into the night */
.mag__end { margin-top: clamp(96px, 16vh, 200px); text-align: center; font-size: var(--step-lead); }
.mag__end .link { display: inline-flex; align-items: center; min-height: 44px; font-size: inherit; }
.mag__end span { margin-left: 10px; transition: transform 400ms var(--ease); }
@media (hover: hover) { .mag__end .link:hover span { transform: translateX(4px); } }
.mag__row {
  display: flex; align-items: flex-start; gap: clamp(16px, 2vw, 32px);
  /* each photograph's width follows its shape, so the row shares one height; never above 3/4 of the screen */
  width: 100%; max-width: calc(75vh * var(--sum) + 64px);
}
.mag__row.is-right { margin-left: auto; }
.mag__item { flex: var(--ar) 1 0; min-width: 0; }
.mag__item .work__cap { margin-top: 12px; }
/* now and then one photograph opens a spread, its title set large beside it */
.mag__row--1 { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--margin); max-width: none; align-items: end; }
.mag__row--1 .mag__item { display: contents; }
.mag__row--1 .work__link { grid-column: 1 / 9; grid-row: 1; }
.mag__row--1 .work__cap { grid-column: 9 / 13; grid-row: 1; margin: 0; display: grid; gap: 10px; }
.mag__row--1.is-right .work__link { grid-column: 5 / 13; }
.mag__row--1.is-right .work__cap { grid-column: 1 / 5; text-align: right; }
.mag__row--1 .is-v .work__link { grid-column: 3 / 7; }
.mag__row--1 .is-v .work__cap { grid-column: 7 / 11; }
.mag__row--1.is-right .is-v .work__link { grid-column: 7 / 11; }
.mag__row--1.is-right .is-v .work__cap { grid-column: 3 / 7; }
.mag__row--1 .cap__title { font-family: var(--display); font-size: var(--step-head); line-height: 1; letter-spacing: -0.02em; }
.mag__row--1 .cap__meta { font-size: var(--step-body); }
.mag__row--1 .cap__meta::before { content: none; }

/* back to the top of a long gallery: there once the page is well under way */
.top {
  position: fixed; z-index: 15;
  right: var(--margin); bottom: calc(var(--margin) + env(safe-area-inset-bottom, 0px));
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 14px;
  background: var(--bg); color: var(--ink);
  font-size: var(--step-small);
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity 400ms ease, transform 500ms var(--ease);
}
.top.is-on { opacity: 1; transform: none; pointer-events: auto; }
.top svg { width: 10px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.3; transition: transform 400ms var(--ease); }
@media (hover: hover) { .top:hover svg { transform: translateY(-3px); } }
.top:active { opacity: 0.75; }

/* About */
.about { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--margin); align-items: end; }
.about__text { grid-column: 1 / 6; display: grid; gap: 20px; justify-items: start; padding-bottom: 4px; }
.about__text .page-title { margin-bottom: clamp(24px, 6vh, 64px); }
.about__lead { font-size: var(--step-lead); line-height: 1.3; max-width: 22ch; }
.about__write { margin-top: 24px; color: var(--muted); font-size: var(--step-small); }
.about__mail { display: inline-block; margin-top: 6px; color: var(--ink); font-size: var(--step-lead); line-height: 1.25; overflow-wrap: anywhere; }
.about__photo { grid-column: 7 / 13; }
/* on a desk the whole About, footer included, is one screen: the photograph gives way to the window's height */
@media (min-width: 761px) {
  body[data-page="about"] main { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; } /* taste-skill-ignore: fallback before svh */
  body[data-page="about"] .about { flex: 1; padding-top: calc(var(--bar-h) + clamp(12px, 4svh, 56px)); padding-bottom: clamp(16px, 3svh, 40px); align-items: center; }
  .about .page-title { font-size: min(var(--step-display), 15svh); }
  .about__text { gap: clamp(10px, 2svh, 20px); }
  .about__text .page-title { margin-bottom: clamp(8px, 4svh, 56px); }
  .about__write { margin-top: clamp(8px, 2svh, 24px); }
  /* as wide as its column allows, but never taller than the window leaves room for */
  .about__photo { container-type: inline-size; }
  .about__photo picture, .about__photo .work__cap { width: min(100cqi, calc((100svh - var(--bar-h) - 230px) * var(--ar, 1.5))); margin-left: auto; }
  body[data-page="about"] .foot { margin-top: 0; padding-block: clamp(16px, 3svh, 32px); }
}

.foot {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px; flex-wrap: wrap;
  margin-top: clamp(120px, 18vh, 220px);
  padding: 32px var(--margin) calc(32px + env(safe-area-inset-bottom, 0px));
  font-size: var(--step-small); color: var(--muted);
}
.foot a { color: var(--ink); }
/* small text links get a taller touch area without moving the text */
.foot a, .about__text p a { display: inline-block; padding-block: 10px; margin-block: -10px; }

/* ---------- Not found ---------- */
.lost {
  min-height: 100vh; min-height: 100svh; /* taste-skill-ignore: fallback before svh */
  display: grid; grid-template-columns: repeat(12, 1fr); column-gap: var(--margin); align-items: center;
  padding: calc(var(--bar-h) + 24px) var(--margin) 48px;
}
.lost__words { grid-column: 1 / 6; display: grid; gap: 24px; }
.lost__photo { grid-column: 7 / 13; }
.lost__photo picture { display: block; background: var(--c); }
.lost__photo img { width: 100%; }
@media (max-width: 760px) {
  .lost { display: block; }
  .lost__photo { margin-top: 56px; }
}
.lost__text { font-size: var(--step-lead); text-wrap: balance; }
.lost__links { display: flex; flex-wrap: wrap; gap: 12px 32px; }
.lost__links a { display: inline-flex; align-items: center; min-height: 44px; }

/* ---------- Viewer ---------- */
.viewer {
  width: 100vw; height: 100vh; height: 100dvh; /* taste-skill-ignore: fallback before dvh */
  max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: var(--viewer-bg); color: var(--viewer-ink);
  overscroll-behavior: contain;
}
.viewer[open] { display: grid; grid-template-rows: minmax(0, 1fr) auto; overflow: hidden; }
.viewer::backdrop { background: var(--viewer-bg); }
.viewer__frame { min-height: 0; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; padding: var(--margin) var(--margin) 0; touch-action: pinch-zoom; cursor: pointer; }
/* inside the frame only the image takes part in the grid */
.viewer__frame source { display: none; }
.viewer__frame picture { display: contents; }
/* sized to the photograph itself (no empty bands), so it grows exactly out of the one clicked */
.viewer__frame img { grid-area: 1 / 1; width: auto; height: auto; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0; }
/* stepping: the next photograph waits unseen, then comes in over the one before */
.viewer__frame img.is-coming { opacity: 0; }
.viewer__frame img.is-going { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .viewer__frame img { transition: opacity 380ms ease; }
}
.viewer__bar {
  display: flex; justify-content: space-between; align-items: center; gap: 8px 32px; flex-wrap: wrap;
  padding: 16px var(--margin) calc(var(--margin) + env(safe-area-inset-bottom, 0px));
}
.viewer__cap { font-size: var(--step-body); }
.viewer__cap .cap__title { color: var(--viewer-ink); }
.viewer__cap .cap__meta, .viewer__count { color: var(--viewer-muted); }
.viewer__count { margin-left: 12px; font-size: var(--step-small); font-variant-numeric: tabular-nums; }
.viewer__nav { display: flex; gap: 28px; }
.viewer__nav .link { font-size: var(--step-body); min-height: 44px; }
/* at the first and the last photograph the way on is closed */
.viewer__nav .link:disabled { opacity: 0.35; cursor: default; text-decoration-color: transparent; }
.is-viewing { overflow: hidden; }
/* the viewer is centred on the whole window, not on the page minus its scrollbar */
html.is-viewing:has(body) { scrollbar-gutter: auto; }

/* switching paper and night: the dissolve does the whole change, so nothing else may
   animate the colours at the same time (that second fade was the flash of light) */
html.is-switching, html.is-switching *, html.is-switching *::before, html.is-switching *::after { transition: none !important; }
html.is-theme-switch .bar { view-transition-name: none; }

/* ---------- Loading: the photograph's own colour first ---------- */
.js .about__photo img, .js .mag img { opacity: 0; transition: opacity 900ms ease, transform 900ms var(--ease); }
.js .about__photo img.is-loaded, .js .mag img.is-loaded { opacity: 1; }
img.is-broken { visibility: hidden; }

/* ---------- Motion ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* the next photograph rises over the last like a curtain, and settles */
  .slide.is-entering { animation: curtain-up 1400ms var(--curtain) both; }
  .slide.is-entering.is-back { animation-name: curtain-down; }
  .slide.is-active img { animation: settle 8s cubic-bezier(.2, .6, .3, 1) both; }
  .slide.is-leaving img { animation: drift 1400ms var(--curtain) both; }
  .slide.is-leaving.is-back img { animation-name: drift-down; }
  @keyframes curtain-up { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0); } }
  @keyframes curtain-down { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0); } }
  @keyframes settle { from { transform: scale(1.14); } to { transform: scale(1); } }
  /* --s: how far the outgoing photograph's settle had got, so it never jumps to its end */
  /* and it goes gently out of focus as it leaves, never all at once */
  @keyframes drift { from { transform: scale(var(--s, 1)); filter: blur(0); } to { transform: translateY(-9%) scale(var(--s, 1)); filter: blur(10px); } }
  @keyframes drift-down { from { transform: scale(var(--s, 1)); filter: blur(0); } to { transform: translateY(9%) scale(var(--s, 1)); filter: blur(10px); } }

  /* captions rise from behind their line, then leave upwards */
  .slide__title, .slide__meta { transform: translateY(110%); }
  .slide.is-active .slide__title { transform: none; transition: transform 1100ms var(--ease) 650ms; }
  .slide.is-active .slide__meta { transform: none; transition: transform 1100ms var(--ease) 780ms; }
  .slide.is-leaving .slide__title, .slide.is-leaving .slide__meta { transform: translateY(-110%); transition: transform 600ms cubic-bezier(.5, 0, .75, 0); }

  /* the way in: the logo, then the name from behind its line; going in, the focus opens to the whole frame */
  .is-entry .entry__mono { animation: rise 1200ms var(--ease) 100ms both; }
  .is-entry .entry .mask > span { display: block; animation: line-in 1100ms var(--ease) both; }
  .is-entry .entry__name .mask > span { animation-delay: 350ms; }
  .is-entry .entry__sub .mask > span { animation-delay: 480ms; }
  .is-entry .entry__go { animation: rise 1100ms var(--ease) 750ms both; }
  .is-entry .entry__sound { animation: fade-in 1200ms ease 1000ms both; }
  @keyframes line-in { from { transform: translateY(110%); } }
  @keyframes fade-in { from { opacity: 0; } }
  .entry.is-leaving .entry__inner, .entry.is-leaving .entry__sound { transition: opacity 1000ms ease, transform 1600ms var(--ease); opacity: 0; transform: translateY(-24px); }
  /* while the focus opens, the caption, the bar and the dots wait; they come in as it settles */
  .is-opening .slide__title, .is-opening .slide__meta { transform: translateY(110%) !important; transition: none !important; }
  .is-opening .bar, .is-opening .dots, .is-opening .slide__more { opacity: 0 !important; }
  .dots { transition: opacity 800ms ease 600ms; }
  .is-entry .slide__title, .is-entry .slide__meta { transform: translateY(110%) !important; transition: none !important; }

  /* the bar arrives once, at the start */
  .is-arriving body[data-page="home"] .bar { animation: bar-in 1200ms var(--ease) 400ms both; }
  @keyframes bar-in { from { opacity: 0; transform: translateY(-16px); } }

  /* the timer in the dots */
  .dot[aria-current="true"] i::after { transform: scaleX(0); animation: fill var(--slide-time) linear forwards; }
  .is-paused .dot[aria-current="true"] i::after, .is-holding .dot[aria-current="true"] i::after { animation-play-state: paused; }
  @keyframes fill { to { transform: scaleX(1); } }

  /* pages: photographs open like the curtain on the home, then settle */
  .js .page-title { animation: rise 1100ms var(--ease) 200ms both; }
  .js .about__text > :not(.page-title) { animation: rise 1100ms var(--ease) both; }
  .js .about__text > :nth-child(2) { animation-delay: 320ms; }
  .js .about__text > :nth-child(3) { animation-delay: 400ms; }
  .js .about__text > :nth-child(4) { animation-delay: 480ms; }
  @keyframes rise { from { opacity: 0; transform: translateY(32px); } }

  /* short, and already moving as the photograph comes into view: scrolling never outruns it */
  .js .about__photo picture, .js .mag picture { clip-path: inset(100% 0 0 0); transition: clip-path 800ms var(--ease); }
  .js .about__photo.is-seen picture, .js .mag .is-seen picture { clip-path: inset(0); }
  .js .mag picture img { transform: scale(1.06); }
  .js .mag .is-seen picture img { transform: none; transition: opacity 600ms ease, transform 1000ms var(--ease); }
  @media (hover: hover) { .js .mag .is-seen .work__link:hover img { transform: scale(1.03); transition: transform 900ms var(--ease); } }
  /* within a row, one after the other */
  .js .mag__item:nth-child(2) picture, .js .mag__item:nth-child(2) img { transition-delay: 90ms; }
  .js .mag__item:nth-child(3) picture, .js .mag__item:nth-child(3) img { transition-delay: 180ms; }
  .js .mag .work__cap { opacity: 0; transform: translateY(12px); transition: opacity 500ms ease 250ms, transform 700ms var(--ease) 250ms; }
  .js .mag .is-seen .work__cap { opacity: 1; transform: none; }
  .js .about__photo img { transform: scale(1.06); }
  .js .about__photo.is-seen img { transform: none; transition: opacity 600ms ease, transform 1000ms var(--ease); }
  .js .about__photo .work__cap { opacity: 0; transform: translateY(12px); transition: opacity 500ms ease 250ms, transform 700ms var(--ease) 250ms; }
  .js .about__photo.is-seen .work__cap { opacity: 1; transform: none; }

  /* page to page: the new page rises over the old one */
  /* page to page: the old page dims and settles back, the new one surfaces through it;
     the bar is part of the page here, so its colour changes with everything else */
  ::view-transition-old(root), ::view-transition-new(root) { mix-blend-mode: normal; }
  ::view-transition-old(root) { animation: page-out 700ms cubic-bezier(.4, 0, .2, 1) both; }
  ::view-transition-new(root) { animation: page-in 1000ms var(--ease) 120ms both; }
  @keyframes page-out { to { opacity: 0; transform: scale(0.985); filter: blur(4px); } }
  /* the bar does not take part: it stays where it is, and only its colours cross over */
  ::view-transition-group(bar) { animation: none; }
  ::view-transition-old(bar), ::view-transition-new(bar) { mix-blend-mode: normal; }
  ::view-transition-old(bar) { animation: fade-out 700ms cubic-bezier(.4, 0, .2, 1) both; }
  ::view-transition-new(bar) { animation: fade-in 700ms cubic-bezier(.4, 0, .2, 1) both; }
  @keyframes page-in { from { opacity: 0; transform: translateY(2.5vh); } }
  /* light and dark: a plain dissolve, nothing moves */
  html.is-theme-switch::view-transition-old(root), html.is-theme-switch::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
  html.is-theme-switch::view-transition-old(root) { animation: fade-out 700ms ease both; }
  html.is-theme-switch::view-transition-new(root) { animation: fade-in 700ms ease both; }
  @keyframes fade-out { to { opacity: 0; } }
  /* a photograph opens out of the gallery into the viewer */
  /* the photograph moves at once and settles slowly: it never seems to wait */
  ::view-transition-group(photo) { animation-duration: 700ms; animation-timing-function: cubic-bezier(.22, .8, .24, 1); }
  ::view-transition-old(photo), ::view-transition-new(photo) { animation-duration: 700ms; animation-timing-function: cubic-bezier(.22, .8, .24, 1); }
  /* while a photograph opens or closes, the page around it only fades */
  html.is-photo-switch::view-transition-old(root) { animation: fade-out 450ms ease both; }
  html.is-photo-switch::view-transition-new(root) { animation: fade-in 450ms ease both; }
}
@media (prefers-reduced-motion: reduce) {
  .entry__layer img { transform: none; }
  .slide.is-entering { animation: fade 400ms ease both; }
  @keyframes fade { from { opacity: 0; } }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation-duration: 200ms !important; }
}

/* ---------- Phone ---------- */
@media (max-width: 760px) {
  /* one photograph after another, each as wide as the screen: an upright one fills it best */
  .mag { grid-template-columns: 1fr 1fr; gap: 40px 12px; }
  .mag__item.is-v { grid-column: 1 / -1; }
  /* the spreads go edge to edge, as in the viewer; their title stays inside the margin */
  .mag .mag__row--1 .work__link { display: block; margin-inline: calc(-1 * var(--margin)); }
  .mag__row { display: contents; }
  .mag .mag__row--1 .mag__item, .mag__item { display: block; }
  .mag__item.is-h { grid-column: 1 / -1; }
  .mag .work__cap, .mag .mag__row--1.is-right .work__cap { margin-top: 10px; text-align: left; display: block; }
  /* the spreads keep their larger title, a step down from the desk */
  .mag .mag__row--1 .cap__title { font-family: var(--display); font-size: var(--step-lead); letter-spacing: -0.01em; line-height: 1.15; }
  .mag .mag__row--1 .cap__meta { font-size: var(--step-small); margin-top: 4px; }

  /* the viewer gives the photograph the whole width, edge to edge */
  .viewer__frame { padding: 0; }
  .viewer__bar { padding-top: 12px; }
  .mag .cap__meta { display: block; }
  .mag .cap__meta::before { content: none; }

  :root { --bar-h: 64px; }
  .bar__nav { gap: 16px; }
  .slide__cap { bottom: calc(var(--margin) + 52px + env(safe-area-inset-bottom, 0px)); }
  .dots { left: calc(var(--margin) - 4px); right: auto; }
  .dot { width: 30px; }
  .dot i { width: 22px; }

  .about { display: block; }
  .about__photo { margin: 72px calc(-1 * var(--margin)) 0; }
  .about__photo .work__cap { padding-inline: var(--margin); }

}
@media (max-width: 400px) {
  .bar__name > span, .bar__title > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
