/* ============================================================================
   FELIPE E. HARKER — PORTFOLIO STYLESHEET
   ----------------------------------------------------------------------------
   Every visual rule for the site lives in this one file. There is no CSS
   framework, no preprocessor, no build step and no JavaScript: what you read
   here is what the browser gets, and `index.html` is the only document that
   consumes it.

   THE DESIGN, IN ONE PARAGRAPH
   The same quiet, modern document the other three sites are set in. A neutral
   sans (Inter) carries every heading and every line of prose; a monospace
   (IBM Plex Mono) is reserved for recorded values — a year, a place, a URL, a
   stack — where the reader benefits from seeing at a glance that something is
   a literal rather than a sentence about one. Structure is carried by hairline
   rules and generous whitespace, not by heavy black bars, boxes, or drop
   shadows. Weight is used sparingly: nothing on the site is set bolder than
   600. One deep red is the only accent, and it means "this is interactive" —
   nothing else.

   WHAT THIS SITE INHERITS FROM THE OLD PORTFOLIO
   One thing, and it is the shape of the work list: a large cover on the left,
   a narrow column of facts on the right, a hairline under each project title,
   and the descriptive lines under that — what the thing is, what it is made
   of, what kind of work it was. The old site drew that with a drop-shadowed
   card that lifted on hover, an orange accent, a serif body face and a fixed
   left sidebar. None of those survive: a cover is a hairline-bordered object
   that takes the accent on its border when hovered, and navigation is the
   contents list, the same as on the other sites. The layout carried over; the
   finish did not.

   THE DESIGN IS WRITTEN DOWN
   The tokens, the section numbering of this file, and the class names for each
   kind of block — .doc, .kicker, .title, .section, .work, .caption — are
   deliberately plain, so a rule can be found from the markup and back again.
   Before changing type, colour, or rule weights, read the design standards
   page on Alexandria Library: a change here is a change to a standard four
   sites follow, not a local tweak.

   HOW THIS FILE IS ORGANISED
      1.  Design tokens ............ every colour, font, size and spacing value
      2.  Document skeleton ........ page frame, resets, base elements
      3.  Masthead ................. the title block at the top of the page
      4.  Abstract ................. the summary paragraph
      5.  Table of contents ........ the section index under the abstract
      6.  Section headings ......... "Selected Work", "About", …
      7.  Body copy ................ paragraphs, lists, labels, captions
      8.  Rules .................... the horizontal dividers
      9.  Work list ................ the project rows and their covers
     10.  Definition grid .......... the label/value block in About
     11.  References ............... the link list at the foot of the page
     12.  Colophon ................. page footer
     13.  Responsive ............... narrow-screen overrides

   To restyle the whole site, change a token in section 1 rather than editing
   the rules below — nearly every rule is expressed in terms of those tokens.
   ========================================================================= */


/* ============================================================================
   1. DESIGN TOKENS
   Change these, not the rules further down. The values are shared with
   hark_ornithology, alexandria_scripting and hark_resume; a divergence here is
   a divergence in the design language, not a local tweak.
   ========================================================================= */

