/* Both fonts are served from this origin (fonts/), never from a CDN. */
@font-face {
  font-family: 'Bebas Neue';
  src: url('fonts/bebas-neue-latin-400-normal.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bebas Neue';
  src: url('fonts/bebas-neue-latin-ext-400-normal.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  src: url('fonts/bricolage-grotesque-latin-wght-normal.woff2') format('woff2');
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  src: url('fonts/bricolage-grotesque-latin-ext-wght-normal.woff2') format('woff2');
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Dark is the page's own look; a light system, or the switch, gets the paper
   version. The light palette appears twice on purpose: one rule cannot cover
   both a media query and an attribute selector. */
:root {
  --bg: #111111;
  --card: #181818;
  --ink: #f1efe9;
  --text: #aaaaaa;
  --dim: #777777;
  --line: #8a8a8a;
  --hair: #3a3a3a;
  --accent: #ff5a2b;
  --ok: #5fcf8f;
  --warn: #e6b24a;
  --nodata: #5a5a5a;

  --display: 'Bebas Neue', 'Arial Narrow', Impact, sans-serif;
  --sans: 'Bricolage Grotesque', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --pad: clamp(16px, 2.8vw, 40px);
  /* The second column of the header, the project heading and the rows. */
  --col: 38%;
  --big: clamp(54px, 11vw, 160px);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --bg: #eceae5;
    --card: #f6f4ef;
    --ink: #111111;
    --text: #4a4946;
    --dim: #8d8b85;
    --line: #5c5a56;
    --hair: #cfccc4;
    --accent: #d2431b;
    --ok: #2c7a4b;
    --warn: #a96a12;
    --nodata: #aaa8a2;
  }
}
:root[data-theme='light'] {
  --bg: #eceae5;
  --card: #f6f4ef;
  --ink: #111111;
  --text: #4a4946;
  --dim: #8d8b85;
  --line: #5c5a56;
  --hair: #cfccc4;
  --accent: #d2431b;
  --ok: #2c7a4b;
  --warn: #a96a12;
  --nodata: #aaa8a2;
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 450;
  line-height: 1.42;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* One language at a time. Without JavaScript the page stays German. */
html[lang='de'] [lang='en'],
html[lang='en'] [lang='de'] {
  display: none !important;
}

a {
  color: inherit;
  text-decoration: none;
}
a:hover {
  color: var(--ink);
}
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
img {
  max-width: 100%;
  display: block;
}
button {
  font: inherit;
  color: inherit;
}
h1,
h2,
h3,
p {
  margin: 0;
}

/* The small uppercase voice used for every label on the page. */
.label {
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--dim);
}

.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--nodata);
}
.dot.live {
  background: var(--ok);
}
.dot.login {
  background: var(--warn);
}

/* The background net (Vanta, see motion.js): a layer behind the whole page,
   strong behind the headline and faint further down (--net). */
.net {
  position: fixed;
  inset: 0;
  z-index: -1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.7s;
}
.net.on {
  opacity: var(--net, 0.7);
}

/* ── Header ───────────────────────────────────────────────────────────── */

.top {
  position: absolute;
  inset: 0 0 auto;
  z-index: 5;
  display: grid;
  grid-template-columns: var(--col) minmax(0, 1fr) auto;
  align-items: start;
  padding: 22px var(--pad) 0;
}
.who,
.what {
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.25;
  text-transform: uppercase;
}
.who {
  color: var(--text);
}
.what {
  color: var(--dim);
}
.switches {
  display: flex;
  gap: 6px;
}
.switch {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 11px;
  border: 1px solid var(--text);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font-size: 12.5px;
  font-weight: 500;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}
