/* style.css — layout and treatment. Every value comes from tokens.css. */

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
}

a { color: inherit; }

:focus-visible {
  outline: var(--rule-heavy) solid var(--accent);
  outline-offset: var(--space-1);
}

/* .wrap owns the side gutters. Anything that also carries .wrap must set only
   PADDING-BLOCK — a `padding: X 0` shorthand later in this file silently wins
   and zeroes the gutters, which put the whole page flush against the edge of
   the screen on a phone before it was caught. */
.wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding-inline: var(--space-3);
}

/* --- Utility face: the voice of all data on this page ---------------------
   Four rules were each restating these same four properties. Stated once here;
   below, each only says how it DIFFERS (colour, rules, position). */
.util, .go, .entry-code, .plate::after {
  font-family: var(--font-util);
  font-size: var(--step--1);
  letter-spacing: var(--track-util);
  text-transform: uppercase;
}

.util { color: var(--ink-soft); }

/* --- Masthead ------------------------------------------------------------ */
.masthead {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
  align-items: baseline;
  padding-block: var(--space-3);
  border-bottom: var(--rule) solid var(--ground-edge);
}

/* --- Hero ----------------------------------------------------------------
   Headline and portrait sit side by side. The portrait is 3:4 because every
   picture of the subject is portrait or square — a 21:9 band would crop his
   head off, so the frame follows the photograph rather than the other way
   round. */
.hero {
  padding-block: var(--space-6) var(--space-5);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--portrait-col));
  gap: var(--space-5);
  align-items: end;
}

.hero-line {
  font-family: var(--font-display);
  font-size: var(--step-display);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  margin: 0;
}

.hero-line em {
  font-style: normal;
  color: var(--accent);
}

.hero-sub {
  margin: var(--space-4) 0 0;
  max-width: var(--measure);
  font-size: var(--step-1);
}

.hero-meta { margin-top: var(--space-3); }

/* --- Plate: an image slot that looks deliberate while it is still empty ----
   Uses background-image, never <img>, so a file that does not exist yet
   renders as a blank labelled plate instead of a broken-image icon. Drop a
   correctly named file into assets/ and it fills. The corner stamp stays
   visible either way — parts catalogues stamp the figure number on the plate
   whether or not the figure is shown. */
.plate {
  position: relative;
  background-color: var(--ground-deep);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: var(--rule) solid var(--ground-edge);
  border-radius: var(--radius);
  /* 1.91:1 — the Open Graph card ratio. Every work plate holds the same share
     card the project's own site serves, and those carry a wordmark and a line
     of type. A squarer frame would crop the words off, so the frame follows
     the artwork rather than the artwork getting cut to fit the frame. */
  aspect-ratio: 1200 / 630;
}

/* Modifiers MUST come after .plate — an aspect-ratio declared before it loses
   the source-order tie and the plate silently reverts to 4:3. This bit once
   already and rendered the portrait as a landscape crop. */
.plate--portrait { aspect-ratio: 3 / 4; }

/* The stamp earns its place on an EMPTY plate — it is what makes a blank read
   as a labelled catalogue figure rather than a hole. On a filled plate it does
   the opposite: it repeats the code already on the rail two columns to the left
   and sits on top of the artwork. So it appears only where it is doing work. */
.plate:not([data-stamp])::after { content: none; }

.plate::after {
  content: attr(data-stamp);
  position: absolute;
  left: 0;
  bottom: 0;
  padding: var(--space-1) var(--space-2);
  background: var(--ground);
  border-top: var(--rule) solid var(--ground-edge);
  border-right: var(--rule) solid var(--ground-edge);
  color: var(--accent);
  /* Explicit: this one is NOT uppercased. Joining the shared utility-face rule
     above would have silently turned "Fig. A" into "FIG. A" — a plate caption
     is a figure label, and reads as one in mixed case. */
  text-transform: none;
}

/* --- Index of works ------------------------------------------------------ */
.index-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: var(--rule-heavy) solid var(--ink);
}

/* Three columns: material code · what it is · the plate. The plate is capped
   rather than full-bleed — an empty plate the width of the page reads as a
   hole, and a filled one would outshout the entry it belongs to. */
.entry {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr) minmax(0, var(--figure-col));
  gap: var(--space-4);
  padding: var(--space-5) 0;
  border-bottom: var(--rule) solid var(--ground-edge);
  align-items: start;
}

/* The rail carries the material code. It is not a sequence number: the prefix
   says what the thing is MADE OF, which is the one fact this page exists to
   show. SW software · ST steel · CH chemistry · BO botany · PR prose. */
.entry-code {
  color: var(--accent);
  border-top: var(--rule-heavy) solid var(--accent);
  padding-top: var(--space-2);
}

.entry-body { display: grid; gap: var(--space-3); }

.entry-title {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  margin: 0;
}

.entry-what {
  margin: 0;
  max-width: var(--measure);
  font-size: var(--step-1);
}

.entry-note {
  margin: 0;
  max-width: var(--measure);
  color: var(--ink-soft);
}

.entry-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  align-items: baseline;
  margin: 0;
  padding: 0;
  list-style: none;
}

.entry-figure { margin: 0; }

/* Links read as destinations, not decoration. */
.go {
  color: var(--accent);
  text-decoration-thickness: var(--rule);
  text-underline-offset: var(--space-1);
  transition: color var(--dur-quick) var(--ease);
}

.go:hover { color: var(--accent-lift); }

.status { color: var(--ink-soft); }
.status--live { color: var(--accent); }

/* --- Footer -------------------------------------------------------------- */
.footer {
  padding-block: var(--space-5) var(--space-6);
  display: grid;
  gap: var(--space-2);
}

/* --- Motion: one deliberate moment on load, nothing on scroll ------------- */
.rise {
  animation: rise var(--dur) var(--ease) both;
}

.rise-2 { animation-delay: 90ms; }
.rise-3 { animation-delay: 180ms; }
.rise-4 { animation-delay: 300ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(var(--space-3)); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .rise { animation: none; }
  * { transition-duration: 1ms !important; }
}

/* --- Narrow screens ------------------------------------------------------ */
/* Tablet: drop the plate under the text, keep the code rail. */
@media (max-width: 64rem) {
  .entry { grid-template-columns: var(--rail) minmax(0, 1fr); }
  .entry-figure { grid-column: 2; max-width: var(--figure-col); }
}

@media (max-width: 46rem) {
  /* Portrait drops below the headline and stops being full-bleed tall. */
  .hero {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }
  .plate--portrait { max-width: var(--portrait-col); }

  .entry {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
  .entry-figure {
    grid-column: 1;
    max-width: none;
    margin-top: var(--space-2);
  }
  .entry-code {
    border-top: none;
    padding-top: 0;
  }
  .hero { padding-block: var(--space-5) var(--space-4); }
}