:root {
  /* -- Colour: surfaces ----------------------------------------------------
     Beyond the page itself there is one barely-there warm tint. It is never
     used to shade a region of the page — a section is set off by whitespace
     and one hairline, not by a panel. The cover placeholder in section 9 uses
     it because a cover is a drawn object standing in for an image, which is
     the same kind of thing as an inline code span and not a region. */
  --color-bg: #ffffff;              /* page background */
  --color-surface: #faf9f7;         /* cover placeholder ground */
  --color-surface-hover: #f4f2ef;   /* inline code, neutral tags */

  /* -- Colour: text --------------------------------------------------------
     Three steps, in descending emphasis. Anything that is not prose — a
     dateline, a year, an eyebrow label — sits on one of the lower two, which
     is most of what keeps the page feeling light. */
  --color-text: #1c1a19;            /* headings and project titles */
  --color-text-soft: #4a4643;       /* secondary prose: summaries, notes */
  --color-text-mute: #7a746e;       /* tertiary: years, places, labels */

  /* -- Colour: accent ------------------------------------------------------
     A single deep red, and the only thing allowed to use it is something you
     can click: a project, a link, an address. The hover step is derived from
     it, so setting --color-accent alone re-accents the site. */
  --color-accent: #7c1405;
  --color-accent-hover: color-mix(in srgb, var(--color-accent) 72%, #000000);
  --color-selection: #ffe0d9;       /* ::selection highlight */

  /* -- Colour: rules -------------------------------------------------------
     Structure is hairlines, not bars. Both weights are 1px; they differ only
     in contrast, and even the "strong" one is a light grey. A divider should
     tell you where a section ends, not draw attention to itself doing it. */
  --color-rule: #eae7e3;            /* between rows within a section */
  --color-rule-strong: #d5d0ca;     /* between major sections */

  /* -- Type ----------------------------------------------------------------
     Both families are loaded from Google Fonts by the <link> in index.html.
     The fallbacks apply if that request fails. Change a family here AND in
     that <link> — one without the other silently falls back. */
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Helvetica, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* -- Type weights --------------------------------------------------------
     Three weights, and no bold. 600 is the heaviest thing on the site; the
     jump from 400 to 600 is enough to mark a heading when the type around it
     is calm. Use --weight-medium for anything that needs to be *noticed*
     without being a heading: a project's stack line, a reference's name. */
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-strong: 600;

  /* -- Type scale ----------------------------------------------------------
     Sizes are smaller than a serif would need at the same apparent scale:
     Inter has a large x-height, so it reads bigger per px. */
  --size-title: 34px;               /* the name at the top */
  --size-section: 23px;             /* section heading */
  --size-subsection: 17px;          /* project title */
  --size-body: 16px;                /* body paragraphs */
  --size-abstract: 16px;            /* abstract paragraph */
  --size-table: 15px;               /* list items, project summaries */
  --size-data: 13px;                /* monospace data: years, places, URLs */
  --size-caption: 13px;             /* captions, colophon */
  --size-fine: 12px;                /* reference descriptions */
  --size-label: 11px;               /* uppercase eyebrow labels */

  /* -- Letter-spacing ------------------------------------------------------
     Inter is drawn for interfaces and sets slightly loose at display sizes,
     so large type is tightened and small caps-tracked type is opened up. */
  --track-tight: -0.02em;           /* the name and section headings */
  --track-body: -0.006em;           /* running prose */
  --track-label: 0.08em;            /* uppercase eyebrow labels */

  /* -- Spacing -------------------------------------------------------------
     A coarse scale; prefer these over bare pixel values. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 18px;
  --space-5: 26px;
  --space-6: 40px;
  --space-7: 56px;

  /* -- Radius --------------------------------------------------------------
     Used only where an element is a drawn object or a control rather than a
     run of text — a cover, a code span. Text stays square; rounding it would
     read as decoration. */
  --radius-sm: 4px;

  /* -- Measure -------------------------------------------------------------
     --measure caps the document. It matches Alexandria Library rather than the
     resume: the work list is a two-column row and needs the width to hold a
     cover at a size worth looking at. --measure-text caps running prose inside
     that column so lines stay readable even though the page is wide. */
  --measure: 1000px;
  --measure-text: 70ch;

  /* -- Page frame ----------------------------------------------------------
     The headroom and footroom. Both sit outside the --space-* scale on
     purpose: they are larger than any gap between elements, which is what
     makes the document read as a page rather than as a scrolling feed. */
  --doc-pad-top: 80px;
  --doc-pad-bottom: 120px;
  --doc-pad-x: 40px;                /* gutter between content and window edge */

  /* -- Work-list geometry --------------------------------------------------
     Section 9 only. The old portfolio split its rows 65/35; 2fr/1fr is the
     same proportion expressed as a grid, and it keeps every cover the same
     width so a scrolled column of them reads as a column rather than as
     ragged boxes. The cover's aspect ratio is a token so that swapping the
     placeholder for a real image cannot change the page's rhythm. */
  --work-cover-ratio: 3 / 2;
  --work-gap: var(--space-6);

  /* -- Motion --------------------------------------------------------------
     One duration, one easing, everywhere. */
  --transition: 140ms ease;
}


/* ============================================================================
   2. DOCUMENT SKELETON
   ========================================================================= */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;    /* the contents list jumps to sections */
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--size-body);
  font-weight: var(--weight-regular);
  line-height: 1.6;
  letter-spacing: var(--track-body);
  /* Kerning and default ligatures on; Inter's contextual alternates are left
     off, since they change letterforms mid-word in ways that read as a bug. */
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