.switch:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}
@media (max-width: 620px) {
  .top {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .what {
    display: none;
  }
}
/* A finger needs more to aim at than a mouse pointer. */
@media (pointer: coarse) {
  .switch {
    height: 34px;
    padding: 0 13px;
  }
}
@media (max-width: 350px) {
  .switch {
    padding: 0 10px;
  }
}

/* ── Hero ─────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  padding: 92px var(--pad) 0;
}
.hero h1 {
  font-family: var(--display);
  font-weight: 400;
  font-size: min(20.6vw, 340px);
  line-height: 0.84;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  color: var(--dim);
}
/* A line is a window (.h-line) and what stands in it (.h-in); the intro lets
   the text rise into the window from below. */
.h-line {
  display: block;
  overflow: hidden;
  /* Bebas sits low in its line box; this evens out the gap between the lines. */
  padding-top: 0.06em;
}
.h-in {
  display: flex;
  align-items: center;
  white-space: nowrap;
}
.hero h1 em {
  font-style: normal;
  color: var(--accent);
}
/* The long dash that stretches so the first line always spans the page. */
.dash {
  flex: 1;
  min-width: 0.5em;
  height: 0.085em;
  margin: 0 0.13em 0.05em;
  background: currentColor;
}
.about {
  position: absolute;
  right: var(--pad);
  bottom: 0.9vw;
  width: min(var(--col), 360px);
  font-size: 14.5px;
}
.about .label {
  margin-right: 8px;
}
.about strong {
  font-weight: 500;
  color: var(--ink);
}
.down {
  display: flex;
  justify-content: space-between;
  margin-top: 22px;
  color: var(--dim);
}
.down i {
  font-style: normal;
}
@media (max-width: 1080px) {
  .about {
    position: static;
    width: auto;
    max-width: 34em;
    margin-top: 28px;
  }
}
/* A phone held upright: the headline becomes a poster of three lines, the
   third as wide as the screen (the word is 2.45em wide), and the first screen
   ends with the text about me. */
@media (max-width: 760px) and (orientation: portrait) {
  .hero {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    padding-bottom: 18px;
  }
  .hero h1 {
    font-size: calc((100vw - 2 * var(--pad)) / 2.47);
  }
  .h-in {
    flex-wrap: wrap;
    row-gap: 0.06em;
  }
  .hero h1 em {
    flex: 0 0 100%;
  }
  .dash {
    margin-right: 0;
  }
  .about {
    margin-top: auto;
    padding-top: 30px;
  }
}

/* ── Projects ─────────────────────────────────────────────────────────── */

.projects {
  margin-top: clamp(44px, 7.5vw, 116px);
}
.stage {
  padding: 0 var(--pad);
}
.heads {
  display: grid;
  grid-template-columns: var(--col) minmax(0, 1fr) auto;
  gap: 10px 0;
  align-items: start;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}
.filter {
  padding: 0;
  border: 0;
  background: none;
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
}
.filter:hover,
.filter[aria-pressed='true'] {
  color: var(--ink);
}
.filter[aria-pressed='true'] {
  text-decoration: underline;
  text-underline-offset: 4px;
}
.legend .dot {
  margin-left: 12px;
}
@media (max-width: 760px) {
  .heads {
    grid-template-columns: minmax(0, 1fr);
  }
  .legend .dot:first-child {
    margin-left: 0;
  }
}

/* A rail of cards. By itself it scrolls sideways (touch, reduced motion, no
   script libraries). Where motion.js sets `pin` on the section, the stage
   sticks to the screen instead and the page's own scroll moves the cards. */
.rail {
  margin: clamp(20px, 2.8vw, 36px) calc(var(--pad) * -1) 0;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--pad);
  scrollbar-width: thin;
  scrollbar-color: var(--hair) transparent;
}
.cards {
  position: relative;
  display: flex;
  gap: clamp(14px, 1.7vw, 24px);
  width: max-content;
  margin: 0;
  padding: 0 var(--pad) 16px;
  list-style: none;
}
.card-item {
  flex: none;
  /* As wide as the screen's height allows a 16:10 picture plus its caption. */
  width: clamp(300px, min(54vw, (100svh - 250px) * 1.6), 960px);
  scroll-snap-align: start;
}
.card {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}
.card-media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--hair);
  border-radius: 6px;
  background: var(--card);
}
/* A card's screens lie on top of each other; app.js moves `on` along. The
   next one comes up from below, the last one leaves upwards. */
.slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(6%);
  /* Out quickly, in a moment later: two screens never show through each other. */
  transition: opacity 0.28s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.slide.on {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s ease 0.2s, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s;
}
.slide.out {
  transform: translateY(-6%);
}
.slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
/* Phone screens stand side by side, large enough to read, and run out over
   the bottom edge. */
.slide.phones {
  --phone: 29%;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 3.5%;
  padding: 4.5% 4% 0;
}
.slide.phones.few {
  --phone: 37%;
}
.slide.phones img {
  flex: none;
  width: var(--phone);
  height: auto;
  border: 1px solid var(--hair);
  border-radius: 9px 9px 0 0;
}
/* A screen recording lies over the pictures and shows once it runs; until
   then, and where it cannot play, the pictures are what there is. */
.card-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  opacity: 0;
  transition: opacity 0.4s;
}
.card-media.live video {
  opacity: 1;
}
.card:has(.live) .ticks {
  visibility: hidden;
}
/* A project without pictures gets its name. */
.slide.plate {
  display: grid;
  place-items: center;
  padding: 8%;
  font-family: var(--display);
  font-size: clamp(38px, 5vw, 76px);
  line-height: 0.9;
  text-align: center;
  text-transform: uppercase;
  color: var(--nodata);
}
.card-go {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: #111111;
  font-size: 17px;
  line-height: 1;
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.18s, transform 0.18s;
}
.card-cap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px 12px;
  padding-top: 12px;
}
.card-name {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(30px, 3.1vw, 46px);
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink);
  transition: color 0.18s;
}
/* One dash per screen; the current one is lit. */
.ticks {
  display: flex;
  gap: 4px;
}
.ticks i {
  width: 13px;
  height: 2px;
  background: var(--hair);
  transition: background 0.3s;
}
.ticks i.on {
  background: var(--ink);
}
.card-line,
.card-meta {
  grid-column: 1 / -1;
}
.card-line {
  color: var(--text);
}
.card-meta {
  margin-top: 5px;
}
.card:focus-visible .card-go {
  opacity: 1;
  transform: none;
}
@media (hover: hover) and (pointer: fine) {
  .card:hover .card-name {
    color: var(--accent);
  }
  .card:hover .card-go {
    opacity: 1;
    transform: none;
  }
}
@media (max-width: 760px) {
  .card-item {
    width: min(88vw, 460px);
  }
}
.progress {
  display: none;
}
/* Nothing appears on hover where there is no hover: the arrow that says a
   card opens is simply there. */
@media not ((hover: hover) and (pointer: fine)) {
  .card-go {
    opacity: 1;
    transform: none;
  }
}
/* A phone held upright: no row to swipe through, where most people would
   see the first card and scroll on. The cards stand below each other at the
   full width, and motion.js brings each one in as it is reached. */
