/* ==========================================================================
   Fonts, self-hosted (Latin subsets) so the page doesn't wait on another server
   ========================================================================== */
@font-face {
  font-family: "EB Garamond"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/fonts/eb-garamond.woff2") format("woff2");
}
@font-face {
  font-family: "EB Garamond"; font-style: italic; font-weight: 400 800; font-display: swap;
  src: url("/fonts/eb-garamond-italic.woff2") format("woff2");
}
@font-face {
  font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/dm-mono.woff2") format("woff2");
}

/* ==========================================================================
   The wordmark fills the hero, docks in the header as you scroll, and grows
   back at the top of the footer. Both moves are scroll-driven animations of
   transforms only, so the text is drawn once and never re-laid out.
   ========================================================================== */
/* type specimen axis: an integer, so it can feed a counter */
@property --wght   { syntax: "<number>";  inherits: true; initial-value: 400; }
/* the same value as a whole number, only to feed the readout's counter */
@property --wght-n { syntax: "<integer>"; inherits: true; initial-value: 400; }

:root {
  /* Light bookends, dark middle. The hero and footer are warm paper; the four
     sections between are deep shades of rose, sage, mist and lilac (all at
     about the same lightness), each with text in the pastel of its own hue
     (all ≥ 9:1 contrast). */
  --paper: #f4eee1;  --paper-ink: #2b221a;
  --rose:  #f2cec5;  --rose-deep:  #4b2a23;
  --sage:  #cadec6;  --sage-deep:  #24382a;
  --mist:  #c5dbee;  --mist-deep:  #1f3349;
  --lilac: #e1d0e9;  --lilac-deep: #3b2a46;
  --g: clamp(16px, 2.6vw, 44px);
  /* Type: EB Garamond does all the talking (wordmark, statements, list); DM Mono
     does the bookkeeping (labels, nav, numbers). Two voices, clearly split. */
  --serif: "EB Garamond", Garamond, "Times New Roman", Times, serif;
  --mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* the wordmark is ~5.44em wide (EB Garamond 400, -0.02em tracking) */
  --ratio: 5.44;
  --big: calc((100vw - 2 * var(--g)) / var(--ratio));
  /* Docked size as a fraction of full size. Set by the script in the page head
     from clamp(92px, 9.5vw, 150px) ÷ (100vw − 2 × gutter); this is the fallback. */
  --k: .1;
  /* One screen's height. Mobile Safari's svh can follow the toolbar as it
     slides, which resizes every pane mid-scroll, so the page head pins this
     to a pixel value that only changes when the width does. This is the
     fallback without the script. */
  --screen: 100vh;
  timeline-scope: --hero, --foot; /* lets the fixed wordmark and header read the sections' timelines */
}

@supports (height: 100svh) { :root { --screen: 100svh; } }

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--paper); scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--paper-ink);
  font-family: var(--serif);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}