/* Links carry the accent. Underlines are set per context rather than globally:
   a link inside prose keeps the browser's underline, while a link that *is* a
   block — a project, a contents entry — drops it and marks itself another
   way. */
a {
  color: var(--color-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--transition);
}

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

a:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

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

figure { margin: 0; }

code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--color-surface-hover);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
}

/* `.doc` is the single centred column the page sits inside. */
.doc {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--doc-pad-top) var(--doc-pad-x) var(--doc-pad-bottom);
}

/* Anchored sections stop below the point they would otherwise land, so a
   heading is never flush against the top edge of the viewport. */
[id] { scroll-margin-top: var(--space-6); }

/* Honour a reader's request for reduced motion: nothing here is meaningful
   animation, so it can all be switched off. The old portfolio faded every row
   in on scroll; that is exactly the kind of motion this rule exists to drop,
   and it is not reintroduced above. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}


/* ============================================================================
   3. MASTHEAD
   The name, what the work is, and where it is done from. Centred: this page is
   the front of a publication rather than the head of a record, which is the
   call Alexandria Library and the ornithology report make on their homepages
   and the opposite of the one the resume makes.
   ========================================================================= */

/* Small tracked caps above the name. Set in the body face rather than the
   monospace: mono caps at this size read as a system message, not a label. */
.kicker {
  text-align: center;
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-mute);
  margin: 0 0 var(--space-4);
}

.title {
  text-align: center;
  font-size: var(--size-title);
  font-weight: var(--weight-strong);
  line-height: 1.15;
  letter-spacing: var(--track-tight);
  margin: 0 0 var(--space-3);
}

.subtitle {
  text-align: center;
  /* Between --size-body and --size-section, and used once. A token here would
     be a name with a single caller. */
  font-size: 17px;
  font-weight: var(--weight-regular);
  color: var(--color-text-soft);
  margin: 0 0 var(--space-5);
}

/* The one line of the masthead that is a recorded value, so it is the one line
   set in the data face. */
.dateline {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--size-data);
  color: var(--color-text-mute);
  margin: 0 0 var(--space-6);
}

/* The hairline between dateline items. It is a rendered separator rather than
   a character in the markup, so a copied line does not come with pipes in it,
   and so the responsive rules can drop it when the line stacks. */
.dateline-sep {
  color: var(--color-rule-strong);
  user-select: none;
}


/* ============================================================================
   4. ABSTRACT
   One paragraph under the masthead saying what the reader is looking at. It is
   capped at --measure-text and centred within the wider document column, so it
   does not run the full width the work list needs.
   ========================================================================= */

.abstract {
  max-width: var(--measure-text);
  margin: 0 auto var(--space-6);
}

.abstract-label {
  text-align: center;
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-mute);
  margin: 0 0 var(--space-3);
}

.abstract p {
  font-size: var(--size-abstract);
  line-height: 1.7;
  color: var(--color-text-soft);
  margin: 0 0 var(--space-3);
}

.abstract p:last-child { margin-bottom: 0; }


