/* Reset */

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

html {
  background: var(--color-backdrop);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  position: relative; /* x-ray overlay spans the whole document */
  min-height: 100svh;
  margin: 0;
  overflow-x: clip;   /* full-bleed blocks can overhang by half a scrollbar */
  background: var(--color-backdrop);
  color: var(--color-text);
  font-family: var(--font-styrene);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
p,
figure {
  margin: 0;
}

img {
  display: block;
  max-width: 100%;
}

/* Read out, not shown */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Page grid: fixed-width columns, as many as fit (up to --grid-cols), centered. */

.grid {
  --cols-cap: var(--grid-cols);
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--grid-col));
  justify-content: center;
  column-gap: var(--grid-gutter);
  max-width: calc(
    var(--cols-cap) * var(--grid-col) + (var(--cols-cap) - 1) * var(--grid-gutter) + 2 * var(--grid-margin)
  );
  margin-inline: auto;
  padding-inline: var(--grid-margin);
}

/* Phones: always --grid-cols columns; --grid-col stretches them to fill (tokens.css) */

@media (width < 656px) {
  .grid {
    grid-template-columns: repeat(var(--grid-cols), var(--grid-col));
  }
}

/* Type styles.
   Each style maps its tokens onto --fs / --lh / --m. The shared block works out where the
   baseline falls in a line box (--bl), rounds it to the nearest grid line (--bl-snap) and
   nudges the text by the difference, so every line sits on the baseline grid as long as the
   element starts on a grid line. --below is baseline → bottom of the line box, for aligning
   a last baseline to an edge. */

.t-client,
.t-title,
.t-display,
.t-heading,
.t-body,
.t-caption {
  --bl: calc(var(--lh) / 2 + var(--m) * var(--fs));
  --bl-snap: round(nearest, var(--bl), var(--baseline));
  --below: calc(var(--lh) - var(--bl-snap));

  position: relative;
  top: calc(var(--bl-snap) - var(--bl));
  font-size: var(--fs);
  line-height: var(--lh);
}

.t-client {
  --fs: var(--client-size);
  --lh: calc(var(--client-leading-bl) * var(--baseline));
  --m: var(--client-m);
  color: var(--client-color);
  font-family: var(--client-font);
  font-style: var(--client-style);
  font-weight: var(--client-weight);
  letter-spacing: var(--client-tracking);
}

.t-title {
  --fs: var(--title-size);
  --lh: calc(var(--title-leading-bl) * var(--baseline));
  --m: var(--title-m);
  color: var(--title-color);
  font-family: var(--title-font);
  font-style: var(--title-style);
  font-weight: var(--title-weight);
  letter-spacing: var(--title-tracking);
}

.t-display {
  --fs: var(--display-size);
  --lh: calc(var(--display-leading-bl) * var(--baseline));
  --m: var(--display-m);
  color: var(--display-color);
  font-family: var(--display-font);
  font-style: var(--display-style);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
}

.t-heading {
  --fs: var(--heading-size);
  --lh: calc(var(--heading-leading-bl) * var(--baseline));
  --m: var(--heading-m);
  color: var(--heading-color);
  font-family: var(--heading-font);
  font-style: var(--heading-style);
  font-weight: var(--heading-weight);
  letter-spacing: var(--heading-tracking);
}

.t-body {
  --fs: var(--body-size);
  --lh: calc(var(--body-leading-bl) * var(--baseline));
  --m: var(--body-m);
  color: var(--body-color);
  font-family: var(--body-font);
  font-style: var(--body-style);
  font-weight: var(--body-weight);
  letter-spacing: var(--body-tracking);
}

.t-body p + p {
  margin-top: calc(var(--body-para-bl) * var(--baseline));
}

/* The project's role line: darker than the body, then a closer gap to the text below */
.project__role {
  color: var(--color-ink);
}

.t-body .project__role + p {
  margin-top: calc(var(--body-role-gap-bl) * var(--baseline));
}

