/* Rediscovering Victorian Women Travellers — styles per DESIGN.md (canonical).
   Palette, type and spacing are tokens from DESIGN.md; do not hard-code new values. */

:root {
  color-scheme: light;
  --paper: #faf7f1;
  --ink: #332a26;
  --accent: #8e3b2f;
  --stone: #c4a184;
  --rule: #eae3d5;
  --muted: #75655d;
  --error: #6d2f24;
  --success: #3f6b4a;
  --sp-xs: 4px; --sp-sm: 8px; --sp-md: 16px; --sp-lg: 32px; --sp-xl: 64px; --sp-xxl: 96px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Source Serif 4', serif;
  font-size: 1.05rem;
  line-height: 1.7;
  overflow-x: clip;
}

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

.wrap { max-width: 62rem; margin: 0 auto; padding: 0 clamp(var(--sp-lg), 6vw, var(--sp-xxl)); }

/* Navigation */
nav.site {
  position: sticky;
  top: 0;
  z-index: 1100;
  background: var(--accent);
  padding: var(--sp-md) 0;
}
nav.site .wrap { display: flex; gap: var(--sp-lg); flex-wrap: wrap; align-items: baseline; }
nav.site a {
  font-family: 'Cabin', sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: rgba(250, 247, 241, 0.82);
  text-decoration: none;
}
nav.site a:hover { color: #ffffff; }
nav.site a.active {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 7px;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--stone);
}
.nav-brand { display: none; font-size: 0.95rem; color: #ffffff !important; }
.nav-links { display: contents; }
.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--sp-xs);
  margin-left: auto;
}
.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: #faf7f1;
  margin: 5px 0;
}
@media (max-width: 1040px) {
  nav.site .wrap { align-items: center; }
  .nav-brand { display: block; font-family: 'Cabin', sans-serif; font-weight: 700; text-decoration: none; }
  .nav-toggle { display: block; }
  .nav-links {
    display: none;
    width: 100%;
    flex-direction: column;
    gap: 0;
    padding-top: var(--sp-sm);
  }
  nav.site.open .nav-links { display: flex; }
  .nav-links a { padding: var(--sp-md) 0; border-top: 1px solid rgba(250, 247, 241, 0.18); }
}

/* Skip link: hidden until focused, then a solid ink tab top-left */
.skip-link {
  position: absolute;
  left: -100vw;
  top: 0;
  z-index: 1200;
  font-family: 'Cabin', sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--ink);
  color: var(--paper);
  padding: var(--sp-sm) var(--sp-md);
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* Keyboard focus: same accent ring everywhere */
figure.painting img:focus-visible,
.station-h:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Graduated map hero (homepage): Stieler 1895, dissolving into the paper */
.hero-visual { position: relative; height: clamp(480px, 72vh, 660px); overflow: hidden; }
@media (max-width: 700px) { .hero-visual { height: clamp(360px, 52vh, 460px); } }
.hero-visual picture { display: contents; }
.hero-visual img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Frame the centre of the Johnston detail, not its top: this brings
     Jerusalem (in the pale band) and the Dead Sea into view instead of
     cropping them off. object-position by percentage keeps the SAME slice of
     the map on every screen size, so the framing is uniform across browsers
     (William, 2026-07-13). */
  object-position: center 42%;
}
.hero-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to bottom,
      rgba(51, 42, 38, 0.08) 0%,
      rgba(250, 247, 241, 0) 40%,
      rgba(250, 247, 241, 0.42) 58%,
      rgba(250, 247, 241, 0.80) 72%,
      rgba(250, 247, 241, 0.94) 85%,
      var(--paper) 100%
    ),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.07'/></svg>");
}
/* Narrow viewports: the hero is short and the title block covers most of it,
   so the dissolve must arrive early. Wide viewports keep the painting. */
@media (max-width: 1000px) {
  .hero-visual::after {
    background:
      linear-gradient(
        to bottom,
        rgba(51, 42, 38, 0.15) 0%,
        rgba(250, 247, 241, 0.06) 22%,
        rgba(250, 247, 241, 0.55) 40%,
        rgba(250, 247, 241, 0.9) 54%,
        var(--paper) 82%
      ),
      url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.07'/></svg>");
  }
}
.hero-text { position: absolute; left: 0; right: 0; bottom: var(--sp-lg); z-index: 2; }
/* On desktop the title rides up onto the map itself; legibility comes from a
   feathered pool of paper light BAKED INTO THE HERO ASSET under the text
   block (rebake it if the text moves) - never a CSS overlay: no scrims, no
   halos (both rejected 2026-07-07, they draw fog lines and glows). The hero
   kicker runs a size up in a deepened red so it cannot merge with the map's
   own red lettering. */