/* ============================================================================
   5. TABLE OF CONTENTS
   A plain index of the sections below, and the whole of this site's
   navigation: with three sections there is nothing a fixed sidebar would do
   that this does not. There are no numerals — the list order is the document
   order, which is all a numeral was telling the reader.
   ========================================================================= */

.toc-label {
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-mute);
  margin: 0 0 var(--space-3);
}

/* Short enough to sit on one line. It wraps rather than scrolling: every entry
   is a destination, and a destination that has scrolled out of the strip is a
   destination the reader will not find. */
.toc {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  padding: 0;
  font-size: var(--size-table);
}

.toc a {
  display: block;
  padding: var(--space-1) 0;
  text-decoration: none;
  color: var(--color-text-soft);
  transition: color var(--transition);
}

.toc a:hover { color: var(--color-accent); }


/* ============================================================================
   6. SECTION HEADINGS
   Plain labels — "Selected Work", "About". Nothing is numbered: the headings
   and the contents list carry the same names, which is enough to navigate by.
   ========================================================================= */

.section-heading {
  font-size: var(--size-section);
  font-weight: var(--weight-strong);
  line-height: 1.25;
  letter-spacing: var(--track-tight);
  margin: 0 0 var(--space-4);
}

/* Whatever follows a section heading gets its gap from the heading's own
   bottom margin, so elements carrying a top margin of their own drop it here
   rather than doubling up. */
.section-heading + .body-text,
.section-heading + .work-list,
.section-heading + .reference-list,
.section-heading + .facts { margin-top: 0; }

/* Each section opens with a hairline. The generous top margin, not the rule's
   weight, is what separates one section from the next. */
.section {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-rule-strong);
}


/* ============================================================================
   7. BODY COPY
   ========================================================================= */

.body-text {
  font-size: var(--size-body);
  line-height: 1.7;
  color: var(--color-text-soft);
  max-width: var(--measure-text);
  margin: 0 0 var(--space-4);
}

.body-text:last-child { margin-bottom: 0; }

.list {
  font-size: var(--size-table);
  line-height: 1.7;
  color: var(--color-text-soft);
  max-width: var(--measure-text);
  margin: var(--space-3) 0 0;
  padding-left: var(--space-4);
}

.list li { margin-bottom: var(--space-2); }
.list li:last-child { margin-bottom: 0; }

/* An uppercase tracked eyebrow above a block of content. */
.label {
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-mute);
  margin: 0 0 var(--space-3);
}

/* Caption under a figure. Sentence case, never numbered — a caption describes
   the thing above it, and "Figure 2" describes nothing. */
.caption {
  font-size: var(--size-caption);
  color: var(--color-text-mute);
  line-height: 1.55;
  margin: var(--space-3) 0 0;
  max-width: var(--measure-text);
}

/* Monospace run of recorded data inside prose: a year, a count, a version. */
.data {
  font-family: var(--font-mono);
  font-size: var(--size-data);
  color: var(--color-text-mute);
  font-variant-numeric: tabular-nums;   /* digits line up between rows */
}


/* ============================================================================
   8. RULES
   Both weights are hairlines; they differ in contrast, not thickness.
   ========================================================================= */

/* Major division — under the masthead. */
.rule {
  border: none;
  border-top: 1px solid var(--color-rule-strong);
  margin: 0 0 var(--space-6);
}

/* Row-level division within a block — under a project title, which is the one
   piece of furniture carried over wholesale from the old portfolio. */
.rule-soft {
  border: none;
  border-top: 1px solid var(--color-rule);
  margin: 0 0 var(--space-4);
}


/* ============================================================================
   9. WORK LIST
   One project per row: a cover on the left, the facts about it on the right.
   Every row has the same parts in the same order — cover, title, hairline,
   summary, stack, kind, address — so a reader scanning down the right-hand
   column finds the same kind of thing at the same offset every time.

   COVERS
   There are no cover images yet. `.work-cover` is the frame they will drop
   into: it holds the aspect ratio, the border and the hover state, and its
   only child is a placeholder carrying the project's name as text. When an
   image arrives, replace the `.work-cover-placeholder` span with an <img> and
   change nothing else.
   ========================================================================= */