main { overflow-x: clip; }
a { color: inherit; text-decoration: none; }
p, ol, ul { margin: 0; }
ol, ul { list-style: none; padding: 0; }
img { display: block; max-width: 100%; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.label { font-family: var(--mono); font-size: 12px; line-height: 1.3; font-weight: 400; letter-spacing: .04em; text-transform: uppercase; }
/* Arrows are drawn, not typed: neither font has ↗ or ↩, and iOS fills the gap
   with its colour emoji */
.arr {
  display: inline-block; width: .72em; height: .72em; vertical-align: -.02em;
  background: currentColor;
  mask: var(--arr) center / contain no-repeat;
}
.arr--ne { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 12.5l9-9M5.5 3.5h7v7'/%3E%3C/svg%3E"); }
.arr--down { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.5v13M3 9.5l5 5 5-5'/%3E%3C/svg%3E"); }
.arr--up { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 14.5v-13M3 6.5l5-5 5 5'/%3E%3C/svg%3E"); }
.arr--left { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 8h-13M6.5 3l-5 5 5 5'/%3E%3C/svg%3E"); }
.arr--right { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.5 8h13M9.5 3l5 5-5 5'/%3E%3C/svg%3E"); }
.arr--back { --arr: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2.5v4.5a3 3 0 0 1-3 3H2.5M6 6.5 2.5 10 6 13.5'/%3E%3C/svg%3E"); }
.label__num {
  display: inline-block; margin-right: .6em; padding: .1em .55em .05em;
  border: 1px solid currentColor; border-radius: 99px;
}


/* ==========================================================================
   Fixed wordmark + header
   ========================================================================== */
.chrome { display: contents; }

/* A white wordmark in difference mode, so every pane edge and drawing cuts
   through the letters: white minus a pastel is its dark complement. The blend
   sits on the two small elements, not on a layer covering the whole screen. */
.logo, .header {
  position: fixed; z-index: 50;
  color: #fff;
  mix-blend-mode: difference;
}

.header {
  top: var(--g); left: var(--g); right: var(--g);
  display: flex; justify-content: space-between; align-items: flex-start;
  font-family: var(--mono); font-size: 12px; line-height: 1.4; font-weight: 400; letter-spacing: .04em; text-transform: uppercase;
  /* fades in as the wordmark lands... */
  animation: header-in linear both;
  animation-timeline: --hero;
  animation-range: cover 92% cover 100%;
}
/* ...and its contents fade out as the footer takes over */
.header > * {
  animation: header-out linear both;
  animation-timeline: --foot;
  animation-range: cover 0% cover 12%;
}
@keyframes header-in  { from { opacity: 0; visibility: hidden; } }
@keyframes header-out { to   { opacity: 0; visibility: hidden; } }
.header__left { display: flex; flex-direction: column; }
.header a:hover { text-decoration: underline; }

.logo {
  top: 0; left: 50%;
  font-family: var(--serif); font-weight: 400;
  font-size: var(--big); line-height: .8;
  letter-spacing: -.02em; padding-right: .02em;
  white-space: nowrap;
  pointer-events: none;
  transform-origin: 50% 0;
  will-change: transform;
  /* centred in the hero → small, in the top gutter */
  animation: logo-dock linear both;
  animation-timeline: --hero;
  animation-range: cover 50% cover 100%;
}
@keyframes logo-dock {
  from { translate: -50% calc(.5 * var(--screen) - .4 * var(--big)); scale: 1; }
  to   { translate: -50% var(--g); scale: var(--k); }
}
/* The inner text undoes the docked scale as the footer arrives, so the
   wordmark grows back to full size where it is (k × 1/k = 1) */
.logo__text {
  display: block;
  transform-origin: 50% 0;
  animation: logo-undock linear both;
  animation-timeline: --foot;
  animation-range: cover 0% cover 50%;
}
@keyframes logo-undock { to { scale: calc(1 / var(--k)); } }

/* Browsers without scroll-driven animations: the wordmark simply sits in the hero */
@supports not (animation-timeline: view()) {
  .logo, .header { position: absolute; }
  .logo { translate: -50% calc(.5 * var(--screen) - .4 * var(--big)); }
}

/* First load: the confetti pops in, then the wordmark and tagline arrive word
   by word, rising out of a blur, once the fonts are in (the page script adds
   .is-ready), so nothing ever flashes in a fallback typeface. Without the
   script, everything shows at once. */
.js:not(.is-ready) .logo__text > span, .js:not(.is-ready) .hero__tagline > span, .js:not(.is-ready) .hero__scroll { opacity: 0; }
.logo__text > span, .hero__tagline > span { display: inline-block; }
.is-ready .logo__text > span { animation: arrive 1.4s calc(.5s + var(--n, 0) * .28s) cubic-bezier(.2, .7, .2, 1) backwards; }
.is-ready .hero__tagline > span { animation: arrive 1.1s calc(1.3s + var(--n, 0) * .18s) cubic-bezier(.2, .7, .2, 1) backwards; }
.is-ready .hero__scroll { animation: arrive 1s 1.9s cubic-bezier(.2, .7, .2, 1) backwards; }
/* Every arrival fills backwards only: once it ends, nothing is left set.
   Safari draws anything with a filter on its own layer and can clip ink
   outside the box (italic overhangs, whole rows), so the blur must not stay. */
@keyframes arrive {
  from { opacity: 0; translate: 0 .4em; filter: blur(.12em); }
}

/* ==========================================================================
   First panel: doodle confetti. hero.js scatters small one-colour shapes;
   the cursor or a finger pushes them aside, a click or tap throws
   them outward, and springs bring them home. Transforms only.
   ========================================================================== */
.hero {
  position: relative;
  height: var(--screen);
  background: var(--paper);
  view-timeline-name: --hero;
  overflow: clip; isolation: isolate;
  touch-action: pan-y;
}
.hero__meta, .hero__scroll { position: absolute; bottom: var(--g); }
.hero__meta { left: var(--g); }
.hero__tagline { font-style: italic; font-weight: 400; font-size: clamp(20px, 1.8vw, 28px); line-height: 1; }
.hero__scroll { right: var(--g); }

.hero__bits {
  position: absolute; inset: 0; z-index: -1;
  color: var(--paper-ink);
  /* fade back as the hero scrolls away */
  animation: bits-out linear both;
  animation-timeline: --hero;
  animation-range: exit 0% exit 100%;
}
@keyframes bits-out { to { opacity: .2; } }
.bit {
  position: absolute; left: 0; top: 0;
  width: var(--size); height: var(--size);
  will-change: transform;
}
.bit svg { display: block; width: 100%; height: 100%; overflow: visible; animation: bit-in 1s var(--delay) cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes bit-in { from { scale: 0; } }

@media (prefers-reduced-motion: reduce) {
  .bit svg { animation: none; }
  .is-ready .logo__text > span, .is-ready .hero__tagline > span, .is-ready .hero__scroll { animation-duration: .01s; animation-delay: 0s; }
}

/* ==========================================================================
   Static panes (palette, no animation)
   ========================================================================== */
.pane {
  min-height: var(--screen);
  padding: calc(var(--g) + 90px) var(--g) var(--g);
  display: flex; flex-direction: column; gap: 6vh;
}
.pane--rose { --pane-bg: var(--rose-deep); background: var(--pane-bg); color: var(--rose); }
.pane--sage { --pane-bg: var(--sage-deep); background: var(--pane-bg); color: var(--sage); }
.pane--mist { --pane-bg: var(--mist-deep); background: var(--pane-bg); color: var(--mist); }
.pane--lilac { --pane-bg: var(--lilac-deep); background: var(--pane-bg); color: var(--lilac); }
.pane--paper { --pane-bg: var(--paper); background: var(--pane-bg); color: var(--paper-ink); }

.pane__grid { flex: 1; display: grid; grid-template-columns: 7fr 5fr; gap: var(--g); align-items: center; }
.pane__big {
  font-size: clamp(30px, 4.1vw, 70px); font-weight: 400; line-height: 1.08; letter-spacing: -.012em;
  text-wrap: pretty;
}
.pane__big em { font-style: italic; }

/* "fonts" can't sit still: it cycles through the weight axis. A hidden heavy copy
   reserves the widest width so the rest of the sentence never reflows. */
.w-fonts { display: inline-grid; }
.w-fonts > span, .w-fonts::after { grid-area: 1 / 1; }
.w-fonts::after { content: attr(data-w); font-weight: 800; visibility: hidden; }
.w-fonts > span {
  font-weight: var(--wght);
  animation: axes 5s ease-in-out infinite;
}
/* typeface vs font, set as exactly that: a typeface (italic Garamond) and a font (a monospaced file) */
.w-typeface { font-style: italic; }
.w-font {
  font-family: var(--mono); font-size: .72em; letter-spacing: -.02em; vertical-align: .08em;
  padding: .02em .28em; border: 1px dashed currentColor; border-radius: .2em;
}

/* Specimen: nobody asked, so it answers anyway — one typeface, endless fonts.
   The weight eases continuously; the readout is a counter fed by --wght-n. */
.specimen {
  margin: 0; justify-self: center; width: min(100%, 460px); aspect-ratio: 1;
  display: grid; grid-template-rows: 1fr auto;
  padding: clamp(14px, 1.6vw, 22px);
  border: 1.5px solid currentColor; border-radius: clamp(18px, 2vw, 28px);
  container-type: inline-size;
  animation: axes 5s ease-in-out infinite;
}
.specimen__glyph {
  place-self: center;
  font-size: 62cqi; line-height: 1; letter-spacing: -.03em;  /* scales with the card */
  font-weight: var(--wght);
}
.specimen__cap {
  display: flex; justify-content: space-between; gap: 8px;
  padding-top: 12px; border-top: 1px solid currentColor;
  font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
}
.specimen__readout { counter-reset: w var(--wght-n); font-variant-numeric: tabular-nums; }
.specimen__readout::before { content: "wght " counter(w); }
@keyframes axes {
  0%, 100% { --wght: 400; --wght-n: 400; }
  50%      { --wght: 800; --wght-n: 800; }
}
.pane__art { width: 100%; max-width: 520px; justify-self: center; }

/* Doodles (Miroodles, converted from Sketch), in one colour: the ink is the
   section's text colour, and what was coloured is a light wash of the same. */
.doodle {
  display: block; overflow: visible;
}
.doodle path { transform-box: fill-box; transform-origin: center; }
.doodle__ink path { fill: currentColor; }
.doodle__color path { fill: currentColor; fill-opacity: .24; }

/* The wash drifts a few pixels off the ink and back, like a print slightly
   out of register; each piece on its own rhythm */
.doodle__color path { animation: register 4s ease-in-out infinite alternate; animation-delay: calc(var(--i) * -7s); }
@keyframes register {
  0%   { translate: 0 0; }
  50%  { translate: 4px -3px; }
  100% { translate: -3px 2px; }
}
/* Pieces pop in one after another once the drawing is well into view
   (reveal.js adds .is-in), over a couple of seconds rather than a few pixels
   of scroll, and again each time it comes back on screen */
.doodle.reveal:not(.is-in) path { opacity: 0; }
.doodle.is-in path { animation: pop .8s calc(var(--i) * 1.8s) cubic-bezier(.3, 1.5, .5, 1) backwards; }
.doodle.is-in .doodle__color path {
  animation: pop .8s calc(var(--i) * 1.8s) cubic-bezier(.3, 1.5, .5, 1) backwards,
             register 4s calc(var(--i) * -7s) ease-in-out infinite alternate;
}
@keyframes pop {
  from { opacity: 0; scale: .3; }
  60%  { opacity: 1; }
  to   { opacity: 1; scale: 1; }
}

.pane__lede { font-size: clamp(20px, 2vw, 32px); font-style: italic; font-weight: 400; line-height: 1.25; max-width: 30ch; }
.pane__list { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.pane__list li {
  border-top: 1px solid currentColor;
  font-size: clamp(32px, 4.8vw, 84px); font-weight: 400; letter-spacing: -.015em; line-height: 1;
}
/* each row is a link to that thing's own page */
.pane__list li > a {
  display: grid; grid-template-columns: clamp(2.5rem, 7vw, 7rem) 1fr auto; align-items: center; gap: var(--g);
  padding: 2vh 0;
}
.pane__list li > a:focus-visible { outline: 1.5px solid currentColor; outline-offset: 4px; }
.li__num { font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; }
.li__text { transition: translate .4s cubic-bezier(.3, 1.4, .5, 1); }
.li__ico {
  width: clamp(40px, 4.6vw, 72px); height: clamp(40px, 4.6vw, 72px);
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
  transition: rotate .5s cubic-bezier(.3, 1.8, .5, 1), scale .5s cubic-bezier(.3, 1.8, .5, 1);
}
.pane__list li:hover .li__text { font-style: italic; translate: .25em 0; }
.pane__list li:hover .li__ico { rotate: -12deg; scale: 1.15; }
.pane__list li:last-child { border-bottom: 1px solid currentColor; }

/* "amateur" gets underlined by hand — the scribble draws itself just after the word arrives */
.scribble { position: relative; white-space: nowrap; font-style: italic; }
.scribble::after {
  content: ""; position: absolute; left: -4%; right: -4%; bottom: -.16em; height: .32em;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 24' preserveAspectRatio='none'%3E%3Cpath d='M4 14c28-9 48 5 78-3s56-7 82 0 22 3 32-5M20 19c40-5 90-6 150-3' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
.lines:not(.is-in) .scribble::after { clip-path: inset(0 100% 0 0); }
.is-in .scribble::after { animation: draw 1s .15s cubic-bezier(.6, 0, .3, 1) backwards; }
@keyframes draw { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* ==========================================================================
   Text arrives as each section scrolls in. Statements (.lines) rise line by
   line out of a mask: reveal.js puts each word in a clipping .mask and moves
   the .word inside it up with the scroll, then adds .is-in once every line
   is up. Other things are marked .reveal and get .is-in once on screen.
   Without the script, or with reduced motion, nothing is hidden.
   ========================================================================== */
.lines .mask, .lines .word { display: inline-block; }
/* the clip reaches past the box for italic overhangs and descenders, and
   comes off once a line is up, so nothing (the scribble) stays cut */
.lines .mask:not(.is-up), .lines .mask.is-load { clip-path: inset(-.4em -.3em -.12em -.3em); }
.lines .mask.is-load .word { animation: line-up 1.1s calc(.35s + var(--l) * .12s) cubic-bezier(.2, .7, .2, 1) backwards; }
@keyframes line-up { from { translate: 0 115%; } }

.label.reveal:not(.is-in), .specimen.reveal:not(.is-in) { opacity: 0; }
.label.is-in { animation: arrive .9s cubic-bezier(.2, .7, .2, 1) backwards; }
.specimen.is-in {
  animation: axes 5s ease-in-out infinite, card-in 1.2s .4s cubic-bezier(.3, 1.4, .5, 1) backwards;
}
@keyframes card-in {
  from { opacity: 0; scale: .85; rotate: -4deg; }
}

.pane__list.reveal:not(.is-in) li { opacity: 0; }
.pane__list.is-in li { animation: arrive 1s calc(var(--n) * .14s) cubic-bezier(.2, .7, .2, 1) backwards; }

/* ==========================================================================
   Last panel
   ========================================================================== */
.footer {
  position: relative;
  height: var(--screen);
  min-height: 520px;
  background: var(--paper);
  color: var(--paper-ink);
  padding: var(--g);
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto 1fr auto;
  --pane-bg: var(--paper);
  view-timeline-name: --foot;
}
/* reveal.js draws the elastic top edge here; it reaches up over the section above */
.footer__edge {
  position: absolute; left: 0; top: -48px; z-index: 1;
  width: 100%; height: 208px;
  pointer-events: none;
}
.footer__space { grid-column: 1 / -1; height: calc(.8 * var(--big) + var(--g)); }
.footer__main { align-self: center; }
/* The link slides up into the middle of the screen as the footer arrives */
@supports (animation-timeline: view()) {
  .footer__main, .footer__art {
    animation: rise linear both;
    animation-timeline: --foot;
    animation-range: cover 15% cover 50%;
  }
}
@keyframes rise { from { opacity: 0; translate: 0 35vh; } }
.footer__link {
  display: inline-block; margin-top: 14px;
  font-size: clamp(32px, 4.8vw, 84px); font-weight: 400; letter-spacing: -.015em; line-height: 1.1;
  text-decoration: underline wavy; text-decoration-thickness: .04em; text-underline-offset: .2em;
  transition: font-weight .4s ease;
}
.footer__link span { display: inline-block; transition: translate .4s cubic-bezier(.3, 1.6, .5, 1); }
.footer__link:hover { font-weight: 600; }
.footer__link:hover span { translate: .12em -.12em; }
.footer__art { align-self: center; width: clamp(180px, 24vw, 360px); }
.footer__bottom { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 8px var(--g); border-top: 1px solid currentColor; padding-top: 14px; }

/* ==========================================================================
   Thing pages (/watches/ and the rest): one page per item in "Things made
   with care", each in one of the home page's colours. A big title with its
   icon drawing itself, three short notes, the owner's own picks, then on to
   the next thing.
   ========================================================================== */
.thing { min-height: var(--screen); padding: var(--g); display: flex; flex-direction: column; }
.thing-head { display: flex; justify-content: space-between; gap: var(--g); }
.thing-head a:hover, .thing-next a:hover { text-decoration: underline; }

.thing__hero {
  min-height: calc(var(--screen) - 2 * var(--g) - 20px);
  display: grid; grid-template-columns: 1fr auto; grid-template-rows: 1fr auto auto; gap: 3vh var(--g);
  align-items: end; padding-bottom: 8vh;
}
.thing__title {
  grid-column: 1; margin: 0;
  font-size: clamp(56px, 11vw, 190px); font-weight: 400; line-height: .9; letter-spacing: -.03em;
  text-wrap: balance;
}
.thing__ico {
  grid-column: 2; grid-row: 1 / 3; align-self: center;
  width: clamp(110px, 20vw, 300px); height: clamp(110px, 20vw, 300px);
  fill: none; stroke: currentColor; stroke-width: 1; stroke-linecap: round; stroke-linejoin: round;
  /* stroke-dash* are inherited, so they reach the paths inside <use>: the
     icon draws itself line by line, then sways a little */
  stroke-dasharray: 160; stroke-dashoffset: 0;
  animation: ico-draw 2.6s .3s cubic-bezier(.5, 0, .3, 1) backwards, ico-sway 6s 3s ease-in-out infinite;
}
@keyframes ico-draw { from { stroke-dashoffset: 160; } }
@keyframes ico-sway { 50% { rotate: -6deg; } }
.thing__lede { grid-column: 1; }

/* the hero arrives word by word, like the home page's name */
.thing__title > span { display: inline-block; }
.js:not(.is-ready) .thing__title > span { opacity: 0; }
.is-ready .thing__title > span { animation: arrive 1.3s calc(.2s + var(--n, 0) * .2s) cubic-bezier(.2, .7, .2, 1) backwards; }

.thing__notes { display: flex; flex-direction: column; }
.thing__note {
  display: grid; grid-template-columns: 7fr 5fr; gap: var(--g); align-items: start;
  padding: 6vh 0; border-top: 1px solid currentColor;
}
.thing__note .label { grid-column: 2; grid-row: 1; padding-top: .9em; }
.thing__note .pane__big { grid-column: 1; grid-row: 1; font-size: clamp(28px, 3.4vw, 58px); }

.thing__mine { padding: 8vh 0; border-top: 1px solid currentColor; display: grid; grid-template-columns: 7fr 5fr; gap: var(--g); }
.thing__mine dl { margin: 0; display: grid; gap: 2.4vh; }
.thing__mine div { display: grid; grid-template-columns: minmax(0, 13em) 1fr; gap: 6px 16px; align-items: baseline; }
.thing__mine dt { font-family: var(--mono); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; }
.thing__mine dd { margin: 0; font-size: clamp(22px, 2.2vw, 34px); line-height: 1.15; }
/* the gaps left for the owner to fill in */
.fill {
  font-family: var(--mono); font-size: .62em; letter-spacing: -.01em; vertical-align: .1em;
  padding: .05em .4em; border: 1px dashed currentColor; border-radius: .25em; opacity: .8;
}
.thing__mine .label { padding-top: .5em; }

/* a joke, with the pause doing most of the work */
.joke { padding: 10vh 0; border-top: 1px solid currentColor; }
.joke .pane__big { max-width: 22ch; }
.joke__punch { margin-top: 3vh; font-size: clamp(30px, 4.1vw, 70px); font-style: italic; line-height: 1.08; }
.joke.reveal:not(.is-in) .joke__punch { opacity: 0; }
.joke.is-in .joke__punch { animation: arrive 1.2s 2.8s cubic-bezier(.2, .7, .2, 1) backwards; }

.thing-next {
  margin-top: auto; padding-top: 14px; border-top: 1px solid currentColor;
  display: flex; justify-content: space-between; gap: 8px var(--g); flex-wrap: wrap;
}
.thing-next .arr { transition: translate .4s cubic-bezier(.3, 1.6, .5, 1); }
.thing-next__prev:hover .arr { translate: -.3em 0; }
.thing-next__next:hover .arr { translate: .3em 0; }
.thing-next__big { display: block; margin-top: 8px; font-family: var(--serif); text-transform: none; letter-spacing: -.015em; font-size: clamp(28px, 3.4vw, 56px); line-height: 1.05; }
.thing-next__next { text-align: right; }

@media (max-width: 767px) {
  .thing__hero { grid-template-columns: 1fr; grid-template-rows: 1fr auto auto auto; }
  .thing__ico { grid-column: 1; grid-row: 1; align-self: end; }
  .thing__note, .thing__mine { grid-template-columns: 1fr; }
  .thing__note .label, .thing__note .pane__big { grid-column: 1; grid-row: auto; padding-top: 0; }
  .thing__mine div { grid-template-columns: 1fr; }
}

@media (max-width: 767px) {
  .pane__grid { grid-template-columns: 1fr; }
  .pane__art { max-width: min(70%, 320px); }
  .pane__list li > a { grid-template-columns: 2.2em 1fr auto; gap: 12px; }
  /* Footer stacks: wordmark space → illustration fills the gap → link → meta row */
  .footer { grid-template-columns: 1fr; grid-template-rows: auto 1fr auto auto; }
  .footer__main { grid-row: 2; }
  .footer__art { grid-row: 3; align-self: end; justify-self: end; width: min(44vw, 180px); padding-bottom: 3vh; }
  .footer__link { font-size: clamp(28px, 9vw, 40px); overflow-wrap: anywhere; }
  .footer__bottom { grid-row: 4; flex-wrap: wrap; }
  .footer__colophon { order: 3; flex-basis: 100%; opacity: .7; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .w-fonts > span, .specimen, .specimen__glyph,
  .doodle path { animation: none; opacity: 1; }
  .scribble::after { animation: none; clip-path: none; }
  .thing__ico { animation: none; stroke-dasharray: none; }
  .is-ready .thing__title > span { animation-duration: .01s; animation-delay: 0s; }
  .footer__main, .footer__art { animation: none; }
}
