/* =====================================================================
   HYRMedia: an editorial sheet.
   A Sunday supplement crossed with a draughtsman's drawing: paper, ink,
   a Didone headline, small-caps labels, and figures that stay pinned
   while their text passes.

   Three faces, one job each:
     --display  Bodoni Moda   headlines, numerals set as display
     --body     Georgia       everything read
     --mono     Plex Mono     small-caps labels, measurements
   ===================================================================== */

/* Fonts are served from this site. Latin subset, as Google Fonts cuts it.
   Bodoni Moda and Gelasio are variable in weight.

   Bodoni Moda is pinned to its text cut (optical size 11). The full file
   lets the browser pick optical size 96 for headlines, and at that size the
   hairlines are too thin to read, most of all on a phone. */
@font-face {
  font-family: "Bodoni Moda";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/bodoni-moda-text.woff2") format("woff2");
}
@font-face {
  font-family: "Bodoni Moda";
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/bodoni-moda-text-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Gelasio";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/gelasio.woff2") format("woff2");
}
@font-face {
  font-family: "Gelasio";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/gelasio-italic.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/plex-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/plex-mono-500.woff2") format("woff2");
}

:root {
  --paper: #f5eedf; /* page */
  --paper-grained: #eee7d8; /* --paper as it looks under the grain */
  --card: #fffdf8; /* sheets, plates, raised paper */
  --ink: #221d16; /* type, drawn lines */
  --muted: #6f665a; /* secondary prose */
  --green: #6b7a52; /* the logo's green, fills */
  --olive: #5b6845; /* labels and italic numerals: 5.2:1 on paper */
  --sage: #a9bc84;
  --wash: rgba(169, 188, 132, 0.34); /* hover and row washes */
  --terracotta: #d4572a; /* the cut line, underlines, large marks only */
  --terra-ink: #a8401c; /* terracotta at text sizes: 5.6:1 on paper */
  --rule: rgba(34, 29, 22, 0.3);
  --rule-soft: rgba(34, 29, 22, 0.16);

  --display: "Bodoni Moda", Didot, "Bodoni MT", "Bodoni 72", "Times New Roman", serif;
  --body: Georgia, Gelasio, Palatino, "Palatino Linotype", "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --pad: clamp(20px, 6vw, 104px);
  --gut: clamp(32px, 5vw, 90px);
  --mast-h: 56px;

  --wipe: cubic-bezier(0.77, 0, 0.18, 1);
  --settle: cubic-bezier(0.16, 1, 0.3, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* Rubber-band overscroll reveals this flat colour past the page. */
  background: var(--paper-grained);
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--mast-h) + 8px);
  -webkit-text-size-adjust: 100%;
}

body {
  position: relative; /* containing block for .grain */
  margin: 0;
  /* Paints --paper, but reports --paper-grained as the background colour:
     iOS Safari fills past the page's end with that colour. */
  background: linear-gradient(var(--paper), var(--paper)) var(--paper-grained);
  color: var(--ink);
  font: 400 1.0625rem/1.62 var(--body);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--sage);
  color: var(--ink);
}

a {
  color: inherit;
}
img {
  max-width: 100%;
  display: block;
}
h1,
h2,
h3,
p,
dl,
dd,
ul,
ol,
figure,
blockquote {
  margin: 0;
}
ul,
ol {
  padding: 0;
  list-style: none;
}

:focus-visible {
  outline: 2px solid var(--terra-ink);
  outline-offset: 4px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 18px;
  border-radius: 99px;
  font: 500 0.72rem/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}
.skip-link:focus {
  top: 12px;
}

/* Paper grain: one static turbulence tile, multiplied over everything.
   Absolute over the whole page, not fixed: iOS Safari paints a solid band
   under its status bar and toolbar when a fixed element touches the edge. */