/* Links in the body and in captions: underlined, ink in the body, the caption's own grey in a caption */
:is(.t-body, .t-caption) a {
  position: relative;
  color: var(--color-ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

/* Links that leave the site show an arrow past their end on hover, sitting on the baseline.
   It takes no room, so the text never shifts. css/motion.css slides it in. */
.t-caption a {
  color: inherit;
}

:is(.t-body, .t-caption) a[href^="http"]::after {
  content: "";
  position: absolute;
  bottom: 0.236em; /* the inline box ends this far below the baseline (the font's descent, fonts.css) */
  left: 100%;
  width: 0.55em;
  height: 0.55em;
  margin-left: 0.3em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke='black' stroke-width='1.4'%3E%3Cpath d='M1.5 8.5l7-7M2.5 1.5h6v6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke='black' stroke-width='1.4'%3E%3Cpath d='M1.5 8.5l7-7M2.5 1.5h6v6'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0;
}

:is(.t-body, .t-caption) a[href^="http"]:is(:hover, :focus-visible)::after {
  opacity: 1;
}

/* An external link inside a sentence: just the underline, no hover arrow (there's no room
   for it before the comma) */
:is(.t-body, .t-caption) a.link--inline::after {
  content: none;
}

/* Links with an icon after the text (a camera for a video, a globe for a website), always
   there; the arrow stays for the other external links. The icon lives in padding at the
   link's end, so it takes room in a sentence, and the underline is drawn on the content box
   only, so it stops at the text. */
:is(.t-body, .t-caption) a:is(.link--video, .link--web) {
  white-space: nowrap; /* the icon hangs off the link's end, so the link stays on one line */
  padding-right: var(--icon-room);
  background-origin: content-box;
  background-clip: content-box;
}

:is(.t-body, .t-caption) a:is(.link--video, .link--web)::after {
  left: auto;
  right: 0;
  margin-left: 0;
  bottom: 0.236em; /* on the baseline */
  opacity: 1;
}

:is(.t-body, .t-caption) a.link--video {
  --icon-room: 1.3em;
}

:is(.t-body, .t-caption) a.link--video::after {
  width: 0.9em;
  height: 0.75em;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10' fill='none' stroke='black' stroke-width='1.3' stroke-linejoin='round'%3E%3Crect x='1' y='1.5' width='7' height='7' rx='1.2'/%3E%3Cpath d='M8 4.2l3-1.7v5l-3-1.7z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 10' fill='none' stroke='black' stroke-width='1.3' stroke-linejoin='round'%3E%3Crect x='1' y='1.5' width='7' height='7' rx='1.2'/%3E%3Cpath d='M8 4.2l3-1.7v5l-3-1.7z'/%3E%3C/svg%3E") center / contain no-repeat;
}

:is(.t-body, .t-caption) a.link--web {
  --icon-room: 1.18em;
}

:is(.t-body, .t-caption) a.link--web::after {
  width: 0.78em;
  height: 0.78em;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.2'%3E%3Ccircle cx='6' cy='6' r='5'/%3E%3Cellipse cx='6' cy='6' rx='2.2' ry='5'/%3E%3Cpath d='M1 6h10'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.2'%3E%3Ccircle cx='6' cy='6' r='5'/%3E%3Cellipse cx='6' cy='6' rx='2.2' ry='5'/%3E%3Cpath d='M1 6h10'/%3E%3C/svg%3E") center / contain no-repeat;
}

.t-body .project__link {
  margin-top: calc(var(--body-link-gap-bl) * var(--baseline));
}

.t-caption {
  --fs: var(--caption-size);
  --lh: calc(var(--caption-leading-bl) * var(--baseline));
  --m: var(--caption-m);
  color: var(--caption-color);
  font-family: var(--caption-font);
  font-style: var(--caption-style);
  font-weight: var(--caption-weight);
  letter-spacing: var(--caption-tracking);
}
