/* Margin: sidgore.com, option 1. The forest band is the spine of every page. */

:root {
  --paper: #f4f2e8;
  --paper-bright: #fbfaf6;
  --paper-sunken: #eae8db;
  --ink: #171912;
  --ink-700: #42433a;
  --ink-500: #5a5a4f;
  --ink-400: #6b6b5e;
  --ink-200: #b0ad9e;
  --ink-100: #d5d2c4;
  --forest: #005725;
  --forest-800: #01451b;
  --on-forest: #fbfaf6;
  --on-forest-muted: #d7ebda;
  --on-forest-faint: #acc1af;
  --green-action: #1b763a;
  --kelly-200: #b4efbf;
  --rule-margin: #c14545;

  /* Day mode after Chapbook: one forest ink in two densities on warm paper. */
  --bg: var(--paper);
  --bg-print: #ebe8da;
  --fg: #003011;
  --fg-muted: #005725;
  --fg-faint: #2f6b47;
  --border: rgb(0 87 37 / 18%);
  --border-strong: rgb(0 87 37 / 34%);
  --link: #005725;
  --ruled: rgb(0 87 37 / 11%);
  --rule-margin-opacity: 0.5;
  --print-shadow: 0 1px 2px rgb(0 48 17 / 6%), 0 10px 28px -14px rgb(0 48 17 / 22%);
  --mark-ground: var(--forest);
  --map-ink: #005725;

  --band: 232px;
  --gutter: 72px;
  --measure: 640px;
  --font: "Newsreader", "Iowan Old Style", Georgia, "Times New Roman", serif;
  /* Motion: two curves and four durations, used by everything that moves.
     Transform and opacity only (colour on hover and focus is the one
     exception, as feedback). Nothing linear. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);    /* arrivals and feedback: quick start, long settle */
  --ease-move: cubic-bezier(0.45, 0, 0.15, 1);  /* one state to another: eases at both ends, so nothing kicks or stops dead */
  --t-feedback: 160ms;  /* hover and focus: colour, the nav underline */
  --t-change: 280ms;    /* a state change: a theme lit, a pip, a button's dot */
  --t-move: 480ms;      /* something moving between places: the year roll, the toggle's rings */
  --t-enter: 640ms;     /* an entrance: the page settling, the print crossfade */
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncA type='linear' slope='0.05'/></feComponentTransfer></filter><rect width='240' height='240' filter='url(%23g)'/></svg>");
  color-scheme: light;
}

:root[data-mode="dark"] {
  --bg: #191c16;
  --bg-print: #252820;
  --fg: var(--paper-bright);
  --fg-muted: #b9beb2;
  --fg-faint: #9aa092;
  --border: rgb(255 255 255 / 12%);
  --border-strong: rgb(255 255 255 / 22%);
  --link: var(--kelly-200);
  --ruled: rgb(255 255 255 / 6%);
  --rule-margin-opacity: 0.45;
  --print-shadow: 0 1px 2px rgb(0 0 0 / 30%), 0 10px 28px -14px rgb(0 0 0 / 60%);
  --map-ink: #b9beb2;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { background: var(--bg); }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-optical-sizing: auto;
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  position: relative;
  min-height: 100vh;
  overflow-x: hidden;
}
body::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  background-size: 240px 240px;
  pointer-events: none;
  z-index: 0;
}

a { color: inherit; text-decoration-color: var(--border-strong); text-underline-offset: 0.16em; text-decoration-thickness: 1px; transition: color var(--t-feedback) var(--ease-out), text-decoration-color var(--t-feedback) var(--ease-out); }
a:hover { color: var(--link); text-decoration-color: currentColor; }
/* Hover and focus feedback on the spans that carry a link's colour. */
.mode, .entries .t, .cities .t, .beside-title, .theme-name { transition: color var(--t-feedback) var(--ease-out); }
:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--kelly-200); color: var(--ink); }
img { max-width: 100%; height: auto; display: block; }