.grain {
  position: absolute;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.34;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' seed='14' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .2 0 0 0 0 .17 0 0 0 0 .12 0 0 0 .62 -.16'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* Small caps: the page's one label voice. */
.sc {
  font: 500 0.6875rem/1.3 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ---------- wipe reveal ---------- */
.wipe {
  display: block;
}
.js .wipe {
  clip-path: inset(-12% 100% -25% -6%);
  transform: translateX(-34px);
  transition:
    clip-path 1.15s var(--wipe),
    transform 1.3s var(--settle);
  transition-delay: var(--d, 0s);
}
.js .in .wipe,
.js .wipe.in {
  clip-path: inset(-12% -6% -25% -6%);
  transform: none;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 0 1.7em;
  border: 1px solid var(--ink);
  border-radius: 99px;
  font: 500 0.72rem/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition:
    background 0.35s var(--settle),
    color 0.35s var(--settle),
    border-color 0.35s,
    transform 0.35s var(--spring);
}
.btn:hover {
  transform: translateY(-1px);
}
.btn-ink {
  background: var(--ink);
  color: var(--paper);
}
.btn-ink:hover {
  background: var(--terra-ink);
  border-color: var(--terra-ink);
}
.btn-line {
  background: transparent;
  color: var(--ink);
}
.btn-line:hover {
  background: var(--wash);
}

/* ---------- masthead ---------- */
/* Above the grain and flat: iOS Safari tints its status bar with this sticky
   bar's background colour, so the two must look the same. */
.mast {
  position: sticky;
  top: 0;
  z-index: 91;
  height: var(--mast-h);
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.4vw, 34px);
  padding: 0 var(--pad);
  background: var(--paper-grained);
}
.mast::before,
.mast::after {
  content: "";
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  border-bottom: 1px solid var(--ink);
}
.mast::before {
  bottom: 4px;
}
.mast::after {
  bottom: 0;
  opacity: 0.35;
}
.mast-logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  margin-right: auto;
}
.mast-logo svg {
  width: 22px;
  height: 24px;
  display: block;
}
.mast-logo b {
  font: italic 400 1.28rem/1 var(--display);
  letter-spacing: 0.005em;
  text-transform: none;
}
.mast-kind {
  color: var(--olive);
  margin-right: auto;
}
.mast-nav {
  display: flex;
  gap: clamp(12px, 1.8vw, 26px);
}
.mast a {
  text-decoration: none;
  white-space: nowrap;
}
.mast-nav a,
.mast-contents {
  display: inline-block;
  padding: 6px 0;
  background: linear-gradient(var(--terracotta), var(--terracotta)) left bottom / 0 2px no-repeat;
  transition:
    background-size 0.5s var(--settle),
    color 0.3s;
}
.mast-nav a:hover,
.mast-nav a:focus-visible,
.mast-nav a[aria-current],
.mast-contents:hover {
  background-size: 100% 2px;
}
.mast-nav a[aria-current] {
  color: var(--terra-ink);
}
.mast-contents {
  display: none;
}
.mast-cta {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 18px;
  border-radius: 99px;
  background: var(--ink);
  color: var(--paper);
  transition: background 0.35s var(--settle);
}
.mast-cta:hover {
  background: var(--terra-ink);
}

/* ---------- title spread ---------- */
.spread {
  position: relative;
  min-height: calc(100vh - var(--mast-h));
  min-height: calc(100svh - var(--mast-h));
  padding: 0 var(--pad) 4vh;
  display: flex;
  flex-direction: column;
  overflow: clip;
}
h1 {
  font: 400 clamp(2.9rem, 9.4vw, 11.4rem)/0.9 var(--display);
  letter-spacing: -0.035em;
  margin: clamp(22px, 5vh, 58px) 0 0;
  position: relative;
  z-index: 2;
}
h1 .l2 {
  padding-left: 0.5em;
  --d: 0.16s;
}
h1 em {
  font-style: italic;
  font-size: 0.62em;
  color: var(--olive);
  letter-spacing: -0.01em;
  margin-right: 0.08em;
  position: relative;
  display: inline-block;
}

.sp-low {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 13fr);
  gap: var(--gut);
  align-items: end;
  position: relative;
}
.sp-text {
  position: relative;
  z-index: 2;
  padding-top: 4vh;
}
.dek {
  font: italic 400 clamp(1.1rem, 1.5vw, 1.45rem)/1.4 var(--body);
  max-width: 22em;
  margin: 0 0 1.3em;
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 1.8em;
}
.toc {
  padding: 12px 0 0;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  max-width: 34em;
}
.toc a {
  text-decoration: none;
  display: inline-block;
  padding: 5px 0;
  background: linear-gradient(var(--terracotta), var(--terracotta)) left bottom / 0 2px no-repeat;
  transition:
    background-size 0.5s var(--settle),
    color 0.3s;
}
.toc a:hover,
.toc a:focus-visible {
  background-size: 100% 2px;
  color: var(--terra-ink);
}
.toc i {
  font: italic 400 1.2em var(--display);
  text-transform: none;
  letter-spacing: 0;
  color: var(--olive);
  margin-right: 0.45em;
}

