/* htut.life, the story page. Built around one brush hand: Htut Brush for the
   large words, Atkinson Hyperlegible Next for reading, ink on paper in light
   mode and black lacquer in dark mode, a single cinnabar accent.

   How the motion is layered, so it degrades cleanly:
   1. With no class on <html> the page is a plain scrolling page and every
      drawing is shown finished. This is what reduced motion gets.
   2. html.motion (set in story-head.js when the visitor has not asked for
      reduced motion) pins the two scenes and lets drawings write themselves.
   3. Scroll-driven drawing uses CSS scroll timelines where the browser has
      them (@supports below). Where it does not, story.js sets the same
      stroke-dashoffset and opacity values from a requestAnimationFrame loop.
   4. html.paused (the Pause animation button) shows every drawing finished.
   Only transform, opacity and stroke-dashoffset ever animate. */

@font-face {
  font-family: "Htut Brush";
  src: url("/assets/fonts/HtutBrush-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("/assets/fonts/AtkinsonHyperlegibleNext.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}

:root {
  /* paper: ink on a light ground */
  --ground: #F6F3EE;
  --ink: #1A1714;
  --muted: #57504A;
  --faint: #6E655C;
  --cinnabar: #B33A26;
  --rule: #D8CFC2;
  --tile: #E7E1D7;
  --disc: #FFFFFF;

  --brush: "Htut Brush", Georgia, serif;
  --sans: "Atkinson Hyperlegible Next", system-ui, sans-serif;
  --ease: cubic-bezier(.22, 1, .36, 1);

  --head: 64px;
  --pad: clamp(16px, 5vw, 72px);
  --inkw: clamp(30px, 6vw, 104px);   /* width of the ink line's column */
  --gut: clamp(4px, 3vw, 56px);      /* from the column to the right edge */
  --gap: clamp(10px, 3vw, 48px);     /* from the content to the column */
  --right: calc(var(--gut) + var(--inkw) + var(--gap));
  --seg: calc(var(--inkw) * 3);      /* a curved segment is 240 x 720 */
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    /* lacquer: warm off-white ink on black lacquer */
    --ground: #15110F;
    --ink: #F1E9DC;
    --muted: #BFB4A3;
    --faint: #9A8F80;
    --cinnabar: #E0644D;
    --rule: #3A322C;
    --tile: #221C19;
    --disc: #F1E9DC;
  }
}
@media (max-width: 699px) { :root { --head: 56px; } }