.work-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Rows are separated by whitespace and a hairline. The last one drops both, so
   a section does not end on a rule sitting a few pixels above the section rule
   that follows it. */
.work {
  display: grid;
  grid-template-columns: 2fr 1fr;   /* the old site's 65/35, as a grid */
  gap: var(--work-gap);
  align-items: start;
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-rule);
}

.work:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

/* -- The cover -------------------------------------------------------------
   A hairline-bordered object, not a shadowed card. The old portfolio lifted
   and shadowed its covers on hover; here the border takes the accent instead,
   which is the same signal the ornithology report's media thumbnails give and
   costs the page no motion. Hovering either half of the row lights the cover
   and the title together, so the two columns read as one target. */
.work-cover {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: var(--work-cover-ratio);
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: border-color var(--transition);
}

.work:hover .work-cover,
.work-cover:hover { border-color: var(--color-accent); }

/* An image, once there is one, fills the frame and is cropped to it rather
   than letterboxed: the frame's ratio is the design, and a cover that does not
   match it should be re-cropped, not padded. */
.work-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The stand-in. It names the project and says plainly that it is a stand-in,
   so nobody has to guess whether an image failed to load. Both lines are
   muted: this is a note about a missing asset, not the project's title, and
   the real title is one column to the right. */
.work-cover-placeholder {
  display: block;
  padding: var(--space-5);
  text-align: center;
  color: var(--color-text-mute);
}

.work-cover-placeholder .name {
  display: block;
  font-size: var(--size-subsection);
  font-weight: var(--weight-medium);
  line-height: 1.3;
  letter-spacing: var(--track-tight);
}

.work-cover-placeholder .note {
  display: block;
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

/* -- The facts column ------------------------------------------------------
   Title, hairline, then the descriptive lines, in descending specificity. */
.work-title {
  font-size: var(--size-subsection);
  font-weight: var(--weight-strong);
  line-height: 1.3;
  letter-spacing: var(--track-tight);
  margin: 0 0 var(--space-3);
}

/* The title's link drops its underline: it is a heading first, and the row's
   shared hover state already marks the whole thing as one target. */
.work-title a {
  color: inherit;
  text-decoration: none;
  transition: color var(--transition);
}

.work:hover .work-title a,
.work-title a:hover { color: var(--color-accent); }

/* One sentence on what the project is. Prose, so it stays in the body face. */
.work-summary {
  font-size: var(--size-table);
  line-height: 1.65;
  color: var(--color-text-soft);
  margin: 0 0 var(--space-3);
}

/* What it is built from: a list of literals read off the project, so it is set
   in the data face, the same as the dateline in the masthead. */
.work-stack {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--size-data);
  color: var(--color-text-mute);
  margin: 0 0 var(--space-3);
}

.work-stack .sep { color: var(--color-rule-strong); user-select: none; }

/* What kind of work it was — Research, Professional, Personal. The old site
   set this in grey italic; the standards have an eyebrow label for exactly
   this job, so it uses that instead. */
.work-kind {
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--color-text-mute);
  margin: 0 0 var(--space-3);
}

/* The address. A URL is a recorded value and a link at once: the data face
   carries the first, the accent the second. Its underline is a border that
   appears on hover, so the line sits quiet at rest without ceasing to look
   like a link. */
.work-link {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--size-data);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition), color var(--transition);
}

.work-link:hover { border-bottom-color: var(--color-accent); }


/* ============================================================================
   10. DEFINITION GRID
   An uppercase label in the left column, its values in the right. The same
   shape the resume uses for skills, and for the same reason — the labels are a
   fixed short vocabulary, and stacking them above their values would double
   the height of the block to no gain.
   ========================================================================= */