.specimen {
  position: relative;
  align-self: end;
  margin-top: -6vw;
}
#spec {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
#specSite {
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
#specSite image {
  transition: opacity 0.6s var(--settle);
}
.focusring {
  fill: none;
  stroke: var(--terra-ink);
  stroke-width: 1.5;
  stroke-dasharray: 3 5;
  opacity: 0;
}
#specSite:focus-visible .focusring {
  opacity: 1;
}
.seg {
  transform-box: fill-box;
  transform-origin: 50% 60%;
}
.js .seg {
  animation: rise 1s var(--spring) both;
  animation-delay: calc(0.35s + var(--i) * 0.12s);
}
@keyframes rise {
  from {
    opacity: 0;
    transform: scale(0.72) translateY(26px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.draft {
  fill: none;
  stroke: var(--ink);
  stroke-width: 0.8;
  opacity: 0.55;
}
.js .draw {
  stroke-dasharray: var(--len, 900);
  stroke-dashoffset: var(--len, 900);
  animation: draw 1.8s var(--settle) 1.1s forwards;
}
@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}
.js .hint {
  animation: fadein 0.8s 1.7s both;
}
@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
#specHint circle {
  animation: pulse 2.2s cubic-bezier(0.4, 0, 0.2, 1) 2.6s infinite;
  transform-box: fill-box;
  transform-origin: center;
}
@keyframes pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(2.3);
    opacity: 0.25;
  }
}
.spec-tap {
  display: none;
  justify-content: space-between;
  gap: 12px;
  margin: 10px 0 0;
}
.spec-tap span:last-child {
  color: var(--terra-ink);
}
.specimen.sm .spec-tap {
  display: flex;
}
.specimen figcaption span:last-child,
.phones figcaption span:last-child {
  white-space: nowrap;
  text-align: right;
}
.specimen figcaption,
.phones figcaption {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--olive);
  border-top: 1px solid var(--rule);
  padding-top: 8px;
  margin-top: 6px;
}

/* SVG drawing classes. Labels hold a constant on-screen size: --s is the
   figure's scale, set by script. */
.lb {
  font: 500 calc(11px / var(--s, 1)) var(--mono);
  letter-spacing: 0.1em;
  fill: var(--ink);
}
.lb.c {
  fill: var(--olive);
}
.lb.t {
  fill: var(--terra-ink);
}
.lb.p {
  fill: var(--paper);
}
.ln {
  fill: none;
  stroke: var(--ink);
  stroke-width: 0.9;
}
.ln.f {
  stroke-width: 0.7;
  opacity: 0.6;
}
.dash {
  stroke-dasharray: 4 4;
}
.sheet {
  fill: var(--card);
  stroke: var(--ink);
  stroke-width: 1;
}
.sm .wide {
  display: none;
}

/* ---------- introduction ---------- */
.intro {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: var(--gut);
  padding: 14vh var(--pad) 6vh;
}
.card {
  align-self: start;
  max-width: 25em;
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 14px 0 6px;
}
.card h2 {
  margin: 0 0 10px;
  font: italic 400 1.45rem/1.1 var(--display);
  letter-spacing: 0;
}
.card div {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px dotted rgba(34, 29, 22, 0.4);
}
.card dt {
  flex: 1;
  color: var(--olive);
}
.card dd {
  font: 500 0.86rem/1.3 var(--mono);
  font-variant-numeric: tabular-nums;
  text-transform: none;
  letter-spacing: 0;
  text-align: right;
}

.prose p {
  max-width: 33em;
  margin: 0 0 1.15em;
}
.prose a:not(.btn) {
  text-decoration-color: var(--terracotta);
  text-underline-offset: 3px;
}
.lead p {
  font-size: clamp(1.06rem, 1.3vw, 1.24rem);
}
.lead .name {
  color: var(--terra-ink);
}

/* ---------- chapters: text left, pinned figure right ---------- */
.chap {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: var(--gut);
  padding: 0 var(--pad) 9vh;
  align-items: start;
}
.head {
  grid-column: 1;
  padding-top: 17vh;
  position: relative;
}
.head .sc {
  color: var(--olive);
  display: flex;
  align-items: center;
  gap: 12px;
}
.head .sc::after {
  content: "";
  height: 1px;
  flex: 1;
  background: currentColor;
  opacity: 0.5;
  max-width: 120px;
}
h2 {
  font: 400 clamp(2.6rem, 5.4vw, 5.7rem)/0.96 var(--display);
  letter-spacing: -0.025em;
  margin: 0.16em 0 0.1em;
}
/* .62 of the h2 size, written out so the numeral's size does not depend on
   inheriting an em. */
