/* The theme. One face, black on white, metadata in caps — read out of the same
   2026 portfolio PDF the print output was, and print/lib/theme.typ is its
   sibling. What differs is what has to: a page that scrolls has no bottom
   margin, so it is spacing that separates one work from the next, and a screen
   is read further away than a sheet of paper, so the type is a shade larger
   relative to its measure than 7pt on A4 landscape.

   IBM Plex Mono is vendored under fonts/ (OFL) and converted to woff2, so no
   system font can substitute itself in. The three faces after Light are
   declared and never fetched unless the text uses them — nothing in the six
   works does today, and the day a body paragraph carries emphasis the browser
   asks for the italic on its own rather than faking one. */

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/IBMPlexMono-Light.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/IBMPlexMono-LightItalic.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/IBMPlexMono-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/IBMPlexMono-SemiBoldItalic.woff2") format("woff2");
}

:root {
  /* --measure and --gutter are the same two numbers as MEASURE and GUTTER in
     site/lib/measure.mjs, which is what sizes every picture and decides which
     files the resampler writes. scripts/test-site.mjs fails if they drift
     apart. */
  --measure: 1280px;
  --gutter: 24px;

  /* Body text sets to its own measure, not the picture's: a line of monospace
     as wide as a photograph is a line nobody finishes. */
  --text-measure: 34rem;

  --ink: #111;
  --quiet: #555;
  --paper: #fff;

  --size-caption: 0.8125rem;
  --size-body: 0.9375rem;
  --leading: 1.55;
  --tracking: 0.07em;

  /* The space between one work and the next. On paper that job belongs to the
     page break. */
  --field: 7.5rem;

  color-scheme: light;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0 auto;
  padding: 0 var(--gutter);
  max-width: calc(var(--measure) + 2 * var(--gutter));
  background: var(--paper);
  color: var(--ink);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-weight: 300;
  font-size: var(--size-body);
  line-height: var(--leading);
  font-variant-ligatures: none;
}

/* Metadata is set in caps, as in the source document. Everything the artist
   actually wrote — body text, the medium, a title — is left as written. */
h1,
h2,
.tools,
figcaption,
.links,
.colophon .copyright {
  font-size: var(--size-caption);
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: var(--tracking);
  line-height: 1.5;
}

h1,
h2 {
  margin: 0;
}

/* The UA stylesheet sets `strong` to `bolder`, which is relative: against the
   300 this page is set in it resolves to 400, and no vendored face is 400, so
   the browser falls back to Light and the emphasis vanishes. SemiBold is the
   only bold there is, so say so. */
strong,
b {
  font-weight: 600;
}

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--quiet);
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Reachable by keyboard, invisible until it is. */
.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: static;
  display: inline-block;
  margin: 1rem 0;
}

/* The print output opens on a single block set low on its own page. Here that
   is a field of its own at the top of the scroll. */
.masthead {
  padding: 5rem 0 var(--field);
}

/* The name on one edge of the measure and the address on the other, which is
   the figcaption's arrangement and is here for the same reason: two facts of
   equal weight, so neither is indented under the other. They wrap to separate
   lines when the measure cannot hold both — at which point space-between has
   one item per line and leaves each one where it started, on the left. */
.masthead .nameplate {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 1.5rem;
}

/* Set as it is written, not in the caps the rest of the chrome is set in: an
   address in caps is an address nobody can copy. The print colophon can
   uppercase its own because paper is not copied from.

   The leading is the h1's, not the body's, so the two halves of the nameplate
   sit on one baseline rather than a shade apart. */
.masthead .contact {
  margin: 0;
  font-size: var(--size-caption);
  line-height: 1.5;
}

.masthead .subtitle {
  margin: 0;
  font-size: var(--size-caption);
  color: var(--quiet);
}

.tools {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 2rem;
}

.work {
  margin-bottom: var(--field);
}

/* The last thing in a work, and the last work on the page, already have the
   field below them. Their own bottom margin would add a second one. */
.work > *:last-child,
.work:last-child {
  margin-bottom: 0;
}