@media (min-width: 1001px) { .hero-text { bottom: 40px; } }
.hero-text .kicker { font-size: 0.95rem; letter-spacing: 0.18em; color: #7c2f22; }
/* Keep each institution on one line, and on phones stack them (dropping the
   middot) so the credit never wraps mid-name or orphans the separator
   (William's iPhone, 2026-07-13). */
.hero-text .kicker .inst { white-space: nowrap; }
@media (max-width: 560px) {
  .hero-text .kicker .kicker-sep { display: none; }
  .hero-text .kicker .inst { display: block; }
}
/* The hero's source credit lives at the foot of the page (William's call,
   2026-07-07), quieter than the footer's own lines. */
.footer-credit { font-size: 0.72rem; opacity: 0.85; }
.intro { border-top: none; padding: var(--sp-lg) 0 var(--sp-xl); }
.intro .actions { margin-top: var(--sp-lg); display: flex; gap: var(--sp-md); flex-wrap: wrap; }

/* Hero */
header.hero { padding: var(--sp-xl) 0; }
.kicker {
  font-family: 'Cabin', sans-serif;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-md);
}
/* Homepage hero runs title first, kicker beneath (decided 2026-07-05,
   restored 2026-07-07 after a "polish" pass matched it to the subpage
   pattern): under the H1 the kicker sits lower in the dissolve, on calm
   ground, instead of riding the least-dissolved band of the painting. */
h1 + .kicker { margin-top: var(--sp-sm); margin-bottom: 0; }
h1 {
  font-family: 'Fraunces', serif;
  font-optical-sizing: auto;
  font-size: 2.8rem;
  font-weight: 600;
  line-height: 1.05;
  max-width: 46rem;
}
@media (max-width: 600px) { h1 { font-size: 2rem; } }
.subtitle {
  font-family: 'Fraunces', serif;
  font-style: italic;
  font-size: 1.2rem;
  line-height: 1.4;
  color: var(--muted);
  margin-top: var(--sp-md);
  max-width: 42rem;
}
.hero .lead { max-width: 42rem; margin-top: var(--sp-lg); }
.hero .actions { margin-top: var(--sp-lg); display: flex; gap: var(--sp-md); flex-wrap: wrap; }

/* Buttons */
.btn {
  display: inline-block;
  font-family: 'Cabin', sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: var(--sp-sm) var(--sp-lg);
  border: 2px solid var(--ink);
  text-decoration: none;
  cursor: pointer;
}
.btn-primary { background: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--accent); border-color: var(--accent); color: #faf7f1; }
.btn-secondary { background: transparent; color: var(--ink); }
.btn-secondary:hover { background: var(--ink); color: var(--paper); }
.btn-disabled {
  background: transparent;
  color: var(--muted);
  border-color: var(--stone);
  cursor: default;
  pointer-events: none;
}

/* Sections */
section { padding: var(--sp-xl) 0; border-top: 1px solid var(--rule); scroll-margin-top: 64px; }
h2 {
  font-family: 'Fraunces', serif;
  font-size: 2.4rem;
  font-weight: 600;
  line-height: 1.12;
  margin-bottom: var(--sp-lg);
}
h3 {
  font-family: 'Fraunces', serif;
  font-size: 1.6rem;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: var(--sp-md);
}
p + p { margin-top: var(--sp-md); }
.measure { max-width: 42rem; }
a { color: var(--accent); }
a:hover { color: var(--ink); }
em { font-style: italic; }

/* Quotation block */
blockquote {
  border-left: 3px solid var(--accent);
  padding: var(--sp-sm) 0 var(--sp-sm) var(--sp-lg);
  margin: var(--sp-lg) 0;
}
blockquote p {
  font-family: 'Fraunces', serif;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.5;
}
blockquote cite {
  display: block;
  font-family: 'Cabin', sans-serif;
  font-style: normal;
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: var(--sp-sm);
}

/* Letter pull-quotes (Thomas's 1866 correspondence) */
.q-cite {
  display: block;
  font-family: 'Cabin', sans-serif;
  font-style: normal;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  line-height: 1.5;
  color: var(--muted);
  margin-top: var(--sp-md);
}
.q-cite em { font-style: italic; }