h2 i {
  font-size: clamp(1.61rem, 3.35vw, 3.53rem);
  color: var(--olive);
  margin-right: 0.08em;
}
.stand {
  font: italic 400 clamp(1.35rem, 2vw, 1.9rem)/1.2 var(--display);
  margin: 0.5em 0 0;
  max-width: 16em;
}
.head-p {
  max-width: 31em;
  margin: 1.1em 0 0;
}

.beats {
  grid-column: 1;
  position: relative;
  z-index: 1;
}
.beat {
  min-height: 68vh;
  padding-top: 5vh;
}
.beat:last-child {
  min-height: 76vh;
}
.beats-short .beat {
  min-height: 50vh;
}
.beats-short .beat:last-child {
  min-height: 54vh;
}
.beat p:not(.note) {
  font-size: clamp(1.06rem, 1.3vw, 1.24rem);
}
.beat h3 {
  margin: 0 0 0.8em;
  color: var(--olive);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  align-items: baseline;
}
.beat h3 b {
  color: var(--ink);
  font-weight: 500;
}

/* Margin notes: a leader line runs out of the text toward the figure. */
.note {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--olive);
  margin: 1.7em 0;
  white-space: nowrap;
}
.note::after {
  content: "";
  flex: 1;
  min-width: 30px;
  height: 7px;
  margin-right: calc(var(--gut) * -1 - 1.5vw);
  background:
    radial-gradient(circle at calc(100% - 3.5px) 50%, currentColor 2.6px, transparent 3.2px),
    linear-gradient(currentColor, currentColor) 0 50% / calc(100% - 3px) 1px no-repeat;
  opacity: 0.75;
}
.note a {
  color: var(--terra-ink);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}
.note a:hover {
  color: var(--ink);
}

.fig {
  grid-column: 2;
  grid-row: 1 / span 2;
  position: sticky;
  top: calc(var(--mast-h) + 2vh);
  height: calc(100vh - var(--mast-h) - 5vh);
  margin: 0;
  display: flex;
  flex-direction: column;
  z-index: 2;
}
.fig-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--olive);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 7px;
}
.stage {
  flex: 1;
  min-height: 0;
  position: relative;
}
.stage::before,
.stage::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border: 1px solid var(--ink);
  opacity: 0.45;
}
.stage::before {
  left: 0;
  top: 8px;
  border-right: 0;
  border-bottom: 0;
}
.stage::after {
  right: 0;
  bottom: 8px;
  border-left: 0;
  border-top: 0;
}
.stage > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: pan-y;
  overflow: visible;
}
.fig-foot {
  border-top: 1px solid var(--rule);
  padding-top: 8px;
  color: var(--olive);
}
.fig-foot .cap {
  font: italic 400 0.92rem/1.4 var(--body);
  color: var(--ink);
}
.read {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin-bottom: 8px;
}
.read b {
  color: var(--ink);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 8px;
}
.chip {
  appearance: none;
  border: 1px solid rgba(34, 29, 22, 0.45);
  background: transparent;
  color: var(--ink);
  min-height: 32px;
  padding: 6px 12px 6px 8px;
  border-radius: 99px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition:
    background 0.35s var(--settle),
    border-color 0.35s,
    color 0.35s,
    transform 0.35s var(--spring);
}
.chip i {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--ink);
  display: block;
}
.chip i:not(:empty) {
  width: auto;
  height: auto;
  border: 0;
  border-radius: 0;
  font: italic 400 1.5em/1 var(--display);
  text-transform: none;
  letter-spacing: 0;
  color: var(--olive);
}
.chip:hover {
  background: var(--wash);
  transform: translateY(-1px);
}
.chip[aria-pressed="true"],
.chip[aria-current="true"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.chip[aria-pressed="true"] i,
.chip[aria-current="true"] i {
  border-color: var(--paper);
  color: var(--sage);
}

.stepper {
  display: none;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
  color: var(--ink);
}
.rm .stepper {
  display: flex;
}
.stepper button {
  appearance: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--ink);
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: var(--ink);
  transition: background 0.2s;
}
.stepper button:hover {
  background: var(--wash);
}
.stepper button:disabled {
  opacity: 0.3;
  cursor: default;
  background: transparent;
}
.stepper svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
}