@media (max-width: 760px) and (orientation: portrait) {
  .heads {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 0;
  }
  .legend {
    grid-area: 1 / 2;
  }
  .filters {
    grid-column: 1 / -1;
    flex-wrap: nowrap;
    gap: 0 18px;
    margin: 0 calc(var(--pad) * -1);
    padding: 0 var(--pad);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .filters::-webkit-scrollbar {
    display: none;
  }
  .filter {
    flex: none;
    padding: 14px 0;
  }
  .rail {
    margin: 10px 0 0;
    overflow: visible;
    scroll-snap-type: none;
  }
  .cards {
    flex-direction: column;
    gap: 46px;
    width: auto;
    padding: 0;
  }
  .card-item {
    width: auto;
  }
  .card-name {
    font-size: 38px;
  }
  /* An app made for a phone: its recording has the live screen in the middle
     and a still on either side. A taller window cut from the middle shows
     that screen at twice the size. */
  .tall .card-media {
    aspect-ratio: 3 / 4;
  }
  .tall .slide img,
  .tall .card-media video {
    object-position: center;
  }
  .tall .slide.phones {
    --phone: 46%;
    align-items: center;
    padding: 0 3%;
  }
}

/* Pinned: the section is as tall as the cards are long, the stage stays. */
.projects.pin {
  height: calc(100svh + var(--travel, 0px));
}
.pin .stage {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  height: 100svh;
  padding-top: 22px;
}
.pin .rail {
  flex: 1;
  display: flex;
  align-items: center;
  margin-top: 0;
  overflow: clip;
  scroll-snap-type: none;
}
.pin .cards {
  padding-bottom: 0;
  will-change: transform;
}
.pin .progress {
  display: block;
  height: 1px;
  margin-bottom: 26px;
  background: var(--hair);
}
.progress i {
  display: block;
  height: 1px;
  background: var(--ink);
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
}
@media (prefers-reduced-motion: reduce) {
  .slide {
    transition: none;
  }
  .band .track {
    animation: none !important;
  }
}

/* For screen readers only: the word behind a status dot. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Before the animations start ──────────────────────────────────────── */

/* Only while <html> has the class `anim` (set by prefs.js when motion is
   wanted, removed again if motion.js never runs): the pieces that animate in
   start out hidden, and motion.js shows them. */
.anim .h-in {
  visibility: hidden;
}
.anim .top > *,
.anim .about,
.anim .card-item {
  opacity: 0;
}
/* The band is driven by the scroll there, not by the stylesheet. */
.anim .band .track {
  animation: none;
}
html.lenis.lenis-smooth {
  scroll-behavior: auto;
}

/* ── More screens ─────────────────────────────────────────────────────── */

.peek {
  --h: 320px;
  position: fixed;
  left: var(--x, 16px);
  top: var(--y, 72px);
  z-index: 40;
  width: min(840px, calc(100vw - 32px));
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--card);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7);
  overflow: hidden;
  animation: peek-in 0.14s ease-out;
}
@keyframes peek-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .peek {
    animation: none;
  }
}
.peek[hidden],
.peek-backdrop[hidden] {
  display: none;
}
.peek-backdrop {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: rgba(0, 0, 0, 0.62);
}
.peek-head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 12px 4px 18px;
}
.peek-head strong {
  margin-right: auto;
  font-family: var(--display);
  font-size: 34px;
  font-weight: 400;
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink);
}
.peek-head a {
  font-size: 12.5px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}
.peek-head a:hover {
  color: var(--accent);
}
.peek-close {
  width: 30px;
  height: 30px;
  border: 1px solid var(--text);
  border-radius: 50%;
  background: transparent;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.peek-close:hover {
  background: var(--ink);
  color: var(--bg);
}
.peek-desc {
  max-width: 46em;
  padding: 0 18px;
  color: var(--text);
}
.peek-tags {
  padding: 8px 18px 0;
}
.peek-strip {
  display: flex;
  gap: 12px;
  margin-top: 14px;
  padding: 0 18px 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Without this a snapped figure sits flush against the edge, past the padding. */
  scroll-padding-inline: 18px;
  overscroll-behavior-x: contain;
}
.peek-strip figure {
  flex: none;
  margin: 0;
  scroll-snap-align: start;
}
.peek-strip img {
  display: block;
  height: var(--h);
  width: auto;
  max-width: none;
  border: 1px solid var(--hair);
  border-radius: 4px;
  background: var(--bg);
}
.peek-strip figcaption {
  width: 0;
  min-width: 100%;
  padding: 7px 1px 10px;
  color: var(--dim);
  font-size: 12.5px;
  line-height: 1.3;
}
.peek-note {
  padding: 4px 18px 0;
}
.peek > :last-child {
  padding-bottom: 16px;
}
/* No hover to rely on: a sheet from the bottom edge. */
@media not ((hover: hover) and (pointer: fine) and (min-width: 760px)) {
  .peek {
    --h: min(48vh, 420px);
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: auto;
    max-height: 92vh;
    /* With the browser's bars showing, 92vh is taller than what is visible. */
    max-height: 92svh;
    overflow-y: auto;
    border-width: 1px 0 0;
    border-radius: 10px 10px 0 0;
  }
  /* A landscape screen at full height would be twice as wide as a phone.
     --ratio (width / height) is set per image by app.js. */
  .peek-strip img {
    width: min(86vw, calc(var(--h) * var(--ratio, 1.6)));
    height: auto;
  }
}

/* ── Statement ────────────────────────────────────────────────────────── */

.statement {
  margin-top: clamp(80px, 11vw, 170px);
  padding: 0 var(--pad);
  text-align: center;
}
.big {
  max-width: 23em;
  margin: 12px auto 0;
  font-size: clamp(20px, 2.5vw, 35px);
  font-weight: 450;
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--text);
  text-wrap: balance;
}
.big b {
  font-weight: inherit;
  color: var(--ink);
}
.cols {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 40px 12%;
  margin: clamp(70px, 9vw, 140px) auto 0;
  padding: 0 7%;
  text-align: left;
}
.list {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--hair);
}
.list li {
  padding: 13px 0 15px;
  border-top: 1px solid var(--hair);
}
.list b {
  display: block;
  font-weight: 500;
  color: var(--ink);
}
.list span {
  display: block;
  margin-top: 3px;
  font-size: 14px;
}
.stack {
  margin-top: 12px;
  color: var(--text);
}
.nb {
  white-space: nowrap;
}
.quiet {
  display: inline-block;
  margin-top: 4px;
  font-size: 15px;
  text-transform: uppercase;
  color: var(--dim);
}
@media (max-width: 820px) {
  .cols {
    grid-template-columns: minmax(0, 1fr);
    padding: 0;
  }
}
@media (max-width: 760px) and (orientation: portrait) {
  :root {
    --big: 18vw;
  }
  .big {
    font-size: clamp(20px, 5.7vw, 28px);
  }
}