/* ── Base ─────────────────────────────────────────────────────────────── */
html {
  background: var(--ground);
  scroll-padding-top: var(--head);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
html.motion:not(.paused) { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 18px/1.6 var(--sans);
  overflow-x: clip;
}
::selection { background: var(--cinnabar); color: var(--ground); }
input, textarea { caret-color: var(--cinnabar); }
:root { accent-color: var(--cinnabar); }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .22em; }
a:hover { color: var(--cinnabar); }
:focus-visible { outline: 3px solid var(--cinnabar); outline-offset: 3px; border-radius: 2px; }
img { max-width: 100%; }
h1, h2, h3 { text-wrap: balance; }
button { font: inherit; color: inherit; }
.vh {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ic { width: 20px; height: 20px; fill: currentColor; flex: none; }
.skip {
  position: absolute; left: 8px; top: -80px; z-index: 40;
  padding: 10px 16px; background: var(--ink); color: var(--ground);
}
.skip:focus { top: 8px; }

/* Every drawing is a filled shape seen through a mask of its own strokes. At
   rest the strokes are whole, so the drawing shows finished. */
.d { stroke-dasharray: 1 2; stroke-dashoffset: 0; }
@keyframes draw { from { stroke-dashoffset: 1.01; } to { stroke-dashoffset: 0; } }

.btn {
  min-height: 48px; padding: 0 30px;
  border: 1px solid currentColor; border-radius: 2px;
  background: transparent; color: var(--ink);
  font: 600 17px/1 var(--sans); cursor: pointer;
  transition: color .12s, border-color .12s;
}
.btn:hover { color: var(--cinnabar); }

/* ═══ The gate ════════════════════════════════════════════════════════════
   The door and the opening are one moment. `gated` is written into the HTML
   and only ever removed by script, so with JavaScript off the site stays shut.
   Content is hidden with visibility, not display, so everything under the
   door keeps its real size and the signature can be measured to its place. */
html.gated { overflow: hidden; overscroll-behavior: none; scrollbar-gutter: stable; }
html.gated body > *:not(.gate):not(.sprite) { visibility: hidden; }
html:not(.gated):not(.gate-open) .gate { display: none; }

.gate { position: fixed; inset: 0; z-index: 100; overflow: auto; }
.gate__ground { position: absolute; inset: 0; background: var(--ground); }
.gate__in {
  position: relative; box-sizing: border-box; min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(14px, 3vh, 30px); padding: 24px 16px max(24px, env(safe-area-inset-bottom));
  text-align: center;
}
.gate__sig { width: min(560px, 84vw); height: auto; display: block; transform-origin: 0 0; }
.gate__fade { display: flex; flex-direction: column; align-items: center; }
.gate__name { margin: 0; font: 400 clamp(34px, 5vw, 46px)/1.1 var(--brush); }
.gate__lines { margin: 6px 0 0; font-size: 18px; line-height: 1.5; color: var(--muted); }
.gate__form {
  margin: clamp(18px, 3vh, 30px) 0 0;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.gate__riddle { margin: 0; font: 400 clamp(32px, 4.5vw, 40px)/1.1 var(--brush); color: var(--cinnabar); }
.gate__pair { display: flex; align-items: flex-end; gap: 22px; }
.gate__field { display: flex; flex-direction: column; align-items: center; }
.gate__num {
  box-sizing: border-box; width: 96px; height: 60px; padding: 0;
  border: 0; border-radius: 4px; background: transparent; color: var(--ink);
  font: 400 44px/1 var(--brush); text-align: center;
  -webkit-appearance: none; appearance: none;
}
.gate__num:focus-visible { outline-offset: 4px; }
.gate__line-art { width: 110px; height: 13px; margin-top: -2px; display: block; }
.gate__slash { font: 400 52px/1 var(--brush); color: var(--muted); padding-bottom: 12px; user-select: none; }
.gate__say { margin: 0; min-height: 26px; font-size: 16px; color: var(--muted); }
.gate__li { margin-top: clamp(18px, 3vh, 30px); font-size: 16px; display: inline-flex; min-height: 44px; align-items: center; }

/* the signature writes itself while the riddle waits */
@media (prefers-reduced-motion: no-preference) {
  html.motion:not(.paused) .gate__sig .d,
  html.motion.returning:not(.paused) .open__sig .d {
    animation: draw calc((var(--b) - var(--a)) * 2.6s) cubic-bezier(.5, 0, .5, 1)
      calc(.3s + var(--a) * 2.6s) both;
  }
  .gate.is-wrong .gate__pair { animation: no .4s var(--ease); }
  @keyframes no {
    10%, 90% { transform: translateX(-3px); }
    30%, 70% { transform: translateX(6px); }
    50% { transform: translateX(-6px); }
  }
}

/* The right answer: the words go, the ground lifts, and the signature travels
   to its place at the head of the story (story.js sets the transform). */
html.gate-open .gate { pointer-events: none; }
html.gate-open .gate__fade { opacity: 0; transition: opacity .3s ease-out; }
html.gate-open .gate__ground { opacity: 0; transition: opacity .8s var(--ease) .3s; }
html.gate-open .open__sig { opacity: 0; }
/* answered before the signature finished writing: finish it at once, so the
   one that lands is the finished one waiting in the story */
html.motion.gate-open:not(.paused) .gate__sig .d { animation: none; }

/* ═══ Header ═════════════════════════════════════════════════════════════ */
.top {
  position: sticky; top: 0; z-index: 20;
  box-sizing: border-box; height: var(--head);
  display: flex; align-items: center; gap: 12px 28px;
  padding: 0 var(--pad);
  background: var(--ground); border-bottom: 1px solid var(--rule);
}
.top__name { margin-right: auto; font: 400 26px/1 var(--brush); text-decoration: none; white-space: nowrap; }
.top__tools { order: 2; display: flex; gap: 4px; }
.top__btn {
  box-sizing: border-box; min-height: 44px; min-width: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 14px; border: 1px solid var(--faint); border-radius: 2px;
  background: transparent; color: var(--ink); font-size: 15px; cursor: pointer;
  transition: color .12s, border-color .12s;
}
.top__btn:hover { color: var(--cinnabar); border-color: currentColor; }
.top__btn .ic { width: 18px; height: 18px; }
/* the sign alone: a 44px square, named by its aria-label */
.top__pause { width: 44px; padding: 0; }
.top__pause .ic { width: 20px; height: 20px; }
html:not(.paused) .ic--play, html.paused .ic--pause { display: none; }

@media (max-width: 599px) {
  .top__name { font-size: 22px; }
  .top__btn { border-color: transparent; }
}

/* ═══ Layout and the ink line ════════════════════════════════════════════ */
main > section { position: relative; }
.wrap { box-sizing: border-box; padding-left: var(--pad); padding-right: var(--right); max-width: 1600px; }

/* The line runs down a column at the right. Each section carries its own
   stretch of it, and every stretch starts and ends at the centre of the
   column heading straight down, so the stretches meet as one line. */
.ink {
  position: absolute; top: 0; bottom: 0; right: var(--gut); z-index: 1;
  width: var(--inkw); display: flex; flex-direction: column;
  color: var(--ink); pointer-events: none;
}
.ink__seg { flex: none; height: var(--seg); }
.ink__fill { flex-basis: 0; min-height: 0; }
.ink__art { display: block; width: 100%; height: 100%; overflow: hidden; }

/* ═══ 1. Opening ═════════════════════════════════════════════════════════ */
.open { --sigw: clamp(220px, min(40vw, 58vh), 560px); --top: clamp(24px, 6vh, 64px); }
.open__pin { position: relative; min-height: calc(100svh - var(--head)); display: flex; }
.open__wrap > * { flex-shrink: 0; }
.open__wrap {
  flex: 1; display: flex; flex-direction: column; gap: clamp(12px, 2.2vh, 22px);
  padding-top: var(--top); padding-bottom: clamp(24px, 6vh, 64px);
}
.open__sig { width: var(--sigw); height: auto; display: block; }
.open__h { margin: clamp(6px, 2vh, 20px) 0 0; font: 400 clamp(44px, min(6.6vw, 10.5vh), 100px)/.98 var(--brush); max-width: 9.6em; }
.open__sub { margin: 0; font-size: clamp(19px, 1.8vw, 26px); line-height: 1.4; color: var(--muted); max-width: 32ch; }
.open__intro { margin: 0; font-size: clamp(17px, 1.3vw, 19px); max-width: 54ch; }
.open__kicker { margin: 0; font-size: 15px; color: var(--muted); }
.open__foot { margin: auto 0 0; padding-top: 16px; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.open__portrait { margin: 0; flex: 0 0 auto; width: 88px; }
.open__portrait img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover; }
@media (min-width: 900px) {
  .open__wrap { position: relative; --pw: clamp(200px, 20vw, 300px); }
  .open__wrap > .open__h, .open__wrap > .open__sub, .open__wrap > .open__intro { max-width: min(var(--mw, 100%), calc(100% - var(--pw) - 48px)); }
  .open__portrait { position: absolute; right: var(--right); top: calc(var(--top) + var(--sigw) * .35); width: var(--pw); }
}
.ink--open { top: calc(var(--top) + var(--sigw) * .1864 - var(--seg) * .15); }
.open .open__h { --n: 0; } .open .open__sub { --n: 1; } .open .open__intro { --n: 2; } .open .open__foot { --n: 3; }

/* the headline arrives as the door opens (or as a returning visitor lands) */
@keyframes arrive { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
html.motion:not(.paused):not(.opened):not(.returning) .arrive { opacity: 0; }
html.motion:not(.paused).opened .arrive,
html.motion:not(.paused).returning .arrive {
  animation: arrive .9s var(--ease) both;
  animation-delay: calc(var(--n, 0) * 90ms + var(--arrive, .25s));
}
html.returning { --arrive: .5s; --flick: 2.5s; }
/* the foot holds the portrait, which is placed against the whole opening on
   wide screens: a sliding transform would carry it along, so the foot fades */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
html.motion:not(.paused).opened .open__foot.arrive,
html.motion:not(.paused).returning .open__foot.arrive { animation-name: fade-in; }

/* the line leaves the signature: a flick on opening, the rest by scrolling */
@keyframes flick { from { stroke-dashoffset: 1.01; } to { stroke-dashoffset: .7; } }
html.motion:not(.paused) .open .flick { stroke-dashoffset: 1.01; }
html.motion:not(.paused).opened .open .flick,
html.motion:not(.paused).returning .open .flick {
  animation: flick 1.1s cubic-bezier(.3, 0, .2, 1) var(--flick, .15s) both;
}

@media (min-height: 560px) {
  html.motion .open { height: calc(100svh - var(--head) + 60vh); }
  html.motion .open__pin { position: sticky; top: var(--head); height: calc(100svh - var(--head)); min-height: 0; overflow: hidden; }
}

/* ═══ 2. Four things I helped build ══════════════════════════════════════ */
.four__wrap { padding-top: clamp(56px, 8vw, 96px); padding-bottom: clamp(56px, 8vw, 96px); }
.four__h { margin: 0 0 32px; font: 400 clamp(38px, 4.6vw, 64px)/1.02 var(--brush); }
.four__item {
  display: grid; grid-template-columns: minmax(120px, 34%) minmax(0, 1fr);
  gap: 24px clamp(24px, 5vw, 72px); align-items: center;
  padding: 36px 0; border-top: 1px solid var(--rule);
}
.four__emblem { width: 100%; max-width: 420px; height: auto; display: block; color: var(--ink); }
.four__org { display: flex; align-items: center; gap: 12px; margin: 0; font-size: 15px; line-height: 1.35; color: var(--muted); }
.four__org img {
  flex: none; width: 40px; height: 40px; box-sizing: border-box; padding: 4px;
  object-fit: contain; border-radius: 50%; background: var(--disc);
}
.four__name { margin: 12px 0 6px; font: 400 clamp(42px, 5vw, 76px)/1 var(--brush); }
.four__tag { margin: 0 0 12px; font-size: clamp(18px, 1.6vw, 22px); line-height: 1.35; color: var(--cinnabar); }
.four__body { margin: 0 0 12px; max-width: 58ch; font-size: clamp(17px, 1.3vw, 19px); }
.four__link { margin: 0; font-size: 17px; }
.out { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; }
.out .ic { width: 16px; height: 16px; }
.four__nav { display: none; }

@media (max-width: 699px) {
  .four__item { grid-template-columns: 1fr; }
  .four__emblem { width: 140px; }
}

/* pinned: the scene holds while the line draws each emblem and the text swaps */
@media (min-height: 620px) {
  html.motion .four { height: calc(100svh - var(--head) + var(--steps) * 65vh); }
  html.motion .four__pin { position: sticky; top: var(--head); height: calc(100svh - var(--head)); overflow: hidden; }
  html.motion .four__wrap {
    box-sizing: border-box; height: 100%; display: flex; flex-direction: column;
    padding-top: clamp(16px, 5vh, 64px); padding-bottom: clamp(12px, 3vh, 40px);
  }
  html.motion .four__h { margin-bottom: clamp(8px, 3vh, 36px); }
  html.motion .four__stage { position: relative; flex: 1; min-height: 0; }
  html.motion .four__item { position: absolute; inset: 0; padding: 0; border: 0; opacity: 0; }
  html.motion .four__item:first-child { opacity: 1; z-index: 2; }
  html.motion .four__nav { display: block; margin-top: clamp(8px, 2vh, 24px); padding-top: 10px; border-top: 1px solid var(--rule); }
  .four__nav ul { display: flex; flex-wrap: wrap; gap: 0 clamp(18px, 3vw, 40px); margin: 0; padding: 0; list-style: none; }
  .four__nav a {
    display: inline-flex; flex-direction: column; justify-content: center; min-height: 44px;
    font: 400 clamp(20px, 2vw, 26px)/1.15 var(--brush); color: var(--faint); text-decoration: none;
  }
  .four__nav a:hover, .four__nav a[aria-current="step"] { color: var(--ink); }
  .four__mark { display: block; height: 10px; opacity: 0; color: var(--cinnabar); }
  .four__nav li:first-child .four__mark { opacity: 1; }
  .four__under { display: block; width: 100%; height: 10px; }
}
@media (min-height: 620px) and (max-width: 699px) {
  html.motion .four__item { grid-template-columns: 72px minmax(0, 1fr); align-content: start; align-items: start; gap: 6px 14px; }
  html.motion .four__emblem { width: 72px; grid-row: 1; }
  html.motion .four__text { display: contents; }
  html.motion .four__org { grid-column: 2; grid-row: 1; align-self: center; }
  html.motion .four__name, html.motion .four__tag, html.motion .four__body, html.motion .four__link { grid-column: 1 / -1; }
  html.motion .four__name { margin: 4px 0 0; font-size: 40px; }
  html.motion .four__tag { margin: 0; font-size: 17px; }
  html.motion .four__body { margin: 0; font-size: 16px; line-height: 1.5; }
}
@media (min-height: 620px) and (max-height: 760px) and (max-width: 699px) {
  html.motion .four__body { font-size: 15px; line-height: 1.45; }
}

/* ═══ 3. The path ════════════════════════════════════════════════════════ */
.path .wrap { padding-top: clamp(72px, 9vw, 120px); padding-bottom: clamp(72px, 9vw, 120px); }
.sec__head { display: flex; flex-wrap: wrap; gap: 12px 48px; align-items: baseline; justify-content: space-between; margin-bottom: clamp(32px, 5vw, 56px); }
.sec__h { margin: 0; font: 400 clamp(40px, 5vw, 68px)/1.02 var(--brush); max-width: 18ch; }
.sec__note { margin: 0; font-size: 15px; color: var(--muted); }
.yrs { display: flex; flex-direction: column; gap: clamp(36px, 5vw, 56px); margin: 0; padding: 0; list-style: none; }
.yr { display: grid; grid-template-columns: minmax(140px, 230px) minmax(0, 64ch); gap: 8px clamp(24px, 4vw, 48px); align-items: baseline; }
.yr__year { margin: 0; font: 400 clamp(40px, 4.4vw, 64px)/1 var(--brush); color: var(--cinnabar); }
.yr__title { margin: 0 0 8px; font: 600 clamp(19px, 1.6vw, 22px)/1.35 var(--sans); }
.yr__text p { margin: 0; }
.yr__text .yr__stats { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 4px 24px; font-size: 16px; color: var(--muted); }
.yr__stats b { font-weight: 700; color: var(--ink); }
@media (max-width: 699px) { .yr { grid-template-columns: minmax(0, 1fr); } }

/* ═══ 4. Drawings and photographs: fanned prints ═════════════════════════
   Without script (no .is-fan): a plain open grid, every picture shown.
   With story.js (.is-fan), each row is a stack of prints on a desk: every
   print in the first cell of the grid, so it is exactly one column wide,
   each turned and nudged by its own fixed amount (--sr, --sx, --sy from the
   build), the first on top and three edges showing beneath it; the rest wait
   under them, unseen. The sign (or a click on the stack) deals them out
   (.is-open): the same grid, a gentle wave down each row, a small turn kept
   (--fr). story.js moves each print from one place to the other with a
   transform only (FLIP), so the layout itself never animates. */
.draw .wrap { padding-top: clamp(48px, 6vw, 80px); padding-bottom: clamp(56px, 7vw, 96px); }
.draw__h { margin-bottom: clamp(24px, 3vw, 40px); max-width: 22ch; }
.strip + .strip { margin-top: clamp(32px, 4vw, 56px); }
.strip__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-bottom: 16px; }
.draw__sub { margin: 0; font: 400 clamp(28px, 3vw, 40px)/1 var(--brush); }

.strip__sign {
  box-sizing: border-box; width: 48px; height: 48px; flex: none;
  display: inline-grid; place-items: center; padding: 0;
  border: 1px solid var(--faint); border-radius: 2px;
  background: transparent; color: var(--ink); cursor: pointer;
  transition: color .12s, border-color .12s;
}
.strip__sign[hidden] { display: none; }
.strip__sign:hover { color: var(--cinnabar); border-color: currentColor; }
.strip__sign .ic { width: 26px; height: 26px; }
.strip__sign[aria-expanded="false"] .ic--gather,
.strip__sign[aria-expanded="true"] .ic--spread { display: none; }

.strip__list {
  --cols: 5;
  display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 32px) clamp(14px, 2vw, 28px);
  align-items: start; margin: 0; padding: 0; list-style: none;
}
.strip--works .strip__list { --cols: 3; }
.cell { margin: 0; }
.work { margin: 0; }
.tile {
  display: block; box-sizing: border-box; width: 100%; padding: 0; border: 0; border-radius: 0;
  background: var(--tile); cursor: zoom-in;
}
.tile img { display: block; width: 100%; height: auto; }
.work figcaption { margin-top: 10px; font-size: 16px; line-height: 1.45; color: var(--muted); }
.work__title { display: block; font: 400 24px/1.1 var(--brush); color: var(--ink); }
@media (max-width: 1099px) { .strip__list { --cols: 3; } }
@media (max-width: 699px) {
  .strip__list, .strip--works .strip__list { --cols: 2; gap: 18px 14px; }
}

/* a print: a thin paper edge round the picture */
.is-fan .tile {
  padding: 5px; background: var(--disc); border: 1px solid var(--rule);
  transform: rotate(var(--fr));
}
.is-fan .strip__list, .is-fan .cell { position: relative; }
.is-fan .tile:focus-visible { outline-offset: 4px; }

/* closed: the stack */
.is-fan:not(.is-open) .strip__desk { cursor: pointer; padding: 10px 0 14px; }
.is-fan:not(.is-open) .cell { grid-area: 1 / 1; z-index: var(--z); }
.is-fan:not(.is-open) .cell:nth-child(n+5) { position: absolute; top: 0; left: 0; width: 100%; opacity: 0; }
.is-fan:not(.is-open) .tile { transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); }
.is-fan:not(.is-open) figcaption { display: none; }