/* A plate: a site in a drawn browser frame. */
.fig-plate .stage {
  container-type: size;
  display: grid;
  place-items: center;
  padding: 22px 0;
}
.plate {
  width: min(100%, calc((100cqh - 78px) * 1.6));
  border: 1px solid var(--ink);
  border-radius: 8px;
  background: var(--card);
  overflow: hidden;
  box-shadow: 0 22px 34px -26px rgba(34, 29, 22, 0.55);
}
.plate-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--ink);
  position: relative;
}
.plate-bar i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--ink);
}
.plate-url {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
}
.plate-view {
  position: relative;
  aspect-ratio: 1440 / 900;
  overflow: hidden;
  background: var(--card);
}
.plate-view img,
.plate-view .mock {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

/* Fig. 2: one frame, two sites, and a cut line between them. */
.tpl-real {
  clip-path: inset(0 calc(100% - var(--w, 6%)) 0 0);
}
.tpl-cut {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--w, 6%);
  width: 2px;
  margin-left: -1px;
  background: var(--terracotta);
}
.tpl-cut b {
  position: absolute;
  top: 12px;
  white-space: nowrap;
  padding: 5px 9px;
  border-radius: 99px;
  background: var(--ink);
  color: var(--paper);
  transition: opacity 0.3s;
}
.tpl-cut b:first-child {
  right: 10px;
  opacity: var(--ours, 0);
}
.tpl-cut b:last-child {
  left: 10px;
  opacity: var(--theirs, 1);
}

/* Fig. 4: six plates in one frame. */
#wkView img {
  opacity: 0;
  transition: opacity 0.55s var(--settle);
}
#wkView img.on {
  opacity: 1;
}

/* Fig. 3 drawing */
.count {
  font: 400 132px/1 var(--display);
  fill: var(--ink);
  letter-spacing: -0.04em;
  transition: opacity 0.5s var(--settle);
}
.fx {
  font: 400 24px var(--mono);
  fill: var(--ink);
  opacity: 0.16;
  transition: opacity 0.5s var(--settle);
}
.fx.lit {
  opacity: 1;
}
.aa {
  font: 400 34px var(--display);
  fill: var(--ink);
}
#hwLive .pulse {
  animation: blink 2.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

/* ---------- services, under the work ---------- */
.chap-tight {
  padding-bottom: 0;
}
.services {
  margin: 4vh var(--pad) 2vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 var(--gut);
  align-items: start;
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 20px 0 22px;
}
.services dl {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 var(--gut);
}
.services dt {
  font: italic 400 1.5rem/1.15 var(--display);
  margin-bottom: 0.35em;
}
.services dd {
  font-size: 0.98rem;
  line-height: 1.5;
  max-width: 24em;
}
.services-cta {
  align-self: center;
}

/* ---------- two-column sections: prose left, a table or a form right ---------- */
.split {
  position: relative;
  padding: 6vh var(--pad) 10vh;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 6vh var(--gut);
  align-items: start;
}
.split .head {
  padding-top: 10vh;
}
.split .prose {
  margin-top: 1.6em;
}
.split-b {
  padding-top: 10vh;
  position: relative;
  z-index: 1;
}
.split-h {
  font: italic 400 clamp(1.7rem, 2.6vw, 2.5rem)/1.1 var(--display);
  letter-spacing: 0;
  margin: 0 0 0.2em;
}
.split-sub {
  margin: 0 0 1.2em;
  color: var(--olive);
}
.split-p {
  max-width: 26em;
}

.tbl {
  width: 100%;
  border-collapse: collapse;
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--ink);
}
.tbl thead th {
  text-align: left;
  padding: 10px 14px 8px 0;
  color: var(--olive);
  font-weight: 500;
}
.tbl thead th:first-child {
  padding-left: 8px;
}
.tbl thead th:last-child {
  text-align: right;
  padding-right: 8px;
}
.tbl tbody th,
.tbl td {
  padding: 16px 14px 16px 0;
  border-top: 1px solid var(--rule);
  vertical-align: top;
  text-align: left;
  font-weight: 400;
  transition: background 0.4s var(--settle);
}
.tbl tbody th {
  font: italic 400 1.5rem/1.15 var(--display);
  padding-left: 8px;
  width: 30%;
}
.tbl td {
  font-size: 0.95rem;
  line-height: 1.45;
}
.tbl td.price {
  font: 400 2.1rem/1 var(--display);
  letter-spacing: -0.02em;
  white-space: nowrap;
  text-align: right;
  padding-right: 8px;
}
.tbl td.price small {
  font: 500 0.6875rem/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--olive);
  margin-right: 0.3em;
}
.tbl tbody tr:hover > * {
  background: var(--wash);
}
.tbl .pop > * {
  background: rgba(169, 188, 132, 0.2);
}
.flag {
  display: inline-block;
  vertical-align: middle;
  margin-top: 8px;
  padding: 4px 8px;
  border-radius: 99px;
  font-style: normal;
  background: var(--ink);
  color: var(--paper);
}
.terms {
  margin: 0 0 1.8em;
}
.terms li {
  padding: 10px 8px;
  border-bottom: 1px dotted rgba(34, 29, 22, 0.4);
  font-size: 0.95rem;
}