.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3) var(--space-5);
  margin: var(--space-5) 0 0;
  max-width: var(--measure-text);
}

.facts dt {
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  font-size: var(--size-label);
  font-weight: var(--weight-medium);
  color: var(--color-text-mute);
  align-self: baseline;
}

/* The values are prose — the names of tools and places as they are written,
   not literals read off a record — so they stay in the body face. */
.facts dd {
  margin: 0;
  font-size: var(--size-table);
  line-height: 1.6;
  color: var(--color-text-soft);
}


/* ============================================================================
   11. REFERENCES
   A plain list of links with a line of description each, gathered at the foot
   of the page. Nothing in the prose above points at them with a bracketed
   marker; where the prose needs to send a reader to one, it links the words
   that name it.
   ========================================================================= */

.reference-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  font-size: var(--size-table);
}

/* Each entry is its own row, separated by a hairline, so a long description
   never runs into the next link. */
.reference-list li {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-rule);
  line-height: 1.65;
}

.reference-list li:first-child { padding-top: 0; }
.reference-list li:last-child { border-bottom: none; }

/* The link is the entry's heading, so it carries the medium weight. */
.reference-list a {
  font-weight: var(--weight-medium);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition), color var(--transition);
}

.reference-list a:hover { border-bottom-color: var(--color-accent); }

/* An address whose name *is* the address is set in the data face. */
.reference-list a.path { font-family: var(--font-mono); font-size: 0.92em; }

/* The description sits under the link on its own line: side by side, the two
   compete, and the link stops looking clickable. */
.reference-list .desc {
  display: block;
  color: var(--color-text-mute);
  font-size: var(--size-caption);
  margin-top: var(--space-1);
}


/* ============================================================================
   12. COLOPHON
   ========================================================================= */

.colophon {
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-rule-strong);
  font-size: var(--size-caption);
  line-height: 1.6;
  color: var(--color-text-mute);
}


/* ============================================================================
   13. RESPONSIVE
   Two breakpoints, and only one of them touches type.

   At 860px the work list collapses to a single column: below roughly that
   width the facts column is too narrow to hold a project title on one line,
   and a cover shrunk to fit beside it is no longer worth looking at. That is a
   limit of the layout rather than of a device, which is why it sits well above
   the phone breakpoint.

   At 640px the page frame tightens and display type steps down.
   ========================================================================= */

@media (max-width: 860px) {
  /* Cover above, facts below — the order the markup is already in. */
  .work { grid-template-columns: 1fr; gap: var(--space-4); }

  /* Stacked, a cover has the full column width, and a 3:2 frame that wide is
     taller than the block of facts beside it ever was. Widening the ratio
     keeps a whole row on screen at once. */
  :root { --work-cover-ratio: 16 / 9; }
}

@media (max-width: 640px) {
  /* Display type steps down by redefining the tokens, so every rule that
     already reads from them follows without being restated here. Only rules
     with no token behind them need a line of their own below. */
  :root {
    --size-title: 27px;
    --size-section: 20px;
    --size-subsection: 16px;
    --doc-pad-top: 44px;
    --doc-pad-bottom: 80px;
    --doc-pad-x: 24px;
  }

  .doc { padding: var(--doc-pad-top) var(--doc-pad-x) var(--doc-pad-bottom); }

  /* The masthead subtitle has no token of its own — see section 3. */
  .subtitle { font-size: 16px; }

  /* On a phone the dateline has no room for two items abreast, so it becomes
     one item per line and the separator is dropped rather than left stranded
     at the end of a row. */
  .dateline { flex-direction: column; gap: var(--space-1); }
  .dateline-sep { display: none; }

  /* Stack label above values instead of side by side. */
  .facts { grid-template-columns: 1fr; gap: var(--space-1); }
  .facts dt { margin-top: var(--space-4); }
  .facts dt:first-child { margin-top: 0; }
}