/* Inset variant: a short accent rule above an italic aside within a prose column */
blockquote.pull-quote {
  border: none;
  padding: 0;
  margin: var(--sp-lg) 0;
}
blockquote.pull-quote p {
  font-family: 'Fraunces', serif;
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ink);
}
blockquote.pull-quote p::before {
  content: "";
  display: block;
  width: 2.25rem;
  height: 2px;
  background: var(--accent);
  margin-bottom: var(--sp-md);
}

/* Card variant: a self-contained tinted letter-slip */
blockquote.pull-card {
  border: 1px solid var(--rule);
  border-left: 4px solid var(--accent);
  background: #f4ede0;
  padding: var(--sp-lg);
  max-width: 34rem;
  margin: var(--sp-lg) 0;
}
blockquote.pull-card.center { margin-left: auto; margin-right: auto; }
blockquote.pull-card.float-right {
  float: right;
  width: 17rem;
  max-width: 45%;
  margin: var(--sp-xs) 0 var(--sp-md) var(--sp-lg);
}
blockquote.pull-card.float-left {
  float: left;
  width: 17rem;
  max-width: 45%;
  margin: var(--sp-xs) var(--sp-lg) var(--sp-md) 0;
}
@media (max-width: 680px) {
  blockquote.pull-card.float-right,
  blockquote.pull-card.float-left {
    float: none; width: auto; max-width: none; margin: var(--sp-lg) 0;
  }
}
.intro .actions { clear: both; }
#journey .map-controls { clear: both; }
blockquote.pull-card .card-kicker {
  display: block;
  font-family: 'Cabin', sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-sm);
}
blockquote.pull-card p {
  font-family: 'Fraunces', serif;
  font-style: italic;
  font-size: 1.1rem;
  line-height: 1.5;
  color: var(--ink);
}

/* Split layout: text beside painting */
.split { display: grid; grid-template-columns: 1.1fr 1fr; gap: var(--sp-xl); align-items: start; }
@media (max-width: 760px) { .split { grid-template-columns: 1fr; gap: var(--sp-lg); } }

/* Painting figure with pigment strip (signature element) */
figure.painting figcaption {
  font-family: 'Cabin', sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.45;
  color: var(--muted);
  margin-top: var(--sp-sm);
}

figure.painting img { cursor: zoom-in; }
figure.painting img:hover { opacity: 0.93; }

/* A single figure set within a prose column spans that column. */
.measure > figure.painting { margin: var(--sp-lg) 0 0; }
.measure > figure.painting img { width: 100%; height: auto; display: block; }

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  /* Above the sticky nav (z 1100) and skip-link (z 1200); at z 500 the nav
     painted over the overlay and swallowed the close button near the top
     edge (seen on Stefano's screen 2026-07-13). */
  z-index: 2000;
  background: rgba(51, 42, 38, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
}
.lightbox figure { max-width: 92vw; }
.lightbox img { max-width: 92vw; max-height: 82vh; margin: 0 auto; }
.lightbox figcaption {
  font-family: 'Cabin', sans-serif;
  font-size: 0.85rem;
  color: #faf7f1;
  text-align: center;
  margin-top: var(--sp-md);
}
.lightbox-close {
  position: absolute;
  top: var(--sp-md);
  right: var(--sp-md);
  width: 44px; height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Cabin', sans-serif;
  font-size: 1.2rem;
  line-height: 1;
  background: transparent;
  border: 1px solid rgba(250, 247, 241, 0.5);
  color: #faf7f1;
  cursor: pointer;
}
.lightbox-close:hover,
.lightbox-close:focus-visible { border-color: #faf7f1; }

/* Paintings gallery: one uniform tile width for EVERY painting on the page -
   place groups, solo sections and the pairing alike (William, 2026-07-07:
   "all the images could be a little bit more uniform... the clicking upon
   them should make sense") - so the page reads as one collection and every
   click is a true enlargement, even for the smallest museum scans (410px). */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, 205px); gap: var(--sp-lg); }