/* Notes: a term, then what it is. */
.notes {
  margin: 1.4em 0 1.6em;
  max-width: 33em;
}
.notes div {
  display: grid;
  grid-template-columns: 7.5em 1fr;
  gap: 14px;
  padding: 11px 0;
  border-top: 1px solid var(--rule);
}
.notes dt {
  color: var(--olive);
  padding-top: 0.35em;
}
.notes dd.num {
  font-size: 0.82rem;
  line-height: 1.6;
  padding-top: 0.2em;
}

/* ---------- the apps ---------- */
.apps {
  position: relative;
  padding: 0 var(--pad) 8vh;
}
.apps > .head {
  max-width: 46%;
}
.app {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--gut);
  align-items: center;
  padding: 8vh 0 4vh;
}
.app + .app {
  border-top: 1px solid var(--rule);
}
.app h3 {
  font: 400 clamp(2rem, 3.6vw, 3.6rem)/1 var(--display);
  letter-spacing: -0.02em;
  margin: 0 0 0.35em;
}
.status {
  margin: 0 0 1.4em;
}
.tag {
  display: inline-block;
  padding: 6px 11px;
  border-radius: 99px;
  background: var(--ink);
  color: var(--paper);
}
.tag-wip {
  background: transparent;
  color: var(--terra-ink);
  border: 1px dashed var(--terra-ink);
}
.phones {
  margin: 0;
}
.phones-row {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: clamp(16px, 3vw, 44px);
  padding: 0 0 22px;
}
/* iPhone frame. Radii and padding are percentages, so the frame keeps its
   proportions at every width. */
.phone {
  position: relative;
  width: min(42%, 250px);
}
.phone:nth-child(2) {
  margin-top: 8%;
}
.phone .btn-vol,
.phone .btn-pow {
  position: absolute;
  width: 3px;
  background: #3a3a3d;
}
.phone .btn-vol {
  left: -3px;
  border-radius: 2px 0 0 2px;
}
.phone .btn-pow {
  right: -3px;
  border-radius: 0 2px 2px 0;
}
.phone .btn-v1 {
  top: 17%;
  height: 5%;
}
.phone .btn-v2 {
  top: 25%;
  height: 8%;
}
.phone .btn-p1 {
  top: 29%;
  height: 11%;
}
.phone-body {
  background: linear-gradient(145deg, #54545a, #1c1c1f);
  padding: 2.8%;
  border-radius: 16% / 7.4%;
  box-shadow:
    0 26px 34px -22px rgba(34, 29, 22, 0.6),
    inset 0 0 0 1.2px rgba(255, 255, 255, 0.12);
}
.phone-screen {
  overflow: hidden;
  background: #000;
  line-height: 0;
  border-radius: 14% / 6.45%;
}
/* height:auto is not optional: the markup carries width and height so the
   frame reserves the right box before the capture lands. */
.phone-screen img {
  width: 100%;
  height: auto;
  display: block;
}
.ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 40px;
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 20px 0 22px;
  margin-top: 4vh;
}
.ask p {
  font: italic 400 clamp(1.2rem, 1.8vw, 1.6rem)/1.3 var(--display);
  max-width: 30em;
}

/* ---------- the shop: a contact sheet ---------- */
.shop {
  position: relative;
  padding: 0 var(--pad) 8vh;
}
.shop-head {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--gut);
  align-items: end;
}
.shop-head .prose {
  padding-bottom: 0.4em;
}
.sheet-grid {
  margin-top: 6vh;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--ink);
  border-left: 1px solid var(--rule);
}
.sheet-grid li {
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.sheet-grid a {
  display: block;
  padding: 12px 12px 14px;
  text-decoration: none;
  transition: background 0.4s var(--settle);
}
.sheet-grid a:hover {
  background: var(--wash);
}
.sheet-grid img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  mix-blend-mode: multiply;
}
.sheet-grid span {
  display: block;
  margin-top: 10px;
  color: var(--olive);
}
.sheet-ask {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 18px;
  padding: 22px;
}
.sheet-ask p {
  font: italic 400 clamp(1.3rem, 2vw, 1.9rem)/1.2 var(--display);
}

/* ---------- studio, contact ---------- */
.split-studio {
  padding-top: 2vh;
  padding-bottom: 0;
  align-items: start;
}
.split-studio .notes {
  margin-top: 0;
}