/* open: rows that rise and fall a little (a layout offset, so FLIP measures it) */
.is-fan.is-open .cell:nth-child(5n+2), .is-fan.is-open .cell:nth-child(5n+4) { margin-top: 14px; }
.is-fan.is-open .cell:nth-child(5n+3) { margin-top: 22px; }
@media (max-width: 1099px) {
  .is-fan.is-open .cell:nth-child(n) { margin-top: 0; }
  .is-fan.is-open .cell:nth-child(3n+2) { margin-top: 16px; }
}
@media (min-width: 1100px) {
  .strip--works.is-fan.is-open .cell:nth-child(n) { margin-top: 0; }
  .strip--works.is-fan.is-open .cell:nth-child(3n+2) { margin-top: 18px; }
}
@media (max-width: 699px) {
  .is-fan.is-open .cell:nth-child(n) { margin-top: 0; }
  .is-fan.is-open .cell:nth-child(2n) { margin-top: 14px; }
}

/* hover, on a fine pointer only: the print straightens and its edge takes the
   accent. No lift, no scale, no glow. */
.is-fan .tile { transition: transform .15s ease-out, border-color .15s ease-out; }
@media (hover: hover) and (pointer: fine) {
  .is-fan.is-open .tile:hover { transform: rotate(0deg); border-color: var(--cinnabar); }
}
/* while dealing or gathering, each print turns on the same clock as it travels */
.is-fan.is-moving .cell { z-index: var(--z); }
.is-fan.is-moving .tile {
  transition: transform var(--deal, 520ms) cubic-bezier(.22, 1, .36, 1) calc(var(--lag, 0) * 30ms);
}