/* ── Contact ──────────────────────────────────────────────────────────── */

.contact {
  margin-top: clamp(90px, 12vw, 190px);
  text-align: center;
}
.invite {
  max-width: 25em;
  margin: 0 auto;
  padding: 0 var(--pad);
  font-size: 14.5px;
}
.band {
  margin-top: clamp(34px, 5vw, 70px);
  overflow: hidden;
  font-family: var(--display);
  font-size: var(--big);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--dim);
}
.band::before,
.band::after {
  content: '';
  display: block;
  height: 1px;
  background: var(--line);
}
.band::before {
  margin: 0 var(--pad) clamp(18px, 2.6vw, 38px);
}
.band::after {
  margin: clamp(12px, 2vw, 30px) var(--pad) 0;
}
.band .track {
  display: flex;
  width: max-content;
  animation: slide4 34s linear infinite;
}
.band .track span {
  flex: none;
  white-space: pre;
}
@keyframes slide4 {
  to {
    transform: translateX(-25%);
  }
}
.mail {
  display: inline-block;
  margin-top: clamp(28px, 3.6vw, 52px);
  padding: 0 var(--pad);
  font-size: clamp(19px, 2.5vw, 35px);
  letter-spacing: -0.015em;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.mail:hover {
  color: var(--accent);
}
/* The address stays on one line down to the narrowest phones. */
@media (max-width: 420px) {
  .mail {
    font-size: 5vw;
  }
}

.foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 14px 20px;
  align-items: center;
  margin-top: clamp(60px, 8vw, 110px);
  padding: 0 var(--pad) 26px;
}
.foot nav {
  /* The middle, whether or not something stands to its left. */
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}
@media (max-width: 820px) {
  .foot {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
  }
  .foot nav {
    grid-column: auto;
  }
}

/* ── Legal pages ──────────────────────────────────────────────────────── */

.legal {
  max-width: 760px;
  margin: 0 auto;
  padding: 120px var(--pad) 0;
}
.legal h1 {
  margin-bottom: 20px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(60px, 11vw, 130px);
  line-height: 0.9;
  text-transform: uppercase;
  color: var(--dim);
}
.legal h2 {
  margin: 30px 0 6px;
  font-size: 11.5px;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--dim);
}
.legal p,
.legal address {
  margin: 0 0 10px;
  font-style: normal;
  color: var(--text);
}
.legal a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.legal code {
  color: var(--ink);
}