.form {
  display: grid;
  gap: 22px;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.field {
  display: grid;
  gap: 6px;
}
.field label {
  color: var(--olive);
}
.field .opt {
  text-transform: none;
  letter-spacing: 0.04em;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  appearance: none;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: 400 1.0625rem/1.4 var(--body);
  padding: 8px 2px 10px;
  transition:
    background 0.3s,
    border-color 0.3s;
}
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23221d16' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 12px 8px;
  padding-right: 26px;
}
.field textarea {
  resize: vertical;
  min-height: 7em;
}
.field input::placeholder,
.field textarea::placeholder {
  color: var(--muted);
  font-style: italic;
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: none;
  border-bottom: 2px solid var(--terra-ink);
  padding-bottom: 9px;
  background-color: rgba(255, 253, 248, 0.7);
}
.btn-submit {
  justify-self: start;
  min-width: 12em;
}
.btn-submit:disabled {
  opacity: 0.55;
  cursor: progress;
}
.form-note {
  font-size: 0.92rem;
  color: var(--muted);
}
.form-note a {
  color: var(--ink);
  text-decoration-color: var(--terracotta);
  text-underline-offset: 3px;
}
.form-success,
.form-error,
.form-fallback {
  display: none;
  border-top: 3px double var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 18px 8px;
  font: italic 400 1.35rem/1.3 var(--display);
}
.form-fallback {
  display: block;
}
.form-error {
  color: var(--terra-ink);
  margin-top: 18px;
  font-size: 1.1rem;
}

/* ---------- end ---------- */
.end {
  margin: 4vh var(--pad) 0;
  padding: 18px 0 34px;
  border-top: 1px solid var(--ink);
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 20px 28px;
}
.end-logo svg {
  width: 54px;
  height: auto;
  display: block;
}
.end-line {
  font: italic 400 clamp(1.3rem, 2.2vw, 2rem)/1.2 var(--display);
  margin-right: auto;
}
.end-meta {
  color: var(--olive);
  text-align: right;
  display: grid;
  gap: 8px;
}
.end-meta nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px 18px;
}
.end-meta a {
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding: 3px 0;
}
.end-meta a:hover {
  color: var(--ink);
  border-bottom-color: currentColor;
}

/* ---------- wide screens: keep the sheet a sheet ---------- */
@media (min-width: 1800px) {
  :root {
    --pad: calc((100vw - 1592px) / 2);
  }
}

/* ---------- narrow masthead ---------- */
@media (max-width: 1100px) {
  .mast-kind {
    display: none;
  }
}