/* ---------- the band ---------- */
.band {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--band);
  background: linear-gradient(180deg, var(--forest) 0%, var(--forest-800) 100%);
  color: var(--on-forest);
  display: flex;
  flex-direction: column;
  z-index: 1;
}
.band::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  background-size: 240px 240px;
  pointer-events: none;
}
.band > * { position: relative; z-index: 1; }
.portrait { display: block; aspect-ratio: 1; overflow: hidden; }
.portrait img { width: 100%; height: 100%; object-fit: cover; }
.band-body { padding: 26px 28px 0; display: flex; flex-direction: column; flex: 1; }
.name { margin: 0 0 14px; font-size: 24px; font-weight: 500; line-height: 1.2; letter-spacing: -0.005em; }
.name a { text-decoration: none; color: var(--on-forest); }
.nav { display: flex; flex-direction: column; }
.nav a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-size: 18px;
  color: var(--on-forest-muted);
  text-decoration: none;
  width: fit-content;
  position: relative;
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 9px; height: 1px;
  background: var(--on-forest);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--t-change) var(--ease-out);
}
.nav a:hover { color: var(--on-forest); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--on-forest); }
/* The orbit object: a box of 140 by 90 holding the still SVG (the page
   without a script) and, once the script runs, the canvas that turns. */