@media (max-width: 560px) { .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.gallery figure.painting { margin: 0; }
/* A section holding a single painting: drop the columns and give the lone
   figure a wider measure instead of leaving two empty columns. */
/* Solo sections take the same uniform tile - no exceptions. */
.gallery.solo figure.painting { max-width: none; }
/* Two-eyes pairing: the same place seen by each artist, side by side.
   Bottom-aligned so a portrait oil and a landscape watercolour meet on a
   common baseline instead of leaving a void under the shorter figure. */
.pairing { display: grid; grid-template-columns: 205px 205px; gap: var(--sp-lg); max-width: none; margin: var(--sp-lg) 0 var(--sp-xl); align-items: end; }
@media (max-width: 560px) { .pairing { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pairing figure.painting { margin: 0; }
.pairing figure.painting img { width: 100%; height: auto; display: block; }


/* Horizontal dynamic timeline (Journey page) */
.timeline {
  display: flex;
  gap: var(--sp-lg);
  overflow-x: auto;
  margin-top: var(--sp-lg);
  padding-bottom: var(--sp-md);
}
/* Snap is deferred until the visitor first scrolls the strip, so the
   timeline always starts at Croydon rather than part-snapped. */
.timeline.snap { scroll-snap-type: x proximity; }
.station-h {
  position: relative;
  flex: 0 0 auto;
  width: 240px;
  padding-top: var(--sp-lg);
  scroll-snap-align: start;
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.station-h.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .station-h { opacity: 1; transform: none; transition: none; }
}
.station-h::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--paper);
  border: 3px solid var(--accent);
}
.station-h::after {
  content: "";
  position: absolute;
  top: 8px;
  left: 26px;
  right: calc(-1 * var(--sp-lg));
  border-top: 2px dotted var(--accent);
}
.station-h:last-child::after { display: none; }
.station-h .place {
  font-family: 'Cabin', sans-serif;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.station-h .date {
  font-family: 'Cabin', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-top: 2px;
}
.station-h p { font-size: 0.95rem; line-height: 1.55; color: var(--muted); margin-top: var(--sp-xs); }
.station-h { cursor: pointer; }
.station-h:hover .place { color: var(--accent); }
/* "You are here": the card the map is currently pointing at fills its node
   and warms its label, without shifting any layout. */
.station-h.active .place { color: var(--accent); }
.station-h.active::before { background: var(--accent); }

/* Faint scroll cues: edge-fades and arrows that surface only when there is
   more of the journey to reach in that direction. */
.timeline-wrap { position: relative; }
.timeline-wrap::before,
.timeline-wrap::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 56px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 2;
}
.timeline-wrap::before { left: 0; background: linear-gradient(to right, var(--paper) 30%, transparent); }
.timeline-wrap::after { right: 0; background: linear-gradient(to left, var(--paper) 30%, transparent); }
.timeline-wrap.can-prev::before,
.timeline-wrap.can-next::after { opacity: 1; }
.tl-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: var(--paper);
  color: var(--muted);
  cursor: pointer;
  opacity: 0.25;
  pointer-events: none;
  transition: opacity 0.4s ease, color 0.2s ease, border-color 0.2s ease;
}
.tl-prev { left: 2px; }
.tl-next { right: 2px; }
/* Both paddles stay put while the strip overflows; the unavailable direction
   dims rather than vanishes, so nothing pops in and out as the visitor moves. */
.timeline-wrap.has-overflow .tl-arrow { display: flex; }
.timeline-wrap.can-prev .tl-prev,
.timeline-wrap.can-next .tl-next { opacity: 0.9; pointer-events: auto; }
.tl-arrow:hover { color: var(--accent); border-color: var(--accent); opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .timeline-wrap::before, .timeline-wrap::after, .tl-arrow { transition: none; }
}