/* ═══ 5. Let's build something ═══════════════════════════════════════════ */
.end__wrap {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 40px; align-items: start;
  padding-top: clamp(80px, 11vw, 150px); padding-bottom: 40px;
}
.end__h { margin: 0 0 28px; font: 400 clamp(52px, 7.6vw, 112px)/1 var(--brush); }
.end__p { margin: 0 0 24px; max-width: 60ch; font-size: clamp(18px, 1.4vw, 20px); }
.end__links { display: flex; flex-wrap: wrap; gap: 4px 34px; margin: 0; padding: 0; list-style: none; font-size: 19px; }
.end__links a { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; }
.end__foot { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; margin-top: 24px; }
.end__foot p { margin: 0; font-size: 14px; color: var(--muted); }
.end__sig { width: clamp(150px, 17vw, 240px); height: auto; display: block; }
.ink--end { bottom: auto; height: calc(var(--seg) * 1.35); }

/* ═══ Lightbox ═══════════════════════════════════════════════════════════ */
.lb {
  box-sizing: border-box; width: 100vw; height: 100dvh; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; background: var(--ground); color: var(--ink);
}
.lb[open] { display: grid; grid-template-columns: 56px minmax(0, 1fr) 56px; align-items: center; }
.lb::backdrop { background: rgb(0 0 0 / .6); }
.lb__fig { grid-column: 2; margin: 0; padding: 64px 0 24px; display: flex; flex-direction: column; align-items: center; gap: 12px; min-width: 0; }
.lb__fig img { display: block; max-width: 100%; max-height: calc(100dvh - 170px); width: auto; height: auto; }
.lb__fig figcaption { max-width: 60ch; font-size: 15px; color: var(--muted); text-align: center; }
.lb__btn {
  width: 48px; height: 48px; display: grid; place-items: center; padding: 0;
  border: 0; background: transparent; color: var(--ink); cursor: pointer;
  transition: color .12s;
}
.lb__btn:hover { color: var(--cinnabar); }
.lb__btn .ic { width: 28px; height: 28px; }
.lb__x { position: absolute; top: 10px; right: 10px; }
.lb__prev { grid-column: 1; justify-self: center; }
.lb__next { grid-column: 3; justify-self: center; }