[data-orb] { display: block; position: relative; aspect-ratio: 140 / 124; }
[data-orb] .orb-still, [data-orb] .orb-live { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
[data-orb].is-live .orb-still { display: none; }
.orb-still path, .orb-still circle { vector-effect: non-scaling-stroke; stroke-width: var(--orb-stroke, 1.25); }
/* The mark is the one moving object on the site: 108px, a 1.25px stroke (a
   lighter stroke breaks up at 1x), muted ink at 0.9 so it sits in the band
   rather than on it. */
.mark { width: 108px; margin: auto 0 22px -6px; color: var(--on-forest-muted); opacity: 0.9; }
.mode {
  margin: 0 28px 24px;
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px;
  padding: 0;
  background: none; border: 0;
  color: var(--on-forest-muted);
  font: inherit; font-size: 16px;
  cursor: pointer;
  width: fit-content;
}
.mode:hover { color: var(--on-forest); }
.rings { width: 22px; height: 22px; flex: none; }
/* Each press of the toggle adds a ring from the centre and lets the outermost
   go; the finished frame is the resting glyph again. (No hover motion: the
   rings are concentric circles, so a turn would show nothing.) */
.ring { transform-box: view-box; transform-origin: 20px 20px; }
.ring-0 { opacity: 0; }
.mode.is-growing .ring-0 { animation: grow-0 var(--t-move) var(--ease-move) both; }
.mode.is-growing .ring-1 { animation: grow-1 var(--t-move) var(--ease-move) both; }
.mode.is-growing .ring-2 { animation: grow-2 var(--t-move) var(--ease-move) both; }
.mode.is-growing .ring-3 { animation: grow-3 var(--t-move) var(--ease-move) both; }
@keyframes grow-0 { from { transform: scale(1); opacity: 0; } 35% { opacity: 1; } to { transform: scale(2.5); opacity: 1; } }
@keyframes grow-1 { from { transform: scale(1); } to { transform: scale(2.375); } }
@keyframes grow-2 { from { transform: scale(1); } to { transform: scale(1.579); } }
@keyframes grow-3 { from { transform: scale(1); opacity: 1; } to { transform: scale(1.32); opacity: 0; } }

/* ---------- the page ---------- */
.page {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  margin-left: var(--band);
  padding: 96px 48px 120px var(--gutter);
  max-width: calc(var(--gutter) + var(--measure) + 48px);
}
/* The red rule belongs to the paper: it lives inside the page, so on a phone
   it starts below the forest strip instead of running through it. */
.margin-rule {
  position: absolute;
  top: 0; bottom: 0;
  left: 34px;
  width: 1px;
  background: var(--rule-margin);
  opacity: var(--rule-margin-opacity);
  transform-origin: top center;
  animation: draw calc(var(--t-enter) * 1.5) var(--ease-move) 120ms both;
  z-index: 2;
  pointer-events: none;
}
@keyframes draw { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes settle { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

h1, h2, h3 { font-weight: 500; letter-spacing: -0.012em; margin: 0; }
h1 { font-size: clamp(34px, 2.2vw + 20px, 48px); line-height: 1.12; }
.page-head { margin-bottom: 56px; animation: settle var(--t-enter) var(--ease-out) both; }
.lede { font-size: 19px; color: var(--fg-muted); margin: 14px 0 0; max-width: 34em; }

/* home: the title page. The tagline is the title (the band carries the
   name); his own sentences follow at a reading measure, left-set like every
   other page, and the orbit object takes the rest of the paper. */
.is-home .page { max-width: none; padding-top: 80px; }
.title-page { animation: settle var(--t-enter) var(--ease-out) both; }
.title-text { max-width: var(--measure); }
.title-head { margin-bottom: 28px; }
.title-page h1 { font-size: clamp(38px, 2.4vw + 16px, 58px); font-weight: 400; letter-spacing: -0.015em; line-height: 1.1; max-width: 12em; text-wrap: balance; }
.intro { font-size: 22px; line-height: 1.45; max-width: 28em; margin: 0 0 36px; text-wrap: pretty; }
/* The home figure slot: empty for now. A still graphic goes here next; it
   should be drawn at --home-figure-size, centred in the slot. Under 1100px
   the slot is hidden and the words run in one column. */
.home-figure { display: none; }
/* From 1100px the title page is two columns: the words at a reading measure
   on the left, the figure slot holding the rest of the paper on the right
   and staying in view while the words scroll. The text column gives a
   little below 1440 so the slot keeps a real size; the gap and the slot
   grow with the screen, so at 2000 wide the paper is still held. */
@media (min-width: 1100px) {
  .title-page {
    display: grid;
    grid-template-columns: minmax(0, clamp(520px, 42vw, 640px)) minmax(220px, 1fr);
    grid-template-rows: auto 1fr;
    column-gap: clamp(40px, 5vw, 120px);
    align-items: start;
    max-width: 1560px;
  }
  .title-text { max-width: none; grid-column: 1; }
  .home-figure {
    --home-figure-size: min(100%, clamp(300px, 30vw, 640px));
    grid-column: 2; grid-row: 1 / 3;
    position: sticky; top: 0;
    align-self: start;
    margin-top: -80px; /* the page's own top padding, so the slot is pinned from the first scroll */
    height: 100vh; min-height: 560px;
    display: grid; place-items: center;
    padding-bottom: 6vh;
  }
  .home-figure > * { width: var(--home-figure-size); }
}
/* The open field: the home figure is part of the paper. The SVG (built in
   build.mjs) sits in the sticky slot but is drawn out of it, to the paper's
   right edge (100vw less the band, the gutter, the text column and the gap)
   and 120px past the slot's foot (the page's bottom padding), so the mesh
   runs off the paper's edges at every scroll. The page clips at its own
   edges (overflow: clip keeps the slot sticky), so nothing can overflow.
   The drawing fades toward the horizon by depth; the fade toward the words
   is a mask here, in the slot's own coordinates, so it holds at every
   width. Light: forest ink on the paper, faint enough to read as
   atmosphere. Dark: kelly lines with a soft glow beneath them, after the
   cover. The pin and its contours use the margin-rule red. Nothing moves. */
.field { display: none; }
@media (min-width: 1100px) {
  .is-home .page { overflow: clip; }
  .home-figure > .field {
    display: block;
    position: absolute; top: 0; left: 0;
    /* to the paper's edge: past the grid's end on a wide screen, and the
       page's 48px side padding when the grid fills the page (1100 to 1150) */
    width: max(calc(100% + 48px), calc(100vw - var(--band) - var(--gutter) - clamp(520px, 42vw, 640px) - clamp(40px, 5vw, 120px)));
    height: calc(100% + 120px);
    pointer-events: none;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 42%);
    mask-image: linear-gradient(90deg, transparent 0, #000 42%);
  }
}
.field {
  --field-ink: var(--forest);
  --field-ink-a: 0.32;
  --field-trail: var(--fg-muted);
  --field-trail-a: 0.46;
  --field-dust-a: 0.32;
  --field-glow-a: 0;
  --field-pin-halo-a: 0;
}
:root[data-mode="dark"] .field {
  --field-ink: var(--kelly-200);
  --field-ink-a: 0.46;
  --field-trail: var(--on-forest-muted);
  --field-trail-a: 0.75;
  --field-dust-a: 0.65;
  --field-glow-a: 0.14;
  --field-pin-halo-a: 0.2;
}
.field .mesh-ink { fill: none; stroke: var(--field-ink); stroke-width: 0.8; stroke-linejoin: round; stroke-linecap: round; opacity: var(--field-ink-a); }
.field .mesh-glow { display: none; fill: none; stroke: var(--kelly-200); stroke-width: 3.2; stroke-linejoin: round; stroke-linecap: round; opacity: var(--field-glow-a); }
:root[data-mode="dark"] .field .mesh-glow { display: inline; }
.field .dust { fill: var(--field-ink); opacity: var(--field-dust-a); }
.field .trail-halo { fill: none; stroke: var(--bg); stroke-width: 7; stroke-linejoin: round; stroke-linecap: round; }
.field .trail { fill: none; stroke: var(--field-trail); stroke-width: 1.3; stroke-linejoin: round; stroke-linecap: round; opacity: var(--field-trail-a); }
.field .pin .ring { fill: none; stroke: var(--rule-margin); stroke-width: 0.9; }
.field .pin .stalk { stroke: var(--rule-margin); stroke-width: 1.2; opacity: 0.8; }
.field .pin .foot { fill: var(--rule-margin); opacity: 0.8; }
.field .pin .halo { fill: var(--rule-margin); opacity: var(--field-pin-halo-a); }
.field .pin .head { fill: var(--rule-margin); }

/* The film quote, set as a quotation: left, with the rule of every
   blockquote on the site, as on the original site. */
.epigraph { margin: 0 0 40px; padding: 4px 0 4px 26px; border-left: 2px solid var(--forest); max-width: 30em; text-align: left; font-style: italic; font-size: 20px; line-height: 1.5; }
.epigraph p { margin: 0; }
.epigraph footer { margin-top: 12px; }
.epigraph cite { font-style: normal; font-size: 16px; color: var(--fg-muted); }
.preface { text-align: left; animation: settle var(--t-enter) var(--ease-out) 80ms both; }
.preface p { font-size: 19px; line-height: 1.65; margin: 0 0 24px; }
.onward {
  margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--border);
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; text-align: left;
  animation: settle var(--t-enter) var(--ease-out) 160ms both;
}
.onward a { display: flex; flex-direction: column; min-height: 44px; text-decoration: none; font-size: 19px; line-height: 1.3; }
.onward small { font-size: 16px; font-style: italic; color: var(--fg-muted); margin-bottom: 4px; }
.onward a:hover { color: var(--link); }
.links { display: flex; gap: 24px; margin: 40px 0 0; justify-content: flex-start; font-size: 17px; }
.links a { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }
.wander-line { margin: 10px 0 0; font-size: 18px; }
.wander-line a { min-height: 44px; display: inline-flex; align-items: center; }
.ago { color: var(--fg-faint); }

blockquote {
  margin: 0 0 32px;
  padding: 4px 0 4px 26px;
  border-left: 2px solid var(--forest);
  font-size: 19px;
  line-height: 1.6;
}
:root[data-mode="dark"] blockquote { border-left-color: var(--on-forest-faint); }
blockquote p { margin: 0 0 10px; }
blockquote footer { margin-top: 12px; }
blockquote cite { font-style: italic; color: var(--fg-muted); font-size: 17px; }

/* entry lists */
.entries { list-style: none; margin: 0; padding: 0; }
.entries li { border-top: 1px solid var(--border); }
.entries li:last-child { border-bottom: 1px solid var(--border); }
.entries a {
  display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
  min-height: 56px; padding: 14px 0;
  text-decoration: none;
}
.entries .t { font-size: 22px; line-height: 1.25; }
.entries time { font-size: 16px; color: var(--fg-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.entries a:hover .t { color: var(--link); }

/* journal years: a heading in the flow on the paper (the fallback without
   the script, and the strip on a phone); with the script on a desktop the
   year moves to its slot in the band and the headings step aside */
.year { position: relative; padding: 0 0 56px; }
.year + .year { padding-top: 8px; }
.year-mark { margin: 0 0 14px; font-size: 28px; line-height: 1.2; font-weight: 400; color: var(--fg-muted); font-variant-numeric: lining-nums tabular-nums; }
html.has-band-year .year-mark { display: none; }
html.has-band-year .year + .year { padding-top: 24px; }

/* The year slot in the band: one fixed place under the nav, clear of the
   name, the nav, the mark and the toggle at any height from 700px up. The
   outgoing year rolls out while the next rolls in, clipped to the slot. */
.band-year { position: relative; height: 64px; margin: 24px 0 0 -2px; overflow: hidden; font-weight: 400; }
.band-year span {
  position: absolute; left: 0; top: 0;
  font-size: 56px; line-height: 64px; letter-spacing: -0.02em;
  color: var(--on-forest); opacity: 0.92; white-space: nowrap;
  font-variant-numeric: lining-nums tabular-nums;
}
/* Out and in share one duration and curve, so the two opacities always sum
   to the resting 0.92 and the slot never dims mid-roll. */
.band-year .is-out-up { animation: year-out-up var(--t-move) var(--ease-move) both; }
.band-year .is-in-up { animation: year-in-up var(--t-move) var(--ease-move) both; }
.band-year .is-out-down { animation: year-out-down var(--t-move) var(--ease-move) both; }
.band-year .is-in-down { animation: year-in-down var(--t-move) var(--ease-move) both; }
@keyframes year-out-up { from { transform: none; opacity: 0.92; } to { transform: translateY(-56%); opacity: 0; } }
@keyframes year-in-up { from { transform: translateY(56%); opacity: 0; } to { transform: none; opacity: 0.92; } }
@keyframes year-out-down { from { transform: none; opacity: 0.92; } to { transform: translateY(56%); opacity: 0; } }
@keyframes year-in-down { from { transform: translateY(-56%); opacity: 0; } to { transform: none; opacity: 0.92; } }
.post .when { margin: 0 0 14px; font-size: 17px; color: var(--fg-faint); }

/* journal rows: title and date in one line; the thumbnail only shows where
   the print panel has no room (under 1100px) */
.row-text { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; flex: 1; min-width: 0; }
.entries .thumb { display: none; }
.entries li[hidden], .year[hidden] { display: none; }

/* ---------- the journal: list, map and the print beside the line ---------- */
.is-journal .page { max-width: calc(var(--gutter) + 600px + 56px + 380px + 48px); }
.journal-body { display: grid; grid-template-columns: minmax(0, 600px) 380px; column-gap: 56px; align-items: start; }
.journal-body .column { min-width: 0; }
.themes { display: grid; grid-template-columns: minmax(0, 600px) 380px; column-gap: 56px; align-items: start; margin: 0 0 64px; animation: settle var(--t-enter) var(--ease-out) 80ms both; }
.map-wrap { position: relative; grid-column: 2; grid-row: 1; }
.theme-list { grid-column: 1; grid-row: 1; }
.map .axis { stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.55; }
.map { display: block; width: 380px; max-width: 100%; height: auto; color: var(--map-ink); overflow: visible; font-family: var(--font); }
.map-ground { opacity: 0.55; }
.map .ring-year { stroke-width: 1; vector-effect: non-scaling-stroke; }
.map .spoke { stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.55; }
.map .heart { color: var(--fg); }
.map .wedge { fill: currentColor; fill-opacity: 0; cursor: pointer; transition: fill-opacity var(--t-change) var(--ease-out); }
.map .sector:hover .wedge { fill-opacity: 0.06; }
.map .sector.is-on .wedge { fill-opacity: 0.09; }
.map .sector-label { font-size: 15px; fill: var(--fg-muted); cursor: pointer; transition: fill var(--t-feedback) var(--ease-out); }
.map .sector:hover .sector-label, .map .sector.is-on .sector-label { fill: var(--fg); }
.map .year-label { font-size: 14px; fill: var(--fg-faint); font-variant-numeric: tabular-nums; paint-order: stroke; stroke: var(--bg); stroke-width: 6px; stroke-linejoin: round; }
.map .dot { outline: none; }
.map .hit { fill: transparent; pointer-events: all; }
.map .pip { fill: var(--fg); stroke: var(--bg); stroke-width: 1; transform-box: fill-box; transform-origin: center; transition: transform var(--t-change) var(--ease-out), opacity var(--t-change) var(--ease-out), fill var(--t-feedback) var(--ease-out); }
.map .dot:hover .pip, .map .dot:focus-visible .pip { transform: scale(1.75); fill: var(--link); }
.map .dot:focus-visible .hit { stroke: var(--link); stroke-width: 1.5; }
.map .dot.is-dim .pip { opacity: 0.18; }
.map .dot.is-lit .pip { fill: var(--link); transform: scale(1.25); }
.map-caption { margin: 10px 0 0; min-height: 28px; font-size: 16px; color: var(--fg-muted); font-style: italic; text-align: center; }
.theme-buttons { list-style: none; margin: 0; padding: 0; }
.theme-list { padding-top: 6px; }
button.theme {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; border-top: 1px solid var(--border);
  padding: 10px 0 10px 14px; min-height: 44px;
  font: inherit; color: inherit; cursor: pointer; position: relative;
}
.theme-buttons li:last-child button.theme { border-bottom: 1px solid var(--border); }
button.theme::before { content: ""; position: absolute; left: 0; top: 14px; width: 6px; height: 6px; border-radius: 50%; background: var(--fg); opacity: 0; transform: scale(0.5); transition: opacity var(--t-change) var(--ease-out), transform var(--t-change) var(--ease-out); }
button.theme[aria-pressed="true"]::before, button.theme:hover::before { opacity: 1; transform: none; }
.theme-name { display: block; font-size: 19px; line-height: 1.3; }
.theme-count { font-size: 15px; color: var(--fg-faint); margin-left: 8px; font-variant-numeric: tabular-nums; }
.theme-line { display: block; font-size: 15px; line-height: 1.4; color: var(--fg-faint); margin-top: 2px; }
button.theme:hover .theme-name { color: var(--link); }
.theme-all { margin: 8px 0 0; }
button.theme-every { border-top: 0; }
button.theme-every[aria-pressed="true"] .theme-name { color: var(--fg-muted); }

/* the print beside the line: one frame, two layers that crossfade */
.beside { position: sticky; top: calc(45vh - 230px); align-self: start; padding-top: 18px; }
.beside-link { display: block; text-decoration: none; color: inherit; }
.beside-frame {
  display: block; position: relative; aspect-ratio: 1; width: 100%;
  padding: 10px; background: var(--bg-print); border: 1px solid var(--border); box-shadow: var(--print-shadow);
  overflow: hidden;
}
/* The two prints crossfade on one duration and curve, so their opacities
   always sum to 1 and the frame never goes pale between photos. */
.beside-print { position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); object-fit: cover; opacity: 0; transition: opacity var(--t-enter) var(--ease-move); }
.beside.is-tall .beside-print.is-shown { object-fit: cover; object-position: center 30%; }
.beside.is-wide .beside-print.is-shown { object-fit: contain; }
.beside-print.is-shown { opacity: 1; }
.beside-standin {
  position: absolute; inset: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: 24px; text-align: center; color: var(--fg-muted);
  opacity: 0; transition: opacity var(--t-enter) var(--ease-move);
}
.beside-standin.is-shown { opacity: 1; }
.beside-standin .rings { width: 34px; height: 34px; opacity: 0.8; }
.standin-title { font-size: 20px; line-height: 1.3; font-style: italic; }
.beside-caption { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; margin-top: 12px; font-size: 16px; color: var(--fg-faint); }
.beside-title { color: var(--fg-muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.beside-when { white-space: nowrap; }
.beside.is-standin .beside-caption { visibility: hidden; }
.beside-link:hover .beside-title { color: var(--link); }

@media (max-width: 1099.98px) {
  .is-journal .page { max-width: calc(var(--gutter) + var(--measure) + 48px); }
  .journal-body { display: block; }
  .themes { display: flex; flex-direction: column; margin-bottom: 48px; }
  .beside { display: none; }
  .map-wrap { margin-bottom: 24px; }
  .entries a { align-items: center; }
  .entries .thumb { display: block; flex: none; width: 56px; height: 56px; object-fit: cover; border: 1px solid var(--border); background: var(--bg-print); padding: 3px; }
  .entries .thumb-none { display: flex; align-items: center; justify-content: center; color: var(--fg-faint); opacity: 0.7; }
  .entries .thumb-none .rings { width: 22px; height: 22px; }
}

/* cities */
.travel-lede { margin: 0 0 22px; font-size: 18px; }
.travel-lede a { min-height: 44px; display: inline-flex; align-items: center; }
.cities { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px 20px; }
.cities a { display: block; text-decoration: none; }
.cities img { aspect-ratio: 1; object-fit: cover; width: 100%; border: 1px solid var(--border); background: var(--bg-print); padding: 6px; box-shadow: var(--print-shadow); }
.cities .t { display: block; margin-top: 10px; font-size: 20px; line-height: 1.25; }
.cities .c { display: block; font-size: 15px; color: var(--fg-faint); margin-top: 2px; }
.cities a:hover .t { color: var(--link); }
.cities.large { gap: 32px 24px; }
.cities.large .t { font-size: 22px; }
.city .country { color: var(--fg-muted); font-weight: 400; }
.visit { position: relative; padding-top: 8px; margin-bottom: 72px; }
.visit .when { margin: 0 0 22px; font-size: 20px; color: var(--fg-muted); }

/* post */
.post-head { margin-bottom: 36px; animation: settle var(--t-enter) var(--ease-out) both; }
.post-head h1 { max-width: 16ch; }
.city-link { margin: 14px 0 0; font-size: 17px; }
.city-link a { min-height: 44px; display: inline-flex; align-items: center; }
.body { animation: settle var(--t-enter) var(--ease-out) 80ms both; }
.print {
  margin: 0 0 36px;
  padding: 10px;
  background: var(--bg-print);
  border: 1px solid var(--border);
  box-shadow: var(--print-shadow);
  width: fit-content;
  max-width: 100%;
}
.print.is-portrait { max-width: min(100%, 460px); }
.print img { width: 100%; }
.print figcaption { font-size: 15px; color: var(--fg-faint); padding: 10px 2px 0; line-height: 1.4; }
/* One rule per verse line, under the whole line. A line that wraps keeps a
   single rule and hangs its continuation, so it still reads as one line. */
.verse .line {
  margin: 0 0 7px;
  font-size: 20px;
  line-height: 32px;
  padding-left: 1.4em;
  text-indent: -1.4em;
  border-bottom: 1px solid var(--ruled);
}
.verse .lines { margin-bottom: 8px; }
.prose .line { margin: 0 0 1.1em; font-size: 18px; line-height: 1.65; }
.body h2 { font-size: 24px; line-height: 1.3; margin: 1.4em 0 0.6em; }
.prints { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin: 0 0 36px; align-items: start; }
.prints .print { margin: 0; width: auto; max-width: none; }
.prints .print:first-child:not(.is-portrait) { grid-column: 1 / -1; }
.prints .print:not(:first-child):not(.is-portrait) img { aspect-ratio: 4 / 3; object-fit: cover; }
.prints .print.is-portrait img { aspect-ratio: 3 / 4; object-fit: cover; }
.body .print + .print { margin-top: 0; }
.turn {
  margin-top: 72px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  display: flex; justify-content: space-between; gap: 32px;
}
.turn a { display: flex; flex-direction: column; min-height: 44px; text-decoration: none; font-size: 19px; line-height: 1.3; max-width: 18em; }
.turn small { font-size: 15px; color: var(--fg-faint); margin-bottom: 4px; }
.turn .later { text-align: right; margin-left: auto; }
.turn a:hover { color: var(--link); }

/* ---------- phone: the band folds into a strip and leaves its edge ---------- */
@media (max-width: 899.98px) {
  :root { --band: 0px; --gutter: 24px; }
  body { font-size: 17px; }
  .band {
    position: relative;
    width: auto; bottom: auto;
    display: grid;
    grid-template-columns: 64px 1fr auto;
    grid-template-rows: 64px 44px;
    align-items: center;
  }
  .portrait { width: 64px; height: 64px; grid-row: 1; grid-column: 1; }
  .band-body { grid-row: 1 / span 2; grid-column: 2; padding: 0 0 0 16px; display: contents; }
  .name { grid-row: 1; grid-column: 2; margin: 0; padding-left: 16px; font-size: 20px; }
  .name a { display: inline-flex; align-items: center; min-height: 44px; }
  .nav { grid-row: 2; grid-column: 1 / -1; flex-direction: row; gap: 4px; padding: 0 10px 0 10px; border-top: 1px solid rgb(255 255 255 / 14%); }
  .nav a { padding: 0 10px; font-size: 17px; }
  .nav a::after { left: 10px; right: 10px; bottom: 7px; }
  .mark { display: none; }
  .mode { grid-row: 1; grid-column: 3; margin: 0 12px 0 0; min-width: 44px; justify-content: center; font-size: 15px; }
  .mode span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .mode .rings { width: 26px; height: 26px; }
  .spine, body::before {
    content: "";
    position: fixed; top: 0; bottom: 0; left: 0;
    width: 6px;
    background: var(--forest);
    z-index: 2;
  }
  .page { padding: 40px 20px 80px calc(6px + var(--gutter)); max-width: none; min-height: calc(100vh - 108px); }
  .margin-rule { left: 22px; }
  h1 { font-size: clamp(30px, 6vw + 10px, 40px); }
  .hero h1 { font-size: clamp(26px, 5vw + 8px, 32px); max-width: none; }
  .about p, blockquote { font-size: 18px; }
  .band-year { display: none; }
  html.has-band-year .year-mark { display: block; }
  .year-mark { position: sticky; top: 0; z-index: 3; margin: 0 0 8px -4px; padding: 8px 0 8px 4px; background: var(--bg); font-size: 22px; }
  .year + .year, html.has-band-year .year + .year { padding-top: 8px; }
  .entries .t { font-size: 20px; }
  .entries a { align-items: center; gap: 16px; }
  .row-text { flex-direction: column; align-items: flex-start; gap: 4px; }
  .is-home .page { padding-top: 40px; }
  .title-page h1 { font-size: clamp(32px, 7.5vw + 4px, 40px); max-width: none; }
  .intro { font-size: 20px; }
  .epigraph { font-size: 19px; }
  .preface p { font-size: 18px; }
  .onward { grid-template-columns: 1fr; gap: 14px; }
  .links { justify-content: flex-start; }
  .map { margin: 0 auto; }
  /* On touch screens the map is a picture; the theme buttons below it are the way in. */
  .themes { margin-bottom: 40px; }
  .cities { grid-template-columns: repeat(2, 1fr); gap: 20px 16px; }
  .cities .t, .cities.large .t { font-size: 18px; }
  .verse .line { font-size: 19px; }
  .prints { gap: 14px; }
  .turn { flex-direction: column; gap: 20px; }
  .turn .later { text-align: left; margin-left: 0; }
  .page-head { margin-bottom: 40px; }
}

@media (max-width: 899.98px) and (pointer: coarse) {
  .map .dot { pointer-events: none; }
}

/* Under 700px tall the band has no room for the mark as well as the year. */
@media (min-width: 900px) and (max-height: 699.98px) {
  .mark { display: none; }
}

@media (max-width: 359.98px) { .map text { display: none; } }

/* Reduced motion: every entrance and roll shows its finished state at once;
   the orbit mark holds its still pose (margin.js). Colour feedback on hover
   and focus stays, since it carries no movement. */
@media (prefers-reduced-motion: reduce) {
  .margin-rule, .page-head, .title-page, .preface, .onward, .themes, .post-head, .body, .mode.is-growing .ring, .band-year span { animation: none; }
  .nav a::after, .beside-print, .beside-standin, .map .pip, .map .wedge, button.theme::before { transition: none; }
}