/* ---------- phone ---------- */
@media (max-width: 860px) {
  body {
    font-size: 1rem;
  }
  .mast-nav {
    display: none;
  }
  .mast-contents {
    display: inline-block;
  }
  h1 {
    font-size: 11.6vw;
    margin-top: 30px;
  }
  h1 .l2 {
    padding-left: 0.2em;
  }
  .sp-low {
    display: flex;
    flex-direction: column-reverse;
    gap: 22px;
    align-items: stretch;
    justify-content: flex-end;
  }
  .sp-text {
    padding-top: 0;
  }
  .specimen {
    margin-top: 26px;
    align-self: stretch;
  }
  .intro {
    display: flex;
    flex-direction: column-reverse;
    gap: 5vh;
    padding-top: 9vh;
  }
  .card {
    max-width: none;
  }

  .chap {
    display: block;
    padding: 0 0 4vh;
  }
  .head {
    padding: 11vh var(--pad) 3vh;
  }
  .fig-top span:last-child {
    display: none;
  }
  .fig {
    position: sticky;
    top: var(--mast-h);
    height: 56vh;
    height: 56svh;
    background: var(--paper);
    padding: 8px var(--pad);
    border-bottom: 1px solid var(--rule);
    box-shadow: 0 14px 18px -14px rgba(34, 29, 22, 0.25);
  }
  /* iOS Safari paints a solid band under its toolbar while a sticky element
     touches the bottom edge. So a figure scrolls in as plain content and pins
     only when it reaches its line under the masthead (site.js sets .pinned). */
  .js .fig:not(.pinned) {
    position: relative;
    top: auto;
  }
  .fig.fig-plate {
    height: auto;
  }
  .fig-plate .stage {
    container-type: normal;
    flex: none;
    padding: 12px 0;
  }
  .fig-plate .stage::before,
  .fig-plate .stage::after {
    display: none;
  }
  .plate {
    width: 100%;
  }
  .fig-foot .cap {
    font-size: 0.84rem;
    line-height: 1.3;
  }
  .read {
    gap: 2px 14px;
    margin-bottom: 6px;
  }
  .legend {
    gap: 6px;
    margin-bottom: 6px;
  }
  .chip {
    padding: 5px 10px 5px 7px;
  }
  #figWork .legend {
    flex-wrap: nowrap;
    overflow-x: auto;
    margin-right: calc(var(--pad) * -1);
    padding-right: var(--pad);
    scrollbar-width: none;
  }
  #figWork .chip {
    flex: none;
  }
  .beats {
    padding: 0 var(--pad);
  }
  /* The figure is pinned across the top here, so a beat needs no extra
     height to keep it in view: only enough travel for its drawing to play. */
  .beat {
    min-height: 34vh;
    padding-top: 5vh;
  }
  .beat:last-child {
    min-height: 0;
    padding-bottom: 4vh;
  }
  .beats-short .beat,
  .beats-short .beat:last-child {
    min-height: 0;
    padding: 4vh 0 1vh;
  }
  .note {
    white-space: normal;
  }
  .note::after {
    margin-right: 0;
    min-width: 40px;
  }
  .services,
  .services dl {
    display: block;
  }
  .services {
    margin: 2vh var(--pad) 6vh;
  }
  .services dl div {
    padding: 10px 0;
  }
  .services dl div + div {
    border-top: 1px dotted rgba(34, 29, 22, 0.4);
  }
  .services-cta {
    padding-top: 14px;
    border-top: 1px dotted rgba(34, 29, 22, 0.4);
  }

  .split {
    display: block;
    padding: 2vh var(--pad) 8vh;
  }
  .split-b {
    padding-top: 6vh;
  }
  .split-studio {
    padding-top: 6vh;
  }
  .split-studio .notes {
    margin-top: 1.4em;
  }

  .tbl,
  .tbl tbody,
  .tbl tr,
  .tbl tbody th,
  .tbl td {
    display: block;
  }
  .tbl thead {
    display: none;
  }
  .tbl tr {
    border-top: 1px solid var(--rule);
    padding: 14px 8px;
  }
  .tbl tbody th,
  .tbl td,
  .tbl td.price {
    border: 0;
    padding: 2px 0;
    width: auto;
    text-align: left;
  }
  .tbl td.price {
    padding-top: 10px;
  }
  .tbl .pop {
    background: rgba(169, 188, 132, 0.2);
  }
  .tbl .pop > *,
  .tbl tbody tr:hover > * {
    background: none;
  }

  .apps > .head {
    max-width: none;
  }
  .apps {
    padding: 0 0 6vh;
  }
  .apps .head {
    padding-bottom: 0;
  }
  .app {
    display: block;
    padding: 7vh var(--pad) 3vh;
  }
  .app + .app {
    border-top: 0;
  }
  .phones {
    margin-top: 5vh;
  }
  .ask {
    margin: 4vh var(--pad) 0;
  }

  .shop {
    padding: 0 0 6vh;
  }
  .shop-head {
    display: block;
  }
  .shop-head .prose {
    padding: 0 var(--pad);
  }
  .sheet-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin: 5vh var(--pad) 0;
  }

  .actions .btn {
    flex: 1 1 auto;
  }
  .sheet-ask {
    grid-column: 1 / -1;
  }
  .btn-submit {
    width: 100%;
  }
  .form-row {
    grid-template-columns: 1fr;
  }
  .end {
    align-items: flex-start;
    flex-direction: column;
  }
  .end-meta {
    text-align: left;
  }
  .end-meta nav {
    justify-content: flex-start;
  }
}
@media (max-width: 860px) and (max-height: 620px) {
  .fig {
    height: 64vh;
  }
}
@media (max-width: 480px) {
  /* Two things in the bar on a phone: the name and the one action. The
     contents list is in the hero and the footer. */
  .mast-contents {
    display: none;
  }
  .notes div {
    grid-template-columns: 6.2em 1fr;
  }
}

/* ---------- reduced motion: figures show their finished states ---------- */
.rm .beat,
.rm .beat:last-child {
  min-height: 0;
  padding-bottom: 5vh;
}
.rm .chap {
  padding-bottom: 8vh;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .js .wipe {
    clip-path: none;
    transform: none;
    transition: none;
  }
  .js .seg,
  .js .draw,
  .js .hint,
  #specHint circle,
  #hwLive .pulse {
    animation: none;
  }
  .js .draw {
    stroke-dashoffset: 0;
  }
  .chip,
  .btn,
  .toc a,
  .mast a,
  .tbl tbody th,
  .tbl td,
  #wkView img,
  #specSite image,
  .count,
  .fx {
    transition: none;
  }
}
