:root {
  color-scheme: light;
  --paper: #e9eee8;
  --paper-deep: #dfe7df;
  --surface: #f8f7f0;
  --ink: #26372e;
  --ink-soft: #65726a;
  --line: rgba(38, 55, 46, 0.22);
  --line-strong: rgba(38, 55, 46, 0.52);
  --green: #315d50;
  --green-dark: #1e4438;
  --pink: #e5a1b6;
  --pink-deep: #9c4f70;
  --pink-wash: #f3d9e1;
  --pink-light: #f2c8d4;
  --gold: #c6a341;
  --shadow: rgba(23, 38, 30, 0.24);
  --page-pad: clamp(22px, 4.5vw, 74px);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #14241d;
  --paper-deep: #0f1d17;
  --surface: #1b2d25;
  --ink: #edf0e9;
  --ink-soft: #aab7ae;
  --line: rgba(229, 235, 226, 0.16);
  --line-strong: rgba(229, 235, 226, 0.36);
  --green: #8cbaa4;
  --green-dark: #b4d3c4;
  --pink: #e4a0b6;
  --pink-deep: #f1b7c9;
  --pink-wash: #4b2d39;
  --pink-light: #ecc5cf;
  --gold: #d3b75f;
  --shadow: rgba(0, 0, 0, 0.44);
}

* {
  box-sizing: border-box;
}

/* No image may exceed its container, whatever else is or is not applied.
   Without this, a screenshot renders at its natural 2360px or 2880px and
   bursts the layout. */
img {
  max-width: 100%;
  height: auto;
}

html {
  scroll-behavior: smooth;
  background: var(--paper);
}

body {
  margin: 0;
  color: var(--ink);
  background:
    radial-gradient(circle at 1px 1px, rgba(46, 75, 61, 0.095) 0.8px, transparent 0.9px) 0 0 / 22px 22px,
    var(--paper);
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 16px;
  line-height: 1.55;
  transition: color 240ms ease, background-color 240ms ease;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  font: inherit;
}

a {
  color: inherit;
}

.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
  padding: 10px 14px;
  background: var(--ink);
  color: var(--surface);
  transform: translateY(-150%);
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  /* Sticky at every width. The catalogue is one long read, so the way out
     of it has to travel with you rather than sit at the very top. Padded
     rather than margined so the backdrop spans the full width as content
     scrolls beneath it. */
  position: sticky;
  top: 0;
  z-index: 60;
  min-height: 108px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 30px;
  padding: 0 var(--page-pad);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  transition: min-height 220ms ease, box-shadow 220ms ease;
}

.site-header.is-stuck {
  min-height: 68px;
  box-shadow: 0 10px 26px color-mix(in srgb, var(--shadow) 45%, transparent);
}

/* Anchor jumps must not land under the sticky header. Its height changes
   with viewport and stuck state, so the offset is measured rather than
   guessed; the literal here is only the pre-script fallback. */
:where(#top, #paperwatcher, #workspace, #propertill, #storageinventory, #moon, #moon-clicker, #rain, #petrichor-garden, #why-index, #index, #contact, #about) {
  scroll-margin-top: calc(var(--header-h, 108px) + 14px);
}

.wordmark {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  font-family: "Newsreader", serif;
  font-size: 28px;
  font-weight: 500;
  line-height: 1;
}

.wordmark-dot {
  color: var(--pink-deep);
}