/* ═══ Scroll-driven drawing, where the browser has scroll timelines ═════════
   The pen sits at 65% of the way down the screen: a stretch of line starts to
   draw when its top reaches that height and finishes as its bottom does, so
   the stretches hand over to each other and the line reads as one. */
@supports (animation-timeline: view()) {
  html.motion .open { view-timeline: --pin-open block; view-timeline-inset: var(--head) 0px; }
  html.motion .four { view-timeline: --pin-four block; view-timeline-inset: var(--head) 0px; }

  html.motion:not(.paused) .ink:not(.ink--open) > * { view-timeline: --pen block; }
  html.motion:not(.paused) .ink:not(.ink--open) .d {
    animation: draw linear both;
    animation-timeline: --pen;
    animation-range: cover 35vh cover calc(100% - 65vh);
  }

  html.motion:not(.paused) .ink--open .d:not(.flick) {
    animation: draw linear both;
    animation-timeline: --pin-open;
    animation-range: contain var(--s) contain var(--e);
  }

  @media (min-height: 620px) {
    html.motion .four__item, html.motion .four__mark {
      animation: swap-mid linear both;
      animation-timeline: --pin-four;
      animation-range: contain var(--s) contain var(--e);
    }
    html.motion .four__item[data-swap="first"], html.motion .four__mark[data-swap="first"] { animation-name: swap-first; }
    html.motion .four__item[data-swap="last"], html.motion .four__mark[data-swap="last"] { animation-name: swap-last; }
    html.motion:not(.paused) .four__emblem .d {
      animation: draw linear both;
      animation-timeline: --pin-four;
      animation-range: contain var(--s) contain var(--e);
    }
  }
}
@keyframes swap-first { 0%, 88% { opacity: 1; z-index: 2; } 100% { opacity: 0; z-index: 0; } }
@keyframes swap-mid { 0% { opacity: 0; z-index: 0; } 12%, 88% { opacity: 1; z-index: 2; } 100% { opacity: 0; z-index: 0; } }
@keyframes swap-last { 0% { opacity: 0; z-index: 0; } 12%, 100% { opacity: 1; z-index: 2; } }