/* Itinerary thread (vertical variant) */
.thread { position: relative; max-width: 34rem; margin-top: var(--sp-lg); }
.thread::before {
  content: "";
  position: absolute;
  left: 6px; top: 6px; bottom: 6px;
  border-left: 2px dotted var(--accent);
}
.station { position: relative; padding: 0 0 var(--sp-lg) var(--sp-lg); }
.station:last-child { padding-bottom: 0; }
.station::before {
  content: "";
  position: absolute;
  left: 0; top: 5px;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--paper);
  border: 3px solid var(--accent);
}
.station .place {
  font-family: 'Cabin', sans-serif;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.station p { font-size: 0.95rem; line-height: 1.55; color: var(--muted); margin-top: var(--sp-xs); }

.map-controls { display: flex; flex-wrap: wrap; gap: var(--sp-sm); margin-top: var(--sp-lg); }
.map-controls .btn { white-space: nowrap; }
.btn-sm { padding: var(--sp-xs) var(--sp-md); font-size: 0.78rem; }

/* Journey map */
#map {
  position: relative;
  z-index: 0;
  isolation: isolate;
  height: 560px;
  background: var(--paper);
  border: 1px solid var(--rule);
  margin-top: var(--sp-md);
}
#map .leaflet-tile-pane {
  filter: sepia(0.5) saturate(0.55) contrast(0.92) brightness(1.03);
}
/* Leaflet defaults brought onto the system: square corners, quiet attribution */
#map .leaflet-bar,
#map .leaflet-bar a,
#map .leaflet-bar a:first-child,
#map .leaflet-bar a:last-child { border-radius: 0; }
#map .leaflet-control-attribution,
#map .leaflet-control-attribution a { color: var(--muted); }
.leaflet-tooltip.station-tip {
  border-radius: 0;
  border: 1px solid var(--rule);
  font-family: 'Cabin', sans-serif;
  padding: var(--sp-sm);
  /* Cap the tip's overall size so even the longest caption (Baalbek) stays
     short enough to fit above or below any marker without spilling past the
     map's top or bottom edge, at any zoom (William, 2026-07-13). */
  max-width: 210px;
}
.station-tip .tip-place {
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.station-tip .tip-place span { color: #8e3b2f; font-weight: 500; margin-left: 6px; }
/* Keep illustrated tips compact so they fit above or below a marker without
   overflowing the map's top or bottom edge (paired with placeTip's two-sided
   room check). */
/* Fixed thumbnail height (cover-cropped) so a tall portrait plate like Baalbek
   can't make the tip taller than the space beside a marker - the real cause of
   the clipping. Uniform peek across every station. */
.station-tip img { width: 172px; height: 104px; object-fit: cover; object-position: center; margin-top: 6px; }
.station-tip .tip-caption { font-size: 0.7rem; color: #75655d; margin-top: 4px; max-width: 194px; white-space: normal; }

/* Team: exactly four people, so fix the column count rather than letting
   auto-fit wrap to an unbalanced 3+1 on wide screens (on a large viewport the
   6vw hero padding hits its 96px cap and narrows the content column, so
   auto-fit dropped to three columns - seen on Stefano's screen 2026-07-13).
   Four across on desktop, 2x2 on tablet, single column on phones. */
.team { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-lg); }
@media (max-width: 1040px) { .team { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .team { grid-template-columns: 1fr; } }
.person { border-top: 2px solid var(--ink); padding-top: var(--sp-md); }
.person h3 { font-size: 1.3rem; margin-bottom: var(--sp-xs); }
/* A linked name keeps the ink of its unlinked neighbours, with a quiet
   stone underline as the affordance; hover deepens both to accent. */
.person h3 a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--stone);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.person h3 a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}
.person .role {
  font-family: 'Cabin', sans-serif;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}

.person .affil {
  font-family: 'Source Serif 4', serif;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--muted);
  margin-top: var(--sp-xs);
}

/* Contact form */
.contact-form { display: grid; gap: var(--sp-md); }
.contact-form label { display: block; }
.form-label {
  display: block;
  font-family: 'Cabin', sans-serif;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-xs);
}
.contact-form input, .contact-form textarea {
  width: 100%;
  font-family: 'Source Serif 4', serif;
  font-size: 1rem;
  padding: var(--sp-sm) var(--sp-md);
  /* muted, not stone: stone on paper is 2.24:1, under the WCAG 3:1 non-text minimum */
  border: 1px solid var(--muted);
  background: var(--paper);
  color: var(--ink);
  outline: none;
  resize: vertical;
}
.contact-form input:focus, .contact-form textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}
.form-note {
  font-family: 'Cabin', sans-serif;
  font-size: 0.8rem;
  color: var(--muted);
}

/* Footer */
footer {
  border-top: 3px solid var(--ink);
  padding: var(--sp-lg) 0 var(--sp-xl);
  margin-top: var(--sp-xl);
}
footer p {
  font-family: 'Cabin', sans-serif;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
  max-width: 42rem;
}
footer p + p { margin-top: var(--sp-sm); }
.footer-logos {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-xl);
  margin-bottom: var(--sp-lg);
}
.footer-logos a { display: inline-flex; }
.footer-logos img {
  height: 44px;
  width: auto;
  filter: brightness(0);
  opacity: 0.58;
  transition: opacity 0.2s ease;
}
.footer-logos a:hover img,
.footer-logos a:focus-visible img { opacity: 1; }