.work > header {
  margin-bottom: 2.5rem;
}

.work > header p {
  margin: 0;
  font-size: var(--size-caption);
}

.work > header .medium {
  margin-top: 0.4em;
}

.work > header .gloss,
.work > header .shown {
  color: var(--quiet);
}

/* A picture is placed at the width the measure gives it, and never wider than
   its own pixels: the max-width on each figure is that width, written by the
   generator from the file's real dimensions. The caption is hung on the
   figure, so it sits on the picture's own edges rather than the page's. */
figure {
  margin: 0 0 4rem;
}

figure img {
  display: block;
  width: 100%;
  height: auto;
}

figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-top: 0.75rem;
}

figcaption .where {
  text-align: right;
}

/* The work's own words, at their own measure. The print output justifies this
   column; at 34rem of monospace with no hyphenation, justifying it would open
   rivers, so it is set ragged. */
.words {
  max-width: var(--text-measure);
  margin: 0 0 4rem;
}

.words > *:first-child {
  margin-top: 0;
}

.words p {
  margin: 0 0 1.1em;
}

/* A heading inside a body. No work has one — the legal notice is the only
   document in the repository long enough to want sections — so this is its
   scale, and it is built from what the page already has rather than from a
   second set of sizes: a rule for the two halves, bold for a section, and the
   caps the rest of the site sets metadata in for the level under that. An h2
   here is the notice's own section, not a work's title, so it drops the caps
   treatment h1 and h2 get as chrome. */
.words h2 {
  margin: 2.8em 0 0.8em;
  padding-top: 1.4em;
  border-top: 1px solid var(--quiet);
  font-size: var(--size-body);
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
}

.words > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.words h3 {
  margin: 1.8em 0 0.4em;
  font-size: var(--size-body);
  font-weight: 600;
}

.words h4,
.words h5,
.words h6 {
  margin: 1.8em 0 0.4em;
  font-size: var(--size-caption);
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: var(--tracking);
}

/* The notice is the whole page rather than a column beside pictures, so it does
   not need the field a work leaves beneath itself. */
.legal {
  margin-bottom: 0;
}

/* A list item's paragraph is the item: it does not need a paragraph's gap under
   it, and the bullets sit closer to the measure than a browser's 40px. */
.words ul,
.words ol {
  margin: 0 0 1.1em;
  padding-left: 1.5em;
}

.words li p {
  margin-bottom: 0.4em;
}

.words hr {
  margin: 1.6em 0;
  border: 0;
  border-top: 1px solid var(--quiet);
}

.credits {
  margin: 1.6em 0 0;
  font-size: var(--size-caption);
}

.credits div {
  margin-bottom: 0.2em;
}

.credits dt,
.credits dd {
  display: inline;
  margin: 0;
}

/* A no-break space, not a plain one: generated content beside an inline box
   is not a reliable place to put a space that has to survive. */
.credits dt::after {
  content: ":\00a0";
}

.links {
  margin: 1.6em 0 0;
  padding: 0;
  list-style: none;
}

.links li + li {
  margin-top: 0.5em;
}

/* The last thing on the page is the notice and the copyright, and nothing
   else. The contact is in the masthead and the PDF is offered there too. */
.colophon {
  padding: var(--field) 0 5rem;
}

.colophon p {
  margin: 0;
  font-size: var(--size-caption);
}

/* Two lines of the same small print, so they set as two lines: the 2rem a
   .tools row carries elsewhere would open a gap between a statement and the
   link it belongs with. */
.colophon .tools {
  margin: 0;
}

@media (max-width: 640px) {
  :root {
    --field: 5rem;
  }

  .masthead {
    padding-top: 3rem;
  }

  figure {
    margin-bottom: 3rem;
  }

  /* Hung on both edges of a picture 1280 px wide; stacked under one 327 px
     wide, where there are not two edges worth hanging anything on. */
  figcaption {
    flex-direction: column;
  }

  figcaption .where {
    text-align: left;
  }
}