.wordmark small {
  align-self: flex-end;
  margin: 0 0 1px 3px;
  color: var(--ink-soft);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.sakura-mark {
  width: 30px;
  height: 30px;
  overflow: visible;
}

/* The same botanical emblem the dashboard and favicon use, in the
   portfolio's own tokens: two-tone petals, a plum outline, brass stamens. */
.sakura-mark .mark-petals path {
  stroke: var(--pink-deep, #9c4f70);
  stroke-width: 3;
  stroke-linejoin: round;
}

.sakura-mark .petal-lt { fill: var(--pink-light, #f2c8d4); }
.sakura-mark .petal-md { fill: var(--pink, #e5a1b6); }

.sakura-mark .mark-stamens path {
  fill: none;
  stroke: var(--gold, #c6a341);
  stroke-width: 2.4;
  stroke-linecap: round;
}

.sakura-mark .mark-stamens circle { fill: var(--gold, #c6a341); }

.sakura-mark .mark-eye {
  fill: var(--gold, #c6a341);
  stroke: var(--surface, #f8f7f0);
  stroke-width: 3.5;
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 42px);
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.primary-nav a {
  padding: 12px 0;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.primary-nav a:hover,
.primary-nav a:focus-visible {
  border-color: var(--pink-deep);
  outline: none;
}

.primary-nav a[aria-current="location"] {
  color: var(--pink-deep);
  border-color: var(--pink-deep);
}

.theme-toggle {
  justify-self: end;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  cursor: pointer;
}

.theme-toggle svg {
  width: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  color: var(--pink-deep);
  border-color: var(--pink-deep);
  outline: none;
}

.opening {
  min-height: calc(100svh - 108px);
  display: flex;
  flex-direction: column;
  padding: clamp(70px, 11vh, 130px) var(--page-pad) 38px;
}

.opening-kicker {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 34px;
  padding-bottom: 15px;
  border-bottom: 1px solid var(--line);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.opening-kicker span:first-child {
  color: var(--pink-deep);
}

.opening-title-wrap {
  flex: 1;
  display: grid;
  grid-template-columns: clamp(120px, 18vw, 280px) 1fr;
  align-items: center;
  padding: 42px 0;
}

.margin-note {
  align-self: start;
  margin: clamp(40px, 10vh, 100px) 0 0;
  color: var(--ink-soft);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  line-height: 1.8;
  text-transform: uppercase;
}

.margin-note::before {
  content: "";
  display: block;
  width: 44px;
  height: 1px;
  margin-bottom: 17px;
  background: var(--pink-deep);
}

.opening h1 {
  max-width: 1050px;
  margin: 0;
  font-family: "Newsreader", serif;
  font-size: clamp(68px, 10.2vw, 164px);
  font-weight: 400;
  letter-spacing: -0.055em;
  line-height: 0.82;
}

.opening h1 span {
  color: var(--green);
}

.opening-foot {
  display: grid;
  grid-template-columns: clamp(120px, 18vw, 280px) 1fr auto;
  align-items: end;
  gap: 0;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

.opening-foot p {
  grid-column: 2;
  max-width: 480px;
  margin: 0;
  color: var(--ink-soft);
  font-size: clamp(16px, 1.35vw, 20px);
}

.text-link {
  display: inline-flex;
  gap: 28px;
  padding-bottom: 4px;
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.text-link:hover,
.text-link:focus-visible {
  color: var(--pink-deep);
  border-color: var(--pink-deep);
  outline: none;
}

.case-study {
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.case-heading {
  display: grid;
  grid-template-columns: clamp(100px, 12vw, 180px) minmax(0, 1.5fr) minmax(300px, 0.8fr);
  gap: clamp(24px, 4vw, 76px);
  padding: clamp(70px, 10vw, 150px) var(--page-pad) clamp(50px, 7vw, 100px);
}

.catalogue-number {
  display: flex;
  flex-direction: column;
  padding-top: 10px;
  font-family: "IBM Plex Mono", monospace;
}

.catalogue-number span {
  font-size: 10px;
  letter-spacing: 0.14em;
}

.catalogue-number strong {
  color: var(--pink-deep);
  font-size: clamp(54px, 7vw, 104px);
  font-weight: 400;
  letter-spacing: -0.08em;
  line-height: 0.9;
}

.eyebrow,
.section-marker {
  margin: 0 0 20px;
  color: var(--pink-deep);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* The title is sized against its own column, not the viewport.

   10vw with a 72px floor measured the wrong box. The title sits in a grid
   column worth about 40 to 48 per cent of the viewport, so between 721px
   and 1600px the word outgrew the column and `overflow-wrap` did what it
   was told: "PaperWatcher" broke mid-word as "PaperWatc / her", and
   "Workspace" did the same below about 1100px.

   17cqi is derived rather than guessed. At the widest layout the column is
   929px and the title renders at 152px, giving a word 855px wide, so the
   word is about 5.6 times the font size. Keeping font x 5.6 inside the
   column means about 0.177 of the column, and 17cqi leaves a little room.

   The vw declaration above it is the fallback for a browser without
   container query units, which drops the cqi line and keeps a floor low
   enough not to reintroduce the break. overflow-wrap stays as a last
   resort: with this sizing nothing should reach it, but a longer title one
   day should still wrap rather than run off the page. */
.case-title-block {
  container-type: inline-size;
}

.case-title-block h2,
.work-index h2 {
  margin: 0;
  overflow-wrap: break-word;
  font-family: "Newsreader", serif;
  font-size: clamp(72px, 10vw, 152px);
  font-weight: 400;
  letter-spacing: -0.06em;
  line-height: 0.82;
}

/* Only the case titles change. The index heading is a short phrase with
   spaces in it, it wraps where it should, and it keeps the sizing above. */
.case-title-block h2 {
  font-size: clamp(40px, 7vw, 152px);
  font-size: clamp(40px, 17cqi, 152px);
}

/* A qualifier on a case-study title, for a name that is not settled yet.
   Block rather than inline, deliberately: the title is a single word at
   up to 152px and already fills its column, so an inline qualifier wraps
   at every width anyway and inherits the display face's 0.82 line-height
   as a tall, disconnected-looking line box. Setting it on its own line
   with a margin of its own makes the same result intentional and the
   same at every width.

   It also has to opt out of the display face's other settings rather
   than inherit them: -0.06em tracking is tuned for a 152px word and
   crushes text at this size. The clamp is its own rather than an em of
   the title, so it stays readable on a phone where the title drops to
   40px. */
.case-title-block h2 small {
  display: block;
  margin-top: 0.45em;
  color: var(--ink-soft);
  font-family: "IBM Plex Sans", sans-serif;
  font-size: clamp(12px, 1.1vw, 16px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.3;
}

.case-deck {
  max-width: 680px;
  margin: 38px 0 0;
  color: var(--ink-soft);
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.42;
}

.case-facts {
  align-self: end;
  margin: 0;
  border-top: 1px solid var(--line-strong);
}

.case-facts div {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 18px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.case-facts dt {
  color: var(--ink-soft);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.case-facts dd {
  margin: 0;
  font-size: 13px;
}

.status-dot {
  width: 7px;
  height: 7px;
  display: inline-block;
  margin-right: 7px;
  background: #3d9664;
  border-radius: 50%;
  box-shadow: 0 0 0 4px rgba(61, 150, 100, 0.13);
}

.hero-object {
  position: relative;
  margin: 0;
  padding: 34px var(--page-pad) 32px;
  overflow: hidden;
  color: #26372e;
  background:
    radial-gradient(circle at 77% 24%, rgba(229, 161, 182, 0.37), transparent 28%),
    linear-gradient(150deg, #d9e4da 0%, #f0ddd9 54%, #cbdcd1 100%);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.object-label,
.hero-object figcaption {
  position: relative;
  z-index: 4;
  display: flex;
  justify-content: space-between;
  gap: 24px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.object-label span:first-child {
  color: #8a3e5e;
}

.tablet-shadow {
  position: absolute;
  z-index: 0;
  left: 12%;
  right: 10%;
  bottom: 75px;
  height: 13%;
  background: rgba(40, 58, 49, 0.28);
  border-radius: 50%;
  filter: blur(35px);
  transform: rotate(-1.5deg);
}

.ipad {
  position: relative;
  z-index: 2;
  width: min(1240px, 91vw);
  /* iPad Air 11": 2360x1640 native, the resolution these screens
     were captured at. The bezel adds its own padding around it. */
  aspect-ratio: 2360 / 1640;
  margin: clamp(48px, 6vw, 90px) auto clamp(54px, 6vw, 84px);
  padding: clamp(13px, 1.25vw, 20px);
  background: linear-gradient(145deg, #39413e, #101714 42%, #27312c 88%);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: clamp(28px, 3vw, 50px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.45) inset,
    0 38px 70px rgba(31, 48, 39, 0.28),
    0 8px 18px rgba(31, 48, 39, 0.22);
  transform: rotate(-1.4deg);
}

.ipad-camera {
  position: absolute;
  z-index: 5;
  top: 50%;
  right: clamp(4px, 0.5vw, 8px);
  width: 5px;
  height: 5px;
  background: #070b09;
  border: 1px solid #4f5f57;
  border-radius: 50%;
  transform: translateY(-50%);
}

.ipad-screen {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  border-radius: clamp(18px, 2vw, 34px);
  background: #f4f5f2;
}

.workspace-ui {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 16.5% 1fr;
  overflow: hidden;
  background: #f4f5f2;
  border-radius: clamp(18px, 2vw, 34px);
  font-family: "IBM Plex Sans", sans-serif;
  transform: translateZ(0);
}

.ws-sidebar {
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: #f4f5f2;
  background: #191e1b;
}

.ws-brand {
  height: 13%;
  display: flex;
  align-items: center;
  gap: clamp(5px, 0.7vw, 11px);
  padding: 0 12%;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  font-size: clamp(7px, 1.05vw, 16px);
  font-weight: 500;
}

.ws-brand-mark {
  width: clamp(15px, 2.1vw, 31px);
  aspect-ratio: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: end;
  gap: 1px;
  padding: 20% 18%;
  background: #303834;
  border-radius: 24%;
}

.ws-brand-mark i {
  display: block;
  height: 44%;
  background: #e2e6e1;
}

.ws-brand-mark i:nth-child(2) {
  height: 67%;
}

.ws-brand-mark i:nth-child(3) {
  height: 88%;
  background: #46a66e;
}

.ws-brand-mark i:nth-child(4) {
  height: 57%;
}

.ws-store,
.ws-user {
  display: flex;
  align-items: center;
  gap: 8%;
  margin: 8% 9%;
  padding: 8%;
  background: #242b27;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
}

.ws-store-dot,
.ws-user > span {
  flex: 0 0 auto;
  width: clamp(19px, 2.8vw, 40px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: #1e7a46;
  border-radius: 50%;
  font-size: clamp(5px, 0.6vw, 9px);
  font-weight: 500;
}

.ws-store div,
.ws-user div {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.ws-store strong,
.ws-user strong {
  overflow: hidden;
  font-size: clamp(6px, 0.75vw, 11px);
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ws-store small,
.ws-user small {
  color: #aeb7b1;
  font-size: clamp(4px, 0.55vw, 8px);
  white-space: nowrap;
}

.ws-sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4% 7%;
}

.ws-sidebar nav span {
  display: flex;
  align-items: center;
  gap: 9%;
  padding: 8% 9%;
  color: #b9c1bc;
  border-radius: 6px;
  font-size: clamp(5px, 0.72vw, 11px);
  white-space: nowrap;
}

.ws-sidebar nav span.active {
  color: #fff;
  background: #1e7a46;
}

.ws-sidebar nav i {
  width: 1.2em;
  color: inherit;
  font-style: normal;
  text-align: center;
}

.ws-user {
  margin-top: auto;
  background: transparent;
  border: 0;
}

.ws-user > span {
  color: #191e1b;
  background: #dbe8df;
}

.ws-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  color: #191e1b;
  background: #f4f5f2;
}

.ws-topbar {
  height: 13%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 3.4%;
  background: #fff;
  border-bottom: 1px solid #d9ddd8;
}

.ws-topbar > div:first-child {
  display: flex;
  flex-direction: column;
}

.ws-topbar small,
.order-rail small,
.customer-card small,
.collection-slot small,
.order-note small {
  color: #66706a;
  font-family: "IBM Plex Mono", monospace;
  font-size: clamp(4px, 0.5vw, 8px);
  letter-spacing: 0.11em;
}

.ws-topbar strong {
  font-size: clamp(9px, 1.35vw, 20px);
  line-height: 1.25;
}

.ws-top-actions {
  display: flex;
  align-items: center;
  gap: clamp(8px, 1.3vw, 22px);
  color: #5c655f;
  font-size: clamp(5px, 0.7vw, 10px);
}

.ws-top-actions button,
.ws-tabs span,
.ws-quantity button {
  color: #3a443f;
  background: #fff;
  border: 1px solid #d9ddd8;
  border-radius: 5px;
}

.ws-top-actions button {
  padding: clamp(3px, 0.5vw, 8px) clamp(5px, 0.8vw, 13px);
  font-size: inherit;
}

.ws-modebar {
  height: 10%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3%;
  padding: 0 3.4%;
  background: #ebede9;
  border-bottom: 1px solid #d9ddd8;
}

.ws-tabs {
  display: flex;
  gap: 4px;
}

.ws-tabs span {
  padding: clamp(3px, 0.48vw, 7px) clamp(5px, 0.78vw, 12px);
  font-size: clamp(4px, 0.62vw, 9px);
}

.ws-tabs span.active {
  color: #fff;
  background: #191e1b;
  border-color: #191e1b;
}

.ws-search {
  width: 31%;
  padding: clamp(3px, 0.55vw, 8px) 2%;
  color: #69716c;
  background: #fff;
  border: 1px solid #d9ddd8;
  border-radius: 5px;
  font-size: clamp(4px, 0.62vw, 9px);
}

.ws-content {
  min-height: 0;
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 36%;
}

.ws-products {
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 3.3%;
}

.ws-section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 2.2%;
}

.ws-section-title strong {
  font-size: clamp(7px, 0.95vw, 14px);
}

.ws-section-title span {
  color: #6d7771;
  font-size: clamp(4px, 0.55vw, 8px);
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.2%;
}

.product {
  position: relative;
  min-width: 0;
  aspect-ratio: 1.18;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 8%;
  color: #27302b;
  background: #fff;
  border: 1px solid #d9ddd8;
  border-radius: clamp(5px, 0.9vw, 12px);
  text-align: left;
  overflow: hidden;
}

.product-art {
  position: absolute;
  top: 10%;
  right: 10%;
  color: #b7c9bd;
  font-family: "Newsreader", serif;
  font-size: clamp(15px, 3.3vw, 50px);
  line-height: 1;
  opacity: 0.72;
}

.product.beef .product-art {
  color: #cba2a2;
}

.product.ham .product-art {
  color: #d9b8ae;
}

.product.veg .product-art {
  color: #88aa8f;
}

.product strong {
  max-width: 80%;
  overflow: hidden;
  font-size: clamp(5px, 0.76vw, 11px);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.product small {
  color: #727a75;
  font-size: clamp(4px, 0.54vw, 8px);
}

.product b {
  position: absolute;
  right: 7%;
  bottom: 10%;
  width: clamp(10px, 1.55vw, 22px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  color: #fff;
  background: #1e7a46;
  border-radius: 50%;
  font-size: clamp(7px, 0.9vw, 13px);
  font-weight: 400;
}

.ws-quantity {
  display: flex;
  align-items: center;
  gap: 1.2%;
  margin-top: auto;
  padding-top: 2.5%;
  border-top: 1px solid #d9ddd8;
}

.ws-quantity span {
  margin-right: auto;
  color: #616b65;
  font-size: clamp(4px, 0.55vw, 8px);
}

.ws-quantity button {
  min-width: clamp(16px, 2.2vw, 32px);
  padding: clamp(2px, 0.4vw, 6px);
  font-size: clamp(4px, 0.58vw, 8px);
}

.order-rail {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 4.5%;
  background: #fff;
  border-left: 1px solid #d9ddd8;
  box-shadow: -5px 0 16px rgba(25, 30, 27, 0.04);
}

.receipt-edge {
  position: absolute;
  left: -5px;
  bottom: 0;
  top: 0;
  width: 6px;
  background: radial-gradient(circle at left, transparent 2px, #fff 2.3px) 0 0 / 6px 10px repeat-y;
}

.order-rail > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 4%;
  border-bottom: 1px solid #d9ddd8;
}

.order-rail > header > div {
  display: flex;
  flex-direction: column;
}

.order-rail > header strong {
  font-family: "IBM Plex Mono", monospace;
  font-size: clamp(7px, 0.9vw, 13px);
}

.order-rail > header button,
.order-lines button {
  color: #636c66;
  background: transparent;
  border: 0;
  font-size: clamp(6px, 0.8vw, 12px);
}

.customer-card {
  display: flex;
  gap: 5%;
  margin: 4% 0;
  padding: 4%;
  background: #e7f0e9;
  border: 1px solid #c7d8cb;
  border-radius: 7px;
}

.customer-card > span {
  flex: 0 0 auto;
  width: clamp(18px, 2.5vw, 37px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  color: #fff;
  background: #1e7a46;
  border-radius: 50%;
  font-size: clamp(5px, 0.56vw, 8px);
}

.customer-card div,
.collection-slot {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.customer-card strong,
.collection-slot strong {
  overflow: hidden;
  font-size: clamp(5px, 0.72vw, 11px);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.customer-card p,
.collection-slot span {
  margin: 0;
  color: #636c66;
  font-size: clamp(4px, 0.53vw, 8px);
}

.collection-slot {
  padding-bottom: 4%;
  border-bottom: 1px solid #d9ddd8;
}

.order-lines {
  display: flex;
  flex-direction: column;
}

.order-lines > div {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 4%;
  padding: 5% 0;
  border-bottom: 1px solid #e5e7e4;
}

.order-lines b {
  width: clamp(14px, 1.9vw, 28px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: #ebede9;
  border-radius: 5px;
  font-family: "IBM Plex Mono", monospace;
  font-size: clamp(5px, 0.65vw, 9px);
  font-weight: 500;
}

.order-lines span {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.order-lines strong {
  overflow: hidden;
  font-size: clamp(5px, 0.68vw, 10px);
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.order-lines small {
  color: #68726c;
  font-size: clamp(3px, 0.48vw, 7px);
}

.order-note {
  margin-top: auto;
  padding: 4%;
  background: #fff9dc;
  border-left: 3px solid #ffd23f;
}

.order-note p {
  margin: 1% 0 0;
  font-size: clamp(4px, 0.55vw, 8px);
}

.confirm-order {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4%;
  margin-top: 4%;
  padding: clamp(5px, 0.85vw, 13px);
  color: #fff;
  background: #1e7a46;
  border: 0;
  border-radius: 6px;
  font-size: clamp(5px, 0.65vw, 10px);
  font-weight: 500;
}

.confirm-order span {
  width: clamp(10px, 1.3vw, 19px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 50%;
}

.hero-object figcaption {
  padding-top: 16px;
  border-top: 1px solid rgba(38, 55, 46, 0.28);
  color: #4c5b53;
  text-transform: none;
  letter-spacing: 0.04em;
}

.case-narrative {
  display: grid;
  grid-template-columns: minmax(300px, 1.1fr) minmax(280px, 0.75fr) minmax(260px, 0.65fr);
  gap: clamp(34px, 6vw, 100px);
  padding: clamp(90px, 12vw, 180px) var(--page-pad);
}

.case-narrative h3,
.system-map h3,
.contribution h3 {
  margin: 0;
  font-family: "Newsreader", serif;
  font-size: clamp(48px, 5.8vw, 88px);
  font-weight: 400;
  letter-spacing: -0.045em;
  line-height: 0.95;
}

.narrative-lead > p:last-child {
  max-width: 610px;
  margin: 40px 0 0;
  color: var(--ink-soft);
  font-size: clamp(18px, 1.5vw, 23px);
  line-height: 1.55;
}

.narrative-column {
  padding-top: 2px;
}

.narrative-column p {
  margin: 0 0 26px;
  color: var(--ink-soft);
}

.pull-quote {
  align-self: end;
  padding: 28px 0 5px;
  border-top: 3px solid var(--pink);
}

.pull-quote p {
  margin: 0;
  font-family: "Newsreader", serif;
  font-size: clamp(25px, 2.4vw, 36px);
  letter-spacing: -0.025em;
  line-height: 1.14;
}

.system-map {
  margin: 0 var(--page-pad);
  padding: clamp(56px, 7vw, 100px) 0;
  border-top: 1px solid var(--line-strong);
  border-bottom: 1px solid var(--line-strong);
}

.system-map > header {
  display: grid;
  grid-template-columns: clamp(130px, 20vw, 320px) 1fr;
}

.system-map h3 {
  max-width: 790px;
}

.system-flow {
  display: grid;
  grid-template-columns: minmax(170px, 0.7fr) minmax(150px, 0.55fr) minmax(0, 2fr);
  align-items: center;
  gap: clamp(24px, 3.5vw, 55px);
  margin-top: clamp(60px, 8vw, 115px);
}

.flow-source,
.flow-outputs div {
  min-height: 136px;
  display: flex;
  flex-direction: column;
  padding: 22px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
}

.flow-source {
  color: var(--surface);
  background: var(--green-dark);
  border-color: var(--green-dark);
}

.flow-source span,
.flow-outputs span {
  margin-bottom: auto;
  color: var(--pink);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
}

.flow-source strong,
.flow-outputs strong {
  font-family: "Newsreader", serif;
  font-size: 25px;
  font-weight: 500;
  line-height: 1.1;
}

.flow-source small,
.flow-outputs small {
  margin-top: 5px;
  color: currentColor;
  font-size: 11px;
  opacity: 0.7;
}

.flow-line {
  display: flex;
  align-items: center;
  color: var(--pink-deep);
  font-family: "IBM Plex Mono", monospace;
  font-size: 8px;
  letter-spacing: 0.13em;
  white-space: nowrap;
}

.flow-line i {
  flex: 1;
  height: 1px;
  background: var(--pink-deep);
}

.flow-line b {
  padding: 0 9px;
  font-weight: 500;
}

.flow-outputs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.flow-outputs div:nth-child(1),
.flow-outputs div:nth-child(4) {
  background: var(--pink-wash);
}


/* Contact: the pitch on the left, the post box on the right. The form is the
   one place on this site a visitor writes rather than reads, so the controls
   are drawn from the same vocabulary as everything else: paper surfaces,
   1px rules, mono labels, pink on focus. */
.contact {
  padding: clamp(90px, 12vw, 180px) var(--page-pad);
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.contact-header {
  display: grid;
  grid-template-columns: clamp(130px, 20vw, 320px) 1fr;
  margin-bottom: clamp(56px, 7vw, 100px);
}

.contact-header .eyebrow { padding-top: 14px; }
.contact-header h2 {
  max-width: 850px;
  font-family: "Newsreader", serif;
  font-size: clamp(58px, 7.5vw, 112px);
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.03em;
  margin: 0 0 22px;
}
.contact-header .case-deck { grid-column: 2; }

.contact-grid {
  display: grid;
  grid-template-columns: minmax(320px, 1.1fr) minmax(300px, 0.9fr);
  gap: clamp(44px, 6vw, 110px);
  align-items: start;
}

.contact-pitch p {
  max-width: 58ch;
  margin: 0 0 22px;
  color: var(--ink-soft);
  line-height: 1.75;
}

.contact-facts {
  margin: 34px 0 38px;
  border-top: 1px solid var(--line-strong);
}

.contact-facts p {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) 1fr;
  gap: 24px;
  max-width: none;
  margin: 0;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}

.contact-facts span {
  color: var(--ink);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.contact-channels {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 34px;
}

.postbox-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: clamp(26px, 3.5vw, 42px);
  border: 1px solid var(--line-strong);
  background: var(--paper);
}

.postbox-form .section-marker { margin: 0 0 4px; }

.postbox-form label {
  display: flex;
  flex-direction: column;
  gap: 9px;
  color: var(--ink);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.postbox-form input,
.postbox-form textarea {
  font: inherit;
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 14px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 12px 13px;
}

.postbox-form textarea { resize: vertical; min-height: 130px; }

.postbox-form input::placeholder,
.postbox-form textarea::placeholder { color: var(--ink-soft); opacity: 0.7; }

.postbox-form input:focus-visible,
.postbox-form textarea:focus-visible {
  outline: 1px solid var(--pink-deep);
  outline-offset: 1px;
  border-color: var(--pink-deep);
}

/* Off screen rather than display:none, so it still looks like a field worth
   filling to the software that fills fields. */
.postbox-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.postbox-submit {
  align-self: flex-start;
  padding: 13px 22px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: border-color 160ms ease, color 160ms ease;
}

.postbox-submit:hover,
.postbox-submit:focus-visible {
  border-color: var(--pink-deep);
  color: var(--pink-deep);
}

.postbox-submit[disabled] { opacity: 0.55; cursor: default; }

.postbox-status {
  min-height: 1.4em;
  margin: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.04em;
}

.postbox-status[data-state="ok"] { color: var(--green-dark); }
.postbox-status[data-state="error"] { color: var(--pink-deep); }

.postbox-noscript { margin: 0; color: var(--ink-soft); font-size: 13px; }

/* Without JavaScript the form cannot deliver, so it steps aside and the
   email address carries the section. */
html:not(.js) .postbox-form { display: none; }

.turnstile-slot:empty { display: none; }

/* PaperWatcher hero: a browser chrome rather than a device bezel, because
   it is a public web service, not a counter tool on a shared iPad. */
.hero-object-screen {
  background:
    radial-gradient(circle at 22% 20%, rgba(198, 163, 65, 0.26), transparent 30%),
    linear-gradient(150deg, #dfe4da 0%, #eee9dc 56%, #d5ddd4 100%);
}

.browser {
  position: relative;
  z-index: 2;
  width: min(1180px, 92%);
  margin: clamp(40px, 5vw, 74px) auto clamp(44px, 5vw, 70px);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 34px 64px var(--shadow), 0 6px 14px var(--shadow);
}

.browser-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  background: color-mix(in srgb, var(--paper-deep) 84%, var(--surface));
  border-bottom: 1px solid var(--line);
}

.browser-bar > span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--line-strong);
  opacity: 0.5;
}

.browser-url {
  flex: 1;
  margin-left: 10px;
  padding: 5px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-align: center;
}

.browser-screen {
  display: block;
  width: 100%;
  height: auto;
  background: #f4f5f2;
}

@media (max-width: 720px) {
  .browser {
    width: calc(100% - (var(--page-pad) * 2));
    border-radius: 9px;
  }

  .browser-bar {
    padding: 8px 10px;
  }

  .browser-url {
    font-size: 8px;
  }
}

/* ==========================================================================
   The WHY studies.

   The catalogue is the frame and the studies bring their own weather. Each
   hero keeps the portfolio's figure label, caption and rhythm, but sits on
   its study's own ground: the Moon's night sky and sodium glow, the rain's
   kiln dust. Their screenshots are plates, a bordered print of the real
   render, with no browser chrome drawn around them: the render is the
   evidence and the frame adds nothing to it.
   ========================================================================== */

/* A question is several words, not one, so it can wrap on purpose. */
.case-title-block h2.case-title-question {
  font-size: clamp(40px, 7vw, 120px);
  font-size: clamp(40px, 12.5cqi, 128px);
  letter-spacing: -0.05em;
  line-height: 0.88;
  text-wrap: balance;
}

.case-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}

.case-links a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--pink-deep);
  text-decoration-color: color-mix(in srgb, var(--pink-deep) 45%, transparent);
  text-underline-offset: 3px;
}

.case-links a:hover,
.case-links a:focus-visible {
  text-decoration-color: currentColor;
}

.plate {
  position: relative;
  z-index: 2;
  width: min(1180px, 92%);
  margin: clamp(40px, 5vw, 74px) auto clamp(44px, 5vw, 70px);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 10px;
  box-shadow: 0 34px 64px rgba(6, 14, 24, 0.34), 0 6px 14px rgba(6, 14, 24, 0.22);
}

/* The aspect ratio is stated as well as implied by width and height, so a
   plate keeps its shape even before its render has been captured. */
.plate-screen {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  background: #0b1f36;
}

/* The Moon's ground: its night sky, with the sodium horizon's glow. */
.hero-object-moon {
  color: #f2deb2;
  background:
    radial-gradient(circle at 78% 16%, rgba(217, 139, 95, 0.3), transparent 34%),
    linear-gradient(172deg, #1d3a5e 0%, #132a47 55%, #0b1f36 100%);
}

.hero-object-moon .object-label span:first-child { color: #eca982; }

.hero-object-moon figcaption {
  color: rgba(242, 222, 178, 0.82);
  border-top-color: rgba(242, 222, 178, 0.28);
}

/* The rain's ground: kiln dust, with the first of the rain on it. */
.hero-object-rain {
  color: #253539;
  background:
    radial-gradient(circle at 18% 20%, rgba(184, 216, 213, 0.6), transparent 34%),
    linear-gradient(160deg, #efe5d2 0%, #e4cfaa 52%, #cdb58f 100%);
}

.hero-object-rain .object-label span:first-child { color: #8e3f26; }
.hero-object-rain figcaption { color: #3d4a4c; border-top-color: rgba(37, 53, 57, 0.3); }
.hero-object-rain .plate { border-color: rgba(37, 53, 57, 0.22); box-shadow: 0 34px 64px rgba(94, 59, 44, 0.24), 0 6px 14px rgba(94, 59, 44, 0.16); }
.hero-object-rain .plate-screen { background: #f2ebdd; }

/* ---------------------------------------------------- StorageInventory

   The one verified screenshot is a portrait desktop window, 864px wide.
   Stretched across the band like the other heroes it would be blown up
   and soft, so it is shown near its natural size, with three notes on
   how to read it beside it. No device or window chrome is drawn: the
   screenshot already is the window's content, and anything more would be
   invented UI. The band keeps the default hero ground, which is fixed
   light in both themes, so the notes use fixed ink like the captions. */

.si-hero {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 540px) minmax(0, 340px);
  justify-content: center;
  align-items: center;
  gap: clamp(32px, 5vw, 84px);
  margin: clamp(40px, 5vw, 74px) auto clamp(44px, 5vw, 70px);
}

.si-window {
  overflow: hidden;
  background: #f9f9f9;
  border: 1px solid rgba(38, 55, 46, 0.24);
  border-radius: 8px;
  box-shadow: 0 34px 64px rgba(23, 38, 30, 0.22), 0 6px 14px rgba(23, 38, 30, 0.14);
}

.si-window img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 864 / 977;
}

.si-notes {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: si-note;
  border-top: 1px solid rgba(38, 55, 46, 0.4);
}

.si-notes li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 4px 12px;
  padding: 18px 0;
  border-bottom: 1px solid rgba(38, 55, 46, 0.2);
  counter-increment: si-note;
}

.si-notes li::before {
  grid-row: 1 / 3;
  content: counter(si-note, decimal-leading-zero);
  color: #8a3e5e;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  line-height: 2.2;
}

.si-notes strong {
  font-family: "Newsreader", serif;
  font-size: 22px;
  font-weight: 500;
  line-height: 1.15;
}

.si-notes span {
  color: #4c5b53;
  font-size: 14px;
  line-height: 1.55;
}

/* The flow is an ordered list, so it is read as five steps in order.
   Each card's rule to the next is drawn across the gap, horizontally in a
   row and vertically once the cards stack. */
.si-flow {
  --si-gap: clamp(14px, 1.8vw, 26px);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--si-gap);
  margin: clamp(60px, 8vw, 115px) 0 0;
  padding: 0;
  list-style: none;
}

.si-flow > li {
  position: relative;
  min-height: 210px;
  display: flex;
  flex-direction: column;
  padding: 22px 20px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
}

.si-flow > li:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 100%;
  width: var(--si-gap);
  height: 1px;
  background: var(--pink-deep);
}

.si-flow > li:first-child {
  color: var(--surface);
  background: var(--green-dark);
  border-color: var(--green-dark);
}

.si-flow > li:last-child {
  background: var(--pink-wash);
}

.si-step {
  margin-bottom: auto;
  padding-bottom: 26px;
  color: var(--pink-deep);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
}

.si-flow > li:first-child .si-step { color: var(--pink); }

/* In the dark theme the first card turns pale, and pink on it is faint. */
:root[data-theme="dark"] .si-flow > li:first-child .si-step {
  color: inherit;
  opacity: 0.72;
}

.si-flow strong {
  font-family: "Newsreader", serif;
  font-size: clamp(21px, 1.7vw, 25px);
  font-weight: 500;
  line-height: 1.1;
}

.si-flow small {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.5;
  opacity: 0.78;
}

.si-tags,
.si-files {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
}

.si-tags li {
  padding: 3px 7px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  text-transform: uppercase;
}

.si-files {
  flex-direction: column;
  gap: 3px;
  overflow-wrap: anywhere;
}

.si-outcomes {
  padding: clamp(80px, 10vw, 150px) var(--page-pad) 0;
}

.si-outcomes > header {
  display: grid;
  grid-template-columns: clamp(130px, 20vw, 320px) 1fr;
}

.si-outcomes h3 {
  max-width: 790px;
  margin: 0;
  font-family: "Newsreader", serif;
  font-size: clamp(40px, 4.6vw, 72px);
  font-weight: 400;
  letter-spacing: -0.04em;
  line-height: 0.96;
}

.si-outcome-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 44px);
  margin: clamp(50px, 6vw, 90px) 0 0;
}

/* The outcome is named in words; the rule colour only repeats it. */
.si-outcome-list div {
  padding-top: 20px;
  border-top: 3px solid var(--line-strong);
}

.si-outcome-list .si-outcome-complete { border-top-color: #3d9664; }
.si-outcome-list .si-outcome-partial { border-top-color: var(--gold); }
.si-outcome-list .si-outcome-failed { border-top-color: var(--pink-deep); }

.si-outcome-list dt {
  font-family: "Newsreader", serif;
  font-size: clamp(24px, 2.1vw, 30px);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.si-outcome-list dd {
  margin: 12px 0 0;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.si-outcome-note {
  max-width: 640px;
  margin: clamp(36px, 4vw, 56px) 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.case-study-si .try-it code {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.88em;
}

.si-get-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 28px;
  margin-top: 18px;
}

.si-get-links .try-it-link {
  margin-top: 0;
}

@media (max-width: 1100px) {
  .si-outcome-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1000px) {
  .si-flow { grid-template-columns: minmax(0, 1fr); }
  .si-flow > li { min-height: 0; }
  .si-step { padding-bottom: 14px; }
  .si-flow > li:not(:last-child)::after {
    top: 100%;
    left: 32px;
    width: 1px;
    height: var(--si-gap);
  }
  .si-outcomes > header { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  .si-hero { grid-template-columns: minmax(0, 540px); }
}

@media (max-width: 720px) {
  .si-hero { padding: 0 var(--page-pad); }
}

@media (max-width: 620px) {
  .si-outcome-list { grid-template-columns: minmax(0, 1fr); }
  .si-get-links { flex-direction: column; align-items: flex-start; }
  .si-get-links .try-it-link { padding: 14px 20px; letter-spacing: 0.05em; }
}

.stamp-text {
  display: inline-block;
  padding: 0 6px;
  border: 1.5px solid currentColor;
  border-radius: 2px;
  color: var(--pink-deep);
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.72em;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transform: rotate(-2deg);
}

/* --------------------------------------------------------- Moon Clicker

   The star of the Moon entry, so it leaves the paper entirely: a full band
   in the game's own night (#071426, its theme colour), the largest type on
   the page after the opening, and the only filled call to action in the
   catalogue. Always dark, in both themes, because that is the game. */

.clicker {
  --night: #071426;
  --chalk: #f2deb2;
  --sodium: #d98b5f;
  --sodium-text: #eca982;
  position: relative;
  padding: clamp(80px, 10vw, 150px) var(--page-pad);
  color: #efe9dc;
  background:
    radial-gradient(circle at 1px 1px, rgba(242, 222, 178, 0.08) 0.8px, transparent 0.9px) 0 0 / 22px 22px,
    radial-gradient(circle at 82% 8%, rgba(217, 139, 95, 0.16), transparent 30%),
    var(--night);
  border-top: 1px solid var(--line);
}

.clicker .section-marker { color: var(--sodium-text); }

.clicker-head {
  display: grid;
  grid-template-columns: clamp(130px, 20vw, 320px) minmax(0, 1fr);
  align-items: end;
  gap: 18px 0;
}

.clicker-head .section-marker { grid-column: 1 / -1; }

.clicker-head h3 {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--chalk);
  font-family: "Newsreader", serif;
  font-size: clamp(64px, 12vw, 190px);
  font-weight: 400;
  letter-spacing: -0.055em;
  line-height: 0.82;
}

.clicker-lede {
  grid-column: 2;
  max-width: 660px;
  margin: 26px 0 0;
  color: rgba(239, 233, 220, 0.86);
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.5;
}

.clicker-lede strong { color: var(--chalk); font-weight: 500; }

.clicker-cta {
  grid-column: 2;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  margin-top: 26px;
  padding: 0 28px;
  border: 1px solid var(--chalk);
  border-radius: 999px;
  background: var(--chalk);
  color: var(--night);
  text-decoration: none;
  font-family: "IBM Plex Mono", monospace;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: background-color 160ms ease, border-color 160ms ease, transform 200ms ease;
}

.clicker-cta:hover,
.clicker-cta:focus-visible {
  background: var(--sodium);
  border-color: var(--sodium);
  transform: translateY(-2px);
}

.clicker-cta:focus-visible,
.clicker a:focus-visible {
  outline: 2px solid var(--chalk);
  outline-offset: 4px;
}

.clicker-plates {
  position: relative;
  margin: clamp(56px, 7vw, 100px) auto 0;
  max-width: 1240px;
}

.clicker-desktop {
  position: relative;
  display: block;
  border-radius: 12px;
  color: inherit;
  text-decoration: none;
  transition: transform 220ms ease;
}

.clicker-desktop:hover,
.clicker-desktop:focus-visible { transform: translateY(-3px); }

.clicker-desktop:hover img,
.clicker-desktop:focus-visible img { border-color: rgba(242, 222, 178, 0.75); }

/* Says where the screenshot goes. Shown on hover and focus, and always on
   a touch screen, where there is no hover to reveal it. */
/* Bottom left, because the phone stands in front of the bottom right and,
   on a narrow screen, the middle. */
.clicker-play {
  position: absolute;
  left: clamp(12px, 2.4vw, 28px);
  bottom: clamp(12px, 2.4vw, 28px);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--chalk);
  color: var(--night);
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 180ms ease, transform 180ms ease;
  pointer-events: none;
}

.clicker-desktop:hover .clicker-play,
.clicker-desktop:focus-visible .clicker-play {
  opacity: 1;
  transform: none;
}

@media (hover: none) {
  .clicker-play { opacity: 1; transform: none; }
}

@media (max-width: 720px) {
  .clicker-play { padding: 7px 12px; font-size: 9.5px; }
}

.clicker-phone { display: block; }

.clicker-desktop img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  /* The game's own night is close to the band's, so the print needs a
     firmer edge than the other plates to stay a print. */
  border: 1px solid rgba(242, 222, 178, 0.4);
  border-radius: 12px;
  background: #0b1f36;
  box-shadow: 0 44px 90px rgba(0, 0, 0, 0.5), 0 8px 20px rgba(0, 0, 0, 0.35);
}

/* The phone stands in front of the desktop, the way the game is actually
   carried: installable, and laid out for one thumb. */
.clicker-phone {
  position: absolute;
  z-index: 2;
  right: -1.5%;
  bottom: -9%;
  width: clamp(130px, 17vw, 250px);
  padding: clamp(5px, 0.6vw, 9px);
  background: linear-gradient(145deg, #39413e, #101714 44%, #27312c 88%);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: clamp(20px, 2.4vw, 34px);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.55), 0 6px 14px rgba(0, 0, 0, 0.4);
  transform: rotate(2deg);
}

.clicker-phone img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 780 / 1688;
  border-radius: clamp(15px, 1.8vw, 26px);
  background: #071426;
}

.clicker-plates figcaption {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  max-width: 76%;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid rgba(242, 222, 178, 0.24);
  color: rgba(242, 222, 178, 0.8);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.clicker-plates figcaption span:first-child { color: var(--sodium-text); }

.clicker-body {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(40px, 6vw, 96px) clamp(40px, 7vw, 120px);
  margin-top: clamp(90px, 11vw, 170px);
}

.clicker-quote {
  margin: 0;
  padding-top: 28px;
  border-top: 3px solid var(--sodium);
}

.clicker-quote p {
  margin: 0;
  color: var(--chalk);
  font-family: "Newsreader", serif;
  font-size: clamp(34px, 4.4vw, 68px);
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.clicker-copy { grid-row: span 2; }

.clicker-copy p {
  margin: 0 0 22px;
  color: rgba(239, 233, 220, 0.8);
  line-height: 1.7;
}

.department-ledger {
  margin: 0;
  border-top: 1px solid rgba(242, 222, 178, 0.3);
}

.department-ledger div {
  display: grid;
  grid-template-columns: minmax(150px, 0.8fr) minmax(0, 1fr);
  gap: 20px;
  padding: 16px 0;
  border-bottom: 1px solid rgba(242, 222, 178, 0.16);
}

.department-ledger dt {
  color: var(--sodium-text);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.7;
  text-transform: uppercase;
}

.department-ledger dd {
  margin: 0;
  color: #efe9dc;
  font-family: "Newsreader", serif;
  font-size: 19px;
  font-style: italic;
  line-height: 1.35;
}

.clicker-facts {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(242, 222, 178, 0.3);
}

.clicker-facts li {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 22px 18px 4px 0;
}

.clicker-facts strong {
  color: var(--chalk);
  font-family: "Newsreader", serif;
  font-size: clamp(34px, 3.4vw, 52px);
  font-weight: 400;
  line-height: 1;
}

.clicker-facts span {
  color: rgba(239, 233, 220, 0.74);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  line-height: 1.6;
  text-transform: uppercase;
}

/* ------------------------------------------ a study feature, and the garden */

.study-feature {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(36px, 6vw, 100px);
  padding: clamp(80px, 10vw, 150px) var(--page-pad);
  border-top: 1px solid var(--line);
}

.study-feature-garden {
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.35fr);
  background: color-mix(in srgb, #b8d8d5 24%, var(--surface));
}

.study-feature-garden .study-feature-figure { order: 2; }

.study-feature-figure { margin: 0; }

.study-feature-figure img,
.why-index-figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #f2ebdd;
  box-shadow: 0 18px 40px var(--shadow);
}

.study-feature-figure figcaption,
.why-index-figure figcaption {
  display: flex;
  gap: 18px;
  margin-top: 14px;
  color: var(--ink-soft);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.study-feature-figure figcaption span:first-child,
.why-index-figure figcaption span:first-child { color: var(--pink-deep); }

.study-feature-copy h3 {
  margin: 0 0 26px;
  font-family: "Newsreader", serif;
  font-size: clamp(40px, 4.6vw, 72px);
  font-weight: 400;
  letter-spacing: -0.04em;
  line-height: 0.96;
}

.study-feature-copy p {
  max-width: 560px;
  margin: 0 0 20px;
  color: var(--ink-soft);
  line-height: 1.7;
}

.study-feature-copy .text-link { margin-top: 10px; }

/* ------------------------------------------------------ The WHY Index

   An interstitial, not a catalogue entry: no number, no facts table. The
   outlined WHY behind it is the publication's name set as a masthead, and
   is decoration only. */

.why-index {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(40px, 6vw, 100px);
  padding: clamp(90px, 12vw, 180px) var(--page-pad);
  background: var(--paper-deep);
  border-top: 1px solid var(--line);
}

.why-index-mark {
  position: absolute;
  right: -2vw;
  bottom: -21vw;
  color: transparent;
  font-family: "Newsreader", serif;
  font-size: 34vw;
  font-style: italic;
  line-height: 1;
  letter-spacing: -0.06em;
  -webkit-text-stroke: 1px var(--line-strong);
  opacity: 0.42;
  pointer-events: none;
  user-select: none;
}

.why-index-copy,
.why-index-figure { position: relative; z-index: 1; }

.why-index h2 {
  max-width: 760px;
  margin: 0 0 30px;
  font-family: "Newsreader", serif;
  font-size: clamp(46px, 5.6vw, 92px);
  font-weight: 400;
  letter-spacing: -0.045em;
  line-height: 0.94;
  text-wrap: balance;
}

.why-index-lede {
  max-width: 600px;
  margin: 0 0 30px;
  color: var(--ink-soft);
  font-size: clamp(17px, 1.4vw, 21px);
  line-height: 1.55;
}

.why-index-status {
  max-width: 600px;
  margin: 0 0 34px;
  border-top: 1px solid var(--line-strong);
}

.why-index-status div {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr);
  gap: 20px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}

.why-index-status dt {
  color: var(--pink-deep);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.8;
  text-transform: uppercase;
}

.why-index-status dd {
  margin: 0;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}

.why-index-figure { margin: 0; }

.work-index li strong a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0 1px;
  transition: background-size 220ms ease;
}

.work-index li strong a:hover,
.work-index li strong a:focus-visible {
  background-size: 100% 1px;
  outline: none;
  color: var(--pink-deep);
}

@media (max-width: 1000px) {
  .clicker-head { grid-template-columns: minmax(0, 1fr); }
  .clicker-lede,
  .clicker-cta { grid-column: 1; }
  .clicker-body { grid-template-columns: minmax(0, 1fr); }
  .clicker-copy { grid-row: auto; }
  .clicker-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .study-feature,
  .study-feature-garden,
  .why-index { grid-template-columns: minmax(0, 1fr); }
  .study-feature-garden .study-feature-figure { order: 0; }
}

@media (max-width: 720px) {
  .plate { width: calc(100% - (var(--page-pad) * 2)); border-radius: 8px; }
  .clicker-phone {
    position: relative;
    right: auto;
    bottom: auto;
    width: min(58%, 230px);
    margin: -18% 4% 0 auto;
  }
  .clicker-plates figcaption { max-width: none; flex-direction: column; gap: 5px; }
  .clicker-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .department-ledger div { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .why-index-status div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .study-feature-figure figcaption,
  .why-index-figure figcaption { flex-direction: column; gap: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .clicker-cta:hover,
  .clicker-cta:focus-visible,
  .clicker-desktop:hover,
  .clicker-desktop:focus-visible { transform: none; }
  .clicker-play { transform: none; }
}

@media (forced-colors: active) {
  .why-index-mark { display: none; }
  .clicker-cta { border: 2px solid ButtonText; }
}

@media (max-width: 860px) {
  .contact-grid { grid-template-columns: 1fr; }
  .contact-header { grid-template-columns: 1fr; }
  .contact-header .case-deck { grid-column: 1; }
}

@media (max-width: 620px) {
  .postbox-form { padding: 20px 16px; }
  .contact-facts p { grid-template-columns: 1fr; gap: 8px; }
  .contact-channels { flex-direction: column; gap: 12px; }
}

.screen-gallery {
  padding: clamp(80px, 10vw, 150px) var(--page-pad);
  border-top: 1px solid var(--line);
}

.screen-gallery header {
  max-width: 660px;
  margin-bottom: clamp(40px, 5vw, 70px);
}

.gallery-grid {
  display: grid;
  /* Two up, not three: these are dense working screens and a third
     column shrinks them past the point of being readable. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(30px, 3.4vw, 54px);
}

.gallery-grid figure:nth-child(odd):last-child {
  grid-column: 1 / -1;
  max-width: calc(50% - clamp(15px, 1.7vw, 27px));
}

@media (max-width: 860px) {
  .gallery-grid {
    grid-template-columns: 1fr;
  }

  .gallery-grid figure:nth-child(odd):last-child {
    grid-column: auto;
    max-width: none;
  }
}

.gallery-grid figure {
  margin: 0;
}

.gallery-grid img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #f4f5f2;
  box-shadow: 0 18px 40px var(--shadow);
}

.gallery-grid figcaption {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.gallery-grid figcaption strong {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pink-deep);
}

.gallery-grid figcaption span {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* Try it: the invitation into the demonstration copy.
   A single centred column rather than the two-column rhythm of the
   sections around it, because it is one instruction rather than a
   comparison, and the change of shape is what stops it reading as
   another block of case-study prose. */
.try-it {
  padding: clamp(80px, 10vw, 150px) var(--page-pad);
  border-top: 1px solid var(--line);
}

.try-it-body {
  max-width: 640px;
}

.try-it h3 {
  margin: 18px 0 24px;
  font-family: "Newsreader", serif;
  font-size: clamp(34px, 4.2vw, 60px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 1.02;
}

.try-it p {
  margin: 0 0 16px;
  max-width: 560px;
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.65;
}

.try-it-note {
  color: var(--ink-soft);
  font-size: clamp(14px, 1.05vw, 16px);
}

.try-it-link {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-top: 18px;
  padding: 14px 26px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}

.try-it-link:hover,
.try-it-link:focus-visible {
  color: var(--surface);
  background: var(--green);
  border-color: var(--green);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  .try-it-link { transition: none; }
}

.contribution {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(420px, 1.2fr);
  gap: clamp(50px, 9vw, 150px);
  padding: clamp(90px, 12vw, 180px) var(--page-pad);
}

.contribution h3 {
  max-width: 660px;
}

.contribution-list {
  border-top: 1px solid var(--line-strong);
}

.contribution-list p {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) 1fr;
  gap: 24px;
  margin: 0;
  padding: 20px 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}

.contribution-list span {
  color: var(--ink);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.work-index {
  padding: clamp(90px, 12vw, 180px) var(--page-pad);
}

.work-index header {
  display: grid;
  grid-template-columns: clamp(130px, 20vw, 320px) 1fr;
  margin-bottom: clamp(60px, 8vw, 110px);
}

.work-index h2 {
  max-width: 850px;
  font-size: clamp(58px, 7.5vw, 112px);
}

.work-index ol {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line-strong);
}

.work-index li {
  display: grid;
  grid-template-columns: 80px 1.1fr 1fr auto;
  align-items: baseline;
  gap: 30px;
  padding: 28px 0;
  border-bottom: 1px solid var(--line);
}

.work-index li > span,
.work-index li > b {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.work-index li strong {
  font-family: "Newsreader", serif;
  font-size: clamp(27px, 3vw, 44px);
  font-weight: 400;
  line-height: 1;
}

.work-index li small {
  color: var(--ink-soft);
  font-size: 14px;
}

.work-index li:not(.current) {
  color: var(--ink-soft);
}

.work-index li.current > span,
.work-index li.current > b {
  color: var(--pink-deep);
}

footer {
  display: grid;
  grid-template-columns: 1.3fr 0.7fr;
  min-height: 430px;
  color: #f5f2ed;
  background: #203c32;
  border-top: 6px solid var(--pink);
}

.footer-lead {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(50px, 7vw, 100px) var(--page-pad);
  border-right: 1px solid rgba(255, 255, 255, 0.18);
}

.sakura-small {
  color: #e5a1b6;
  font-size: 34px;
}

.footer-lead p {
  max-width: 800px;
  margin: 60px 0 0;
  font-family: "Newsreader", serif;
  font-size: clamp(38px, 5vw, 75px);
  letter-spacing: -0.04em;
  line-height: 0.98;
}

.footer-meta {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 12px;
  padding: clamp(50px, 7vw, 100px) var(--page-pad);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.footer-meta a {
  width: fit-content;
  color: #f1b7c9;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 700ms ease, transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* The header drops its section links to a second, scrolling row before the
   rest of the layout reflows. With five entries in the nav the single row
   only fits from about 1280px, so this switches a little above that to
   leave room for font rendering. It used to switch at 1000px, where even
   four entries left no slack. Restoring Workspace's link needs about
   1380px here (see the portfolio README). */
@media (max-width: 1320px) {
  .site-header {
    grid-template-columns: 1fr auto;
    gap: 0 18px;
    padding-top: 12px;
    padding-bottom: 10px;
  }

  .primary-nav {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-content: flex-start;
    gap: 20px;
    margin-top: 2px;
    padding-bottom: 2px;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .primary-nav::-webkit-scrollbar {
    display: none;
  }

  /* A soft right edge is the only hint that the row scrolls; it clears
     once you reach the end so the last item is never dimmed for nothing. */
  .primary-nav.has-more {
    -webkit-mask-image: linear-gradient(90deg, #000 86%, transparent 100%);
    mask-image: linear-gradient(90deg, #000 86%, transparent 100%);
  }

  .primary-nav a {
    padding: 6px 0;
    white-space: nowrap;
  }
}

@media (max-width: 1000px) {
  .opening-title-wrap {
    grid-template-columns: 1fr;
  }

  .margin-note {
    margin: 0 0 50px;
  }

  .opening h1 {
    font-size: clamp(72px, 14vw, 124px);
  }

  .opening-foot {
    grid-template-columns: 1fr auto;
  }

  .opening-foot p {
    grid-column: 1;
  }

  .case-heading {
    grid-template-columns: 110px 1fr;
  }

  .case-facts {
    grid-column: 2;
  }

  .case-narrative {
    grid-template-columns: 1.1fr 0.9fr;
  }

  .pull-quote {
    grid-column: 2;
  }

  .system-map > header,
  .work-index header {
    grid-template-columns: 1fr;
  }

  .system-flow {
    grid-template-columns: 1fr;
  }

  /* Stacked, the line no longer runs left to right between a source and its
     outputs; it runs down between them. A horizontal bar rotated onto its
     side drifts from the cards it is meant to join the moment their heights
     differ, so this is drawn as an actual vertical rule instead: a real
     flex column, sized by its own box rather than by how much horizontal
     room happened to be left over. */
  .flow-line {
    flex-direction: column;
    width: auto;
    height: 108px;
    margin: 4px 0;
  }

  .flow-line i {
    width: 1px;
    height: auto;
  }

  .flow-line b {
    padding: 9px 0;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
  }

  .contribution {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  :root {
    --page-pad: 24px;
  }

  .site-header {
    min-height: 76px;
    padding: 10px var(--page-pad);
  }

  .wordmark {
    gap: 9px;
    font-size: 25px;
  }

  .wordmark small {
    display: none;
  }

  .sakura-mark {
    width: 27px;
    height: 27px;
  }

  .theme-toggle {
    width: 42px;
    height: 42px;
  }

  .opening {
    min-height: calc(100svh - 88px);
    padding-top: 52px;
    padding-bottom: 28px;
  }

  .opening-kicker {
    grid-template-columns: 1fr auto;
  }

  .opening-kicker span:nth-child(2) {
    display: none;
  }

  .margin-note {
    margin-bottom: 38px;
  }

  .opening h1 {
    font-size: clamp(59px, 17.8vw, 86px);
    line-height: 0.87;
  }

  .opening-foot {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .text-link {
    justify-self: start;
  }

  .case-heading {
    grid-template-columns: 1fr;
    gap: 34px;
  }

  .catalogue-number {
    flex-direction: row;
    align-items: baseline;
    gap: 12px;
  }

  .catalogue-number strong {
    font-size: 58px;
  }

  .case-title-block h2 {
    /* Scale with the viewport rather than sitting on a fixed floor: a
       long single word like "PaperWatcher" cannot wrap, so a hard 67px
       minimum pushed it off the side of a phone. */
    font-size: clamp(40px, 12.5vw, 100px);
  }

  .case-deck {
    margin-top: 28px;
  }

  .case-facts {
    grid-column: 1;
  }

  .hero-object {
    padding-left: 0;
    padding-right: 0;
  }

  .object-label,
  .hero-object figcaption {
    margin-left: var(--page-pad);
    margin-right: var(--page-pad);
  }

  .object-label span:last-child {
    max-width: 180px;
    text-align: right;
  }

  .ipad {
    /* The old rule bled the frame to 155vw so the mockup's reflowing CSS
       stayed legible. A real screenshot cannot reflow, so bleeding it just
       crops the screen off both edges: keep the whole device on screen. */
    width: calc(100% - (var(--page-pad) * 2));
    margin-left: auto;
    margin-right: auto;
    border-radius: 22px;
    transform: rotate(-0.6deg);
  }

  .ipad-camera {
    right: 5px;
  }

  .hero-object figcaption {
    flex-direction: column;
    gap: 5px;
  }

  .case-narrative {
    grid-template-columns: 1fr;
  }

  .case-narrative h3,
  .system-map h3,
  .contribution h3 {
    font-size: clamp(48px, 14vw, 68px);
  }

  .narrative-column,
  .pull-quote {
    grid-column: 1;
  }

  .flow-outputs {
    grid-template-columns: 1fr;
  }

  .contribution-list p {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .work-index h2 {
    font-size: clamp(56px, 16vw, 78px);
  }

  .work-index li {
    grid-template-columns: 42px 1fr auto;
    gap: 12px;
  }

  .work-index li small {
    grid-column: 2 / 4;
  }

  .work-index li b {
    text-align: right;
  }

  footer {
    grid-template-columns: 1fr;
  }

  .footer-lead {
    min-height: 380px;
    border-right: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  }

  .footer-meta {
    padding-top: 42px;
    padding-bottom: 42px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .reveal,
  .js .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   The mark turns when you reach for the wordmark.

   The same gesture on all four surfaces, so the identity behaves the same
   wherever you meet it: the gate, the catalogue, and the herbarium's three
   pages. Written against `.wordmark .sakura-mark` rather than any one
   site's own class because the markup differs between them and the
   behaviour should not.

   Suppressed rather than merely un-animated under reduced motion. Both
   sheets already kill transition-duration globally there, which would have
   left a 24 degree snap: instant, but not what someone asking for less
   movement had in mind.
   ========================================================================== */

.wordmark .sakura-mark {
  transition: transform 420ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

.wordmark:hover .sakura-mark,
.wordmark:focus-visible .sakura-mark {
  transform: rotate(24deg);
}

@media (prefers-reduced-motion: reduce) {
  .wordmark .sakura-mark { transition: none; }
  .wordmark:hover .sakura-mark,
  .wordmark:focus-visible .sakura-mark { transform: none; }
}
