/* GENERATED from design/_fonts.css and design/_blog.css by
   scripts/css-from-mockup.py. Do not edit: change the mock-up and run
   `npm run design`. */

/* The app's fonts, self-hosted from public/fonts. Prepended to public/css/site.css
   by scripts/css-from-mockup.py. The mock-ups load the same faces from Google.
   Fraunces and Source Serif 4 are under the SIL Open Font License 1.1;
   see public/fonts/. */

/* Fraunces, normal, latin-ext */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/fraunces-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Fraunces, normal, latin */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/fraunces-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Source Serif 4, italic, latin-ext */
@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Source Serif 4, italic, latin */
@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Source Serif 4, normal, latin-ext */
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-normal-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Source Serif 4, normal, latin */
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-normal-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================================
   The blog's stylesheet, and the specification for how it looks.

   public/css/site.css is GENERATED from this file by scripts/css-from-mockup.py:
   everything above the RIG marker at the bottom, minus nothing. Never edit
   site.css; change this and run `npm run design`.

   Editorial and photo-led. The photographs are the colour on the page, so the
   chrome stays quiet: warm paper, dark ink, and one accent taken from the logo,
   its dark green by day and its sky blue by night, used on links, the active
   tab and the primary button and almost nothing else. Text never sits
   on a photograph.

   Every text token clears 7:1 on every ground token in both modes. The gate is
   design/_contrast.py, and tests/contrast.test.js in the app.
   ========================================================================== */

:root {
	--bg:          #f6f2ea;
	--bg-raised:   #fcfaf5;
	--bg-sunken:   #ede6da;

	--text:        #1c1915;
	--text-muted:  #4a433a;
	--accent:      #003028;
	--on-accent:   #fcfaf5;
	--danger:      #7d1f17;

	--pill-bg:     #e6ddcd;
	--pill-text:   #3a332b;

	--border:      #e0d7c7;
	--border-firm: #c4b8a2;

	/* The photo viewer is dark in both modes: a photograph reads best on black. */
	--viewer-bg:   #0d0c0b;
	--viewer-text: #f2ece3;

	--shadow:      0 1px 2px rgb(40 30 20 / .06), 0 8px 24px rgb(40 30 20 / .08);

	--font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
	--font-body:    "Source Serif 4", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
	--font-ui:      system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

	--measure:   42rem;   /* the reading column */
	--wide:      64rem;   /* photos in a story */
	--page:      72rem;   /* the header, the home grid, the footer */
	--gutter:    1rem;
	--radius:    .5rem;

	color-scheme: light;
}

:root.dark {
	--bg:          #171513;
	--bg-raised:   #211e1b;
	--bg-sunken:   #100e0d;

	--text:        #f2ece3;
	--text-muted:  #bfb5a8;
	--accent:      #87b1f0;
	--on-accent:   #00201b;
	--danger:      #f4a79d;

	--pill-bg:     #2e2924;
	--pill-text:   #d9cfc2;

	--border:      #2d2925;
	--border-firm: #4a443d;

	--shadow:      0 1px 2px rgb(0 0 0 / .3), 0 8px 24px rgb(0 0 0 / .3);

	color-scheme: dark;
}

@media (min-width: 40rem) {
	:root { --gutter: 1.5rem; }
}

/* ── Base ─────────────────────────────────────────────────────────────────── */

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

/* hidden means hidden, whatever display a class gives the element. */
[hidden] { display: none !important; }

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

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font: 400 1.0625rem/1.6 var(--font-body);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
}

main { flex: 1; }

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

a { color: var(--accent); text-underline-offset: .18em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

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

h1, h2, h3 {
	font-family: var(--font-display);
	font-weight: 600;
	font-optical-sizing: auto;
	line-height: 1.12;
	letter-spacing: -.01em;
	margin: 0;
	text-wrap: balance;
}

.visually-hidden {
	position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.icon { width: 1.25em; height: 1.25em; flex: none; }

/* Small sans labels: dates, places, counts, captions. Never below 14px. */
.meta {
	font: 500 .875rem/1.5 var(--font-ui);
	color: var(--text-muted);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .25rem .5rem;
}
.meta > * + *::before { content: "·"; margin-right: .5rem; }
.meta a { color: inherit; }

/* The trip a post belongs to, above its title. */
.kicker {
	font: 600 .8125rem/1.4 var(--font-ui);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--accent);
	text-decoration: none;
}
a.kicker:hover { text-decoration: underline; }

/* ── Header ───────────────────────────────────────────────────────────────── */

.site-header {
	display: flex;
	align-items: center;
	gap: .75rem;
	padding: .75rem var(--gutter);
	max-width: calc(var(--page) + 2 * var(--gutter));
	margin: 0 auto;
	width: 100%;
}

.brand {
	display: flex;
	align-items: center;
	gap: .6rem;
	color: var(--text);
	text-decoration: none;
	/* Not a line height of 1: the name clips for its ellipsis, and at 1 that
	   cuts the tails off the g's. */
	font: 600 1.25rem/1.35 var(--font-display);
	letter-spacing: -.01em;
	min-width: 0;
}
/* The logo, coloured by the theme: the file is a mask, and the colour is
   the ink's, so it is dark on paper and cream on charcoal. An absolute path,
   so it resolves the same from public/css/site.css and from the mock-ups,
   which are served with design/ as the root. */
.brand-mark {
	display: block;
	height: 1.9rem;
	aspect-ratio: 418 / 285;
	flex: none;
	background: var(--text);
	-webkit-mask: url("/icons/logo.svg") center / contain no-repeat;
	mask: url("/icons/logo.svg") center / contain no-repeat;
}
.brand-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The home page has the name as a nameplate, so the bar shows the mark alone. */
.is-home .brand-name { display: none; }
/* Below about 400px the name and the public links do not both fit; the mark
   carries it. The dashboard's bar has room for longer, down to about 350px. */
@media (max-width: 25.99rem) { body:not(.app) .brand-name { display: none; } }
@media (max-width: 21.99rem) { .brand-name { display: none; } }

.site-nav { margin-left: auto; display: flex; align-items: center; gap: .25rem; }

.nav-link {
	font: 600 .9375rem/1 var(--font-ui);
	color: var(--text);
	text-decoration: none;
	padding: .6rem .7rem;
	border-radius: 999px;
	white-space: nowrap;
}
.nav-link:hover { background: var(--bg-sunken); }
.nav-link[aria-current="page"] { color: var(--accent); }

.icon-btn {
	display: inline-grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 999px;
	border: 0;
	background: none;
	color: var(--text);
	cursor: pointer;
	flex: none;
}
.icon-btn:hover { background: var(--bg-sunken); }
.icon-btn .icon { width: 1.25rem; height: 1.25rem; }

/* The mode toggle shows the moon in light mode and the sun in dark. */
.mode-toggle .sun { display: none; }
.dark .mode-toggle .sun { display: block; }
.dark .mode-toggle .moon { display: none; }

/* On the home page the name is a nameplate, set large and centred. */
.nameplate {
	text-align: center;
	padding: 2.5rem var(--gutter) 2rem;
}
.nameplate h1 {
	font-size: clamp(2.5rem, 9vw, 5.25rem);
	font-weight: 600;
	letter-spacing: -.025em;
	line-height: 1;
}
.nameplate p {
	margin: .9rem auto 0;
	max-width: 32rem;
	font-style: italic;
	font-size: clamp(1.0625rem, 2.4vw, 1.25rem);
	color: var(--text-muted);
}

/* ── Buttons and fields ───────────────────────────────────────────────────── */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .5rem;
	font: 600 .9375rem/1 var(--font-ui);
	padding: .8rem 1.15rem;
	min-height: 2.75rem;
	border-radius: 999px;
	border: 1px solid var(--border-firm);
	background: var(--bg-raised);
	color: var(--text);
	text-decoration: none;
	cursor: pointer;
	white-space: nowrap;
}
.btn:hover { border-color: var(--text-muted); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-primary:hover { border-color: var(--accent); filter: brightness(1.08); }
.btn-quiet { border-color: transparent; background: none; }
.btn-quiet:hover { background: var(--bg-sunken); border-color: transparent; }
.btn-danger { color: var(--danger); }
.btn-block { width: 100%; }
.btn-small { min-height: 2.25rem; padding: .5rem .85rem; font-size: .875rem; }

.field { display: grid; gap: .4rem; align-content: start; }
.field + .field { margin-top: 1.1rem; }
.field label, .label {
	font: 600 .875rem/1.3 var(--font-ui);
	color: var(--text);
}
.field .hint { font: 400 .875rem/1.45 var(--font-ui); color: var(--text-muted); margin: 0; }

.input, .textarea, .select {
	width: 100%;
	font: 400 1rem/1.4 var(--font-ui);  /* 16px stops iOS zooming on focus */
	color: var(--text);
	background: var(--bg-raised);
	border: 1px solid var(--border-firm);
	border-radius: var(--radius);
	padding: .7rem .8rem;
	min-height: 2.75rem;
}
.textarea { min-height: 7rem; resize: vertical; line-height: 1.55; }
.input:focus, .textarea:focus, .select:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }

.check { display: flex; gap: .65rem; align-items: flex-start; font: 400 1rem/1.45 var(--font-ui); }
.check input { width: 1.25rem; height: 1.25rem; margin: .1rem 0 0; accent-color: var(--accent); flex: none; }

/* The honeypot on the comment form. Hidden from people, not from bots. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

.pill {
	display: inline-block;
	font: 600 .8125rem/1 var(--font-ui);
	padding: .35rem .6rem;
	border-radius: 999px;
	background: var(--pill-bg);
	color: var(--pill-text);
	white-space: nowrap;
}
.pill-accent { background: var(--accent); color: var(--on-accent); }

.notice {
	font: 400 .9375rem/1.5 var(--font-ui);
	background: var(--bg-sunken);
	border-radius: var(--radius);
	padding: .9rem 1rem;
	margin: 0 0 1.25rem;
}
/* Across the top of a page: a preview of a draft. Not drawn in the mock-ups;
   the notice, stretched edge to edge. */
.notice.banner { margin: 0; border-radius: 0; text-align: center; }
.notice.error { color: var(--danger); }
/* A temporary password, shown once to be read out or copied. */
.notice .temp-password { display: inline-block; margin: .35rem 0; font: 700 1.125rem/1.3 ui-monospace, Menlo, monospace; user-select: all; overflow-wrap: anywhere; }

/* ── Home ─────────────────────────────────────────────────────────────────── */

/* A feature: the latest post on the home page, and a trip at the top of its
   page. On a phone the photo runs edge to edge with the words beneath it. On a
   wide screen the two sit side by side, so the title has room and the photo
   does not swallow the screen. Text never sits on a photograph. */
.hero {
	max-width: calc(var(--page) + 2 * var(--gutter));
	margin: 0 auto 3.5rem;
}
.hero-photo {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background: var(--bg-sunken);
}
.hero-text {
	padding: 1.75rem var(--gutter) 0;
	text-align: center;
}
.hero-text h1, .hero-text h2 { font-size: clamp(2rem, 6vw, 3.25rem); margin: .55rem 0 .7rem; letter-spacing: -.02em; }
.hero-text h2 a { color: inherit; text-decoration: none; }
.hero-text h2 a:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.hero-text .excerpt { font-size: 1.1875rem; color: var(--text-muted); margin: 0 0 1rem; text-wrap: pretty; }
.hero-text .meta { justify-content: center; }
.hero-text .btn { margin-top: 1.5rem; }
@media (min-width: 56rem) {
	.hero {
		display: grid;
		grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
		gap: 2.5rem;
		align-items: center;
		padding: 2rem var(--gutter) 0;
	}
	.hero-photo { border-radius: var(--radius); max-height: 75vh; }
	.hero-text { padding: 0; text-align: left; }
	.hero-text h1, .hero-text h2 { font-size: clamp(2.25rem, 3.6vw, 3.25rem); }
	.hero-text .meta { justify-content: flex-start; }
}

.section {
	max-width: calc(var(--page) + 2 * var(--gutter));
	margin: 0 auto 4rem;
	padding: 0 var(--gutter);
}
.section-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	border-top: 1px solid var(--border-firm);
	padding-top: 1rem;
	margin-bottom: 1.5rem;
}
.section-head h2 { font-size: 1.5rem; }
.section-head a { font: 600 .9375rem/1 var(--font-ui); }

/* A post in a listing. */
.cards { display: grid; gap: 2.75rem 2rem; }
@media (min-width: 46rem) { .cards { grid-template-columns: 1fr 1fr; } }
@media (min-width: 68rem) { .cards.three { grid-template-columns: 1fr 1fr 1fr; } }

.card { display: flex; flex-direction: column; gap: .55rem; position: relative; }
.card-photo {
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	border-radius: var(--radius);
	background: var(--bg-sunken);
	margin-bottom: .5rem;
}
.card h3 { font-size: 1.6rem; }
.card h3 a { color: var(--text); text-decoration: none; }
/* The whole card is the link's target, without nesting links. */
.card h3 a::after { content: ""; position: absolute; inset: 0; }
.card:hover h3 a { text-decoration: underline; text-decoration-thickness: 2px; }
.card .excerpt {
	margin: 0;
	color: var(--text-muted);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.card .kicker { position: relative; z-index: 1; }

.photo-count { display: inline-flex; align-items: center; gap: .3rem; }
.photo-count .icon { width: 1rem; height: 1rem; }
/* On a phone the line keeps to date and place, so it does not wrap and start a
   line with a separator. */
@media (max-width: 39.99rem) { .meta .photo-count { display: none; } }

.pager {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	margin-top: 3rem;
}
.pager .btn:only-child { margin-left: auto; }

/* Trip cards: a trip in a listing. */
.trip-card { position: relative; display: flex; flex-direction: column; gap: .45rem; }
.trip-card img {
	width: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	border-radius: var(--radius);
	background: var(--bg-sunken);
	margin-bottom: .45rem;
}
.trip-card h3 { font-size: 1.4rem; }
.trip-card h3 a { color: var(--text); text-decoration: none; }
.trip-card h3 a::after { content: ""; position: absolute; inset: 0; }
.trip-card:hover h3 a { text-decoration: underline; text-decoration-thickness: 2px; }

/* On a phone the trips scroll sideways rather than stacking three tall cards. */
.trip-strip {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: min(78%, 22rem);
	gap: 1.25rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	margin: 0 calc(-1 * var(--gutter));
	padding: 0 var(--gutter) .75rem;
	scrollbar-width: thin;
}
.trip-strip > * { scroll-snap-align: start; }
@media (min-width: 52rem) {
	.trip-strip { grid-auto-flow: row; grid-template-columns: repeat(3, 1fr); overflow: visible; margin: 0; padding: 0; }
}

/* ── Follow along: subscribe and RSS ─────────────────────────────────────── */

.follow {
	background: var(--bg-sunken);
	border-radius: calc(var(--radius) * 2);
	padding: 2rem var(--gutter);
	text-align: center;
}
.follow h2 { font-size: 1.75rem; }
.follow p { margin: .5rem auto 1.25rem; max-width: 28rem; color: var(--text-muted); }
.follow form { display: flex; gap: .5rem; max-width: 28rem; margin: 0 auto; flex-wrap: wrap; }
.follow .input { flex: 1 1 12rem; }
.follow .btn { flex: 1 0 auto; }
.follow .rss { display: inline-flex; align-items: center; gap: .35rem; margin-top: 1rem; font: 600 .9375rem/1 var(--font-ui); }
.follow .rss .icon { width: 1rem; height: 1rem; }

/* ── A post ───────────────────────────────────────────────────────────────── */

/* The story is a grid: text in the reading column, photos in the wide one. */
.story {
	display: grid;
	grid-template-columns:
		[full-start] minmax(var(--gutter), 1fr)
		[wide-start] minmax(0, calc((var(--wide) - var(--measure)) / 2))
		[content-start] min(var(--measure), 100% - 2 * var(--gutter))
		[content-end] minmax(0, calc((var(--wide) - var(--measure)) / 2))
		[wide-end] minmax(var(--gutter), 1fr) [full-end];
}
.story > * { grid-column: content; }
.story > .wide { grid-column: wide; }
.story > .full { grid-column: full; }

/* A post opens with its words. Its cover is for listings, emails and links
   shared elsewhere; drawn here too, it showed the same photo twice. The head
   spans the wide column so a long title is not squeezed. */
.story > .post-head { grid-column: wide; }
.post-head { text-align: center; padding: 2.75rem 0 2.5rem; max-width: 48rem; margin: 0 auto; }
.post-head h1 { font-size: clamp(2.25rem, 6vw, 3.75rem); margin: .7rem 0 0; letter-spacing: -.02em; }
.post-head .subtitle {
	font-style: italic;
	font-size: clamp(1.1875rem, 3vw, 1.4rem);
	line-height: 1.45;
	color: var(--text-muted);
	margin: 1rem 0 0;
	text-wrap: balance;
}
.post-head .meta { justify-content: center; margin-top: 1.25rem; }

.prose { font-size: 1.1875rem; line-height: 1.7; }
@media (min-width: 40rem) { .prose { font-size: 1.25rem; } }
.prose > * { margin: 0; }
.prose > * + * { margin-top: 1.15em; }
.prose h2 { font-size: 1.65rem; margin-top: 2em; }
.prose blockquote {
	margin-left: 0;
	padding-left: 1.1rem;
	border-left: 3px solid var(--accent);
	font-style: italic;
	color: var(--text-muted);
}
.prose ul, .prose ol { padding-left: 1.4em; }
.prose li + li { margin-top: .35em; }

/* Gaps between blocks. */
.story > .prose + .photos,
.story > .photos + .prose,
.story > .photos + .photos { margin-top: 2.25rem; }
.story > .prose + .prose { margin-top: 1.15em; }

/* ── Photo blocks ─────────────────────────────────────────────────────────── */

/* A block is one or more rows. In a row each figure grows in proportion to its
   aspect ratio (--ar = width / height) from a basis of zero, which makes every
   photo in the row the same height with nothing cropped. */
.photos { display: grid; gap: .5rem; margin: 0; }
.photo-row { display: flex; gap: .5rem; align-items: flex-start; }
.photo-row figure { flex: var(--ar) 1 0; margin: 0; min-width: 0; }
.photo-row img {
	width: 100%;
	height: auto;
	border-radius: 3px;
	background: var(--bg-sunken);
	cursor: zoom-in;
}
.photo-row a { display: block; }

/* A single photo is never taller than most of the screen: its figure is
   capped at the width that makes it 80% of the viewport's height, and centred.
   One that is square or upright sits in the reading column, not the wide one;
   the class says portrait, and covers square too. */
.photos.single .photo-row { justify-content: center; }
.photos.single figure {
	flex: 1 1 auto;
	max-width: min(100%, calc(80vh * var(--ar)));
	max-width: min(100%, calc(80dvh * var(--ar)));
}
.story > .photos.portrait { grid-column: content; }

/* On a phone a row of three is too small to see: the first takes the width,
   the other two share the line beneath it. */
@media (max-width: 39.99rem) {
	.photo-row.n3 { flex-wrap: wrap; }
	.photo-row.n3 > :first-child { flex-basis: 100%; }
}

figcaption {
	font: 400 .875rem/1.45 var(--font-ui);
	color: var(--text-muted);
	margin-top: .45rem;
	padding: 0 .1rem;
}
/* A caption under a photo in the wide column keeps to the reading measure. */
.photos > figcaption, .photos.single figcaption { max-width: var(--measure); }

/* ── End of a post: trip navigation, comments ─────────────────────────────── */

.post-end { margin-top: 4rem; }

.trip-nav {
	border-top: 1px solid var(--border-firm);
	border-bottom: 1px solid var(--border-firm);
	padding: 1.5rem 0;
}
.trip-nav-head { text-align: center; margin-bottom: 1.25rem; }
.trip-nav-head .meta { justify-content: center; }
.trip-nav-head h2 { font-size: 1.35rem; margin-top: .3rem; }
.trip-nav-head h2 a { color: var(--text); }
.trip-nav-links { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.trip-nav-link {
	display: grid;
	gap: .5rem;
	text-decoration: none;
	color: var(--text);
}
.trip-nav-link img { aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius); width: 100%; background: var(--bg-sunken); }
.trip-nav-link .meta { font-size: .8125rem; }
.trip-nav-link strong { font: 600 1.0625rem/1.25 var(--font-display); }
.trip-nav-link:hover strong { text-decoration: underline; }
.trip-nav-link.next { text-align: right; }
.trip-nav-link.next .meta { justify-content: flex-end; }
.trip-nav-link.empty { visibility: hidden; }

.comments { margin-top: 3.5rem; }
.comments h2 { font-size: 1.5rem; margin-bottom: 1.5rem; }
.comment { padding: 1.25rem 0; border-top: 1px solid var(--border); }
.comment:last-of-type { border-bottom: 1px solid var(--border); }
.comment-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem; margin-bottom: .4rem; }
.comment-head strong { font: 600 1rem/1.3 var(--font-ui); }
.comment-head .by-author { font: 600 .8125rem/1 var(--font-ui); color: var(--accent); }
.comment-head time { font: 400 .875rem/1.3 var(--font-ui); color: var(--text-muted); }
.comment p { margin: 0; font-size: 1.0625rem; }
.comment p + p { margin-top: .6em; }
.comments-empty { color: var(--text-muted); font-style: italic; margin: 0; }

.comment-form { margin-top: 2rem; }
.comment-form h3 { font-size: 1.25rem; margin-bottom: 1rem; }
.comment-form .fields { display: grid; gap: 1.1rem; }
@media (min-width: 36rem) { .comment-form .fields { grid-template-columns: 1fr 1fr; } }
.comment-form .fields .field + .field { margin-top: 0; }
.comment-form .field.body { margin-top: 1.1rem; }
.field .optional { font-weight: 400; color: var(--text-muted); }
.comment-form .actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; margin-top: 1.1rem; }
.comment-form .actions p { margin: 0; font: 400 .875rem/1.45 var(--font-ui); color: var(--text-muted); }

.post-end .follow { margin-top: 3.5rem; }

/* ── A trip ───────────────────────────────────────────────────────────────── */

.trip-head { text-align: center; padding: 2.25rem 0 2rem; }
.trip-head h1 { font-size: clamp(2.25rem, 7vw, 4rem); margin: .6rem 0 0; }
.trip-head .description { font-size: 1.1875rem; color: var(--text-muted); margin: 1rem 0 0; }
.trip-head .meta { justify-content: center; margin-top: 1.1rem; }
.trip-head .btn { margin-top: 1.5rem; }

/* A trip reads oldest first, numbered, like chapters. */
.chapters { list-style: none; margin: 0; padding: 0; display: grid; gap: 3rem; counter-reset: chapter; }
.chapter { position: relative; display: grid; gap: .5rem; }
@media (min-width: 46rem) {
	.chapter { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 2rem; align-items: center; }
}
.chapter img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--radius); background: var(--bg-sunken); }
.chapter .number { font: 600 .875rem/1 var(--font-ui); color: var(--accent); letter-spacing: .06em; text-transform: uppercase; }
.chapter h2 { font-size: clamp(1.5rem, 4vw, 2rem); margin: .4rem 0 .5rem; }
.chapter h2 a { color: var(--text); text-decoration: none; }
.chapter h2 a::after { content: ""; position: absolute; inset: 0; }
.chapter:hover h2 a { text-decoration: underline; text-decoration-thickness: 2px; }
.chapter .excerpt { margin: 0 0 .6rem; color: var(--text-muted); }

/* ── Small centred pages: sign in, subscribe, confirmations ──────────────── */

.narrow {
	max-width: calc(26rem + 2 * var(--gutter));
	margin: 0 auto;
	padding: 3rem var(--gutter) 4rem;
	width: 100%;
}
.narrow .brand-mark { height: 3.25rem; margin: 0 auto 1.25rem; }
.narrow h1 { font-size: 2.25rem; text-align: center; }
.narrow .lede { text-align: center; color: var(--text-muted); margin: .6rem 0 2rem; }
.narrow form .btn-block { margin-top: 1.5rem; }
.narrow .after { text-align: center; font: 400 .9375rem/1.5 var(--font-ui); margin-top: 1.5rem; }

/* ── Footer ───────────────────────────────────────────────────────────────── */

.site-footer {
	border-top: 1px solid var(--border-firm);
	margin-top: 5rem;
	padding: 2.5rem var(--gutter) 3rem;
	font: 400 .9375rem/1.6 var(--font-ui);
	color: var(--text-muted);
}
.site-footer .inner {
	max-width: var(--page);
	margin: 0 auto;
	display: grid;
	gap: 1.5rem;
}
@media (min-width: 46rem) { .site-footer .inner { grid-template-columns: 2fr 1fr; } }
.site-footer h2 { font: 600 1.125rem/1.2 var(--font-display); color: var(--text); margin-bottom: .4rem; }
.site-footer p { margin: 0; max-width: 34rem; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.site-footer a { color: var(--text); }
.site-footer .small { grid-column: 1 / -1; font-size: .875rem; }

/* ── The photo viewer ─────────────────────────────────────────────────────── */

/* Every photo in the post in one horizontal scroll-snap track. Swiping is the
   browser's own scrolling, so it feels native on a phone and needs no gesture
   code; the arrows and keys just scroll the track by one. */
.viewer {
	position: fixed;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: var(--viewer-bg);
	color: var(--viewer-text);
	overflow: hidden;
}
.viewer::backdrop { background: var(--viewer-bg); }
.viewer[open] { display: grid; grid-template-rows: auto 1fr auto; }
.viewer-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: .5rem .75rem;
	font: 500 .9375rem/1 var(--font-ui);
}
.viewer .icon-btn { color: var(--viewer-text); }
.viewer .icon-btn:hover { background: rgb(255 255 255 / .1); }
.viewer-track {
	display: flex;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	min-height: 0;
}
.viewer-track::-webkit-scrollbar { display: none; }
.viewer-slide {
	flex: 0 0 100%;
	scroll-snap-align: center;
	display: grid;
	place-items: center;
	padding: 0 .5rem;
	min-height: 0;
}
/* Capped against the viewport, not the slide: a percentage height inside the
   track does not resolve, and a portrait photo then spills past the caption. */
.viewer-slide img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: calc(100vh - 8.5rem);
	max-height: calc(100dvh - 8.5rem);
	object-fit: contain;
	border-radius: 2px;
}
.viewer-caption {
	min-height: 3.5rem;
	padding: .75rem 1rem calc(1rem + env(safe-area-inset-bottom));
	text-align: center;
	font: 400 .9375rem/1.45 var(--font-ui);
}
.viewer-prev, .viewer-next {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	background: rgb(0 0 0 / .45) !important;
}
.viewer-prev { left: .75rem; }
.viewer-next { right: .75rem; }
@media (hover: none) { .viewer-prev, .viewer-next { display: none; } }

/* ============================================================================
   Authors: the dashboard and the editor. Phone first, system sans throughout,
   because this is a tool rather than something to read.
   ========================================================================== */

.app { font-family: var(--font-ui); }
.app h1, .app h2, .app h3 { font-family: var(--font-ui); letter-spacing: 0; }

.app-header {
	position: sticky;
	top: 0;
	z-index: 10;
	background: var(--bg);
	border-bottom: 1px solid var(--border);
}
.app-header .site-header { padding-top: .5rem; padding-bottom: .5rem; }

/* The account menu: a disclosure, so it opens without a script. */
.menu { position: relative; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-list {
	position: absolute;
	right: 0;
	top: calc(100% + .35rem);
	z-index: 20;
	min-width: 13rem;
	background: var(--bg-raised);
	border: 1px solid var(--border-firm);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	padding: .35rem;
	display: grid;
}
.menu-list a, .menu-list button {
	font: 500 .9375rem/1.3 var(--font-ui);
	color: var(--text);
	text-align: left;
	text-decoration: none;
	background: none;
	border: 0;
	padding: .65rem .75rem;
	border-radius: .35rem;
	cursor: pointer;
	width: 100%;
}
.menu-list a:hover, .menu-list button:hover { background: var(--bg-sunken); }
.menu-list hr { border: 0; border-top: 1px solid var(--border); margin: .3rem 0; }
.menu-list .menu-head { padding: .6rem .75rem .3rem; margin: 0; font: 600 .9375rem/1.3 var(--font-ui); }
.menu-list .menu-head span { display: block; font-weight: 400; color: var(--text-muted); font-size: .875rem; }
.menu-list .danger { color: var(--danger); }

.avatar {
	display: inline-grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 999px;
	background: var(--accent);
	color: var(--on-accent);
	font: 700 .9375rem/1 var(--font-ui);
}

/* Dashboard tabs wrap onto a second line on a narrow screen, as the sibling
   apps' settings tabs do, rather than scrolling sideways out of sight. */
.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: .25rem;
	max-width: calc(48rem + 2 * var(--gutter));
	margin: 0 auto;
	padding: .1rem calc(var(--gutter) - .6rem) .6rem;
}
.tab {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	font: 600 .9375rem/1 var(--font-ui);
	color: var(--text-muted);
	text-decoration: none;
	padding: .6rem .7rem;
	border-radius: var(--radius);
	white-space: nowrap;
}
.tab:hover { color: var(--text); background: var(--bg-sunken); }
.tab[aria-current="page"] { color: var(--accent); background: var(--bg-sunken); }
.tab .count {
	font: 700 .75rem/1 var(--font-ui);
	background: var(--accent);
	color: var(--on-accent);
	border-radius: 999px;
	padding: .2rem .45rem;
}

.dash {
	max-width: calc(48rem + 2 * var(--gutter));
	margin: 0 auto;
	padding: 1.75rem var(--gutter) 4rem;
	width: 100%;
}
.dash h1 { font-size: 1.5rem; }
.dash-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.dash h2 {
	font: 600 .8125rem/1 var(--font-ui);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--text-muted);
	margin: 2.25rem 0 .75rem;
}
.dash h2:first-of-type { margin-top: 0; }

.new-post { width: 100%; min-height: 3.5rem; font-size: 1.0625rem; margin-bottom: 2rem; }
.new-post .icon { width: 1.25rem; height: 1.25rem; }

/* A row in a dashboard list: thumbnail, words, an action or a status. */
.rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.rows > li { border-bottom: 1px solid var(--border); }
.row {
	display: grid;
	grid-template-columns: 4rem minmax(0, 1fr) auto;
	align-items: center;
	gap: .9rem;
	padding: .75rem 0;
	color: var(--text);
	text-decoration: none;
}
a.row:hover strong { text-decoration: underline; }
.row img, .row .no-photo {
	width: 4rem;
	height: 4rem;
	object-fit: cover;
	border-radius: .35rem;
	background: var(--bg-sunken);
}
.row .no-photo { display: grid; place-items: center; color: var(--text-muted); }
.row strong {
	display: block;
	font: 600 1rem/1.3 var(--font-ui);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.row strong.untitled { color: var(--text-muted); font-style: italic; font-weight: 500; }
.row .meta { font-size: .8125rem; margin-top: .2rem; }
.row.no-thumb { grid-template-columns: minmax(0, 1fr) auto; }

/* A comment waiting for a decision. */
.queue { display: grid; gap: 1rem; }
.queue-item {
	background: var(--bg-raised);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1rem;
}
.queue-item .on { font: 500 .875rem/1.4 var(--font-ui); color: var(--text-muted); margin: 0 0 .6rem; }
.queue-item .on a { color: var(--text); font-weight: 600; }
.queue-item .who { font-weight: 600; }
.queue-item .who span { font-weight: 400; color: var(--text-muted); }
.queue-item .body { margin: .4rem 0 1rem; font: 400 1rem/1.55 var(--font-ui); }
.queue-item .actions { display: flex; gap: .5rem; flex-wrap: wrap; }

.panel {
	background: var(--bg-raised);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.25rem;
}
.panel + .panel { margin-top: 1.25rem; }
.panel h3 { font-size: 1.0625rem; margin-bottom: 1rem; }
.panel.spaced { margin-top: 2rem; }
.panel form > .btn { margin-top: 1.1rem; }
.after-check { margin: .4rem 0 0 1.9rem; }
.check + .field, .hint + .check, .field + .check, .hint + .field { margin-top: 1.25rem; }
.panel > .hint:last-child, .form-actions + .hint { margin-top: .9rem; }
.panel > .hint + .btn { margin-top: 1rem; }
.cover-pick { border: 0; padding: 0; margin: 1.1rem 0 0; }
.cover-pick legend { margin-bottom: .5rem; }
.form-actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1.5rem; }

.stat { font: 700 2.25rem/1 var(--font-ui); }
.stat-label { font: 500 .9375rem/1.4 var(--font-ui); color: var(--text-muted); }

/* Not drawn in the mock-ups, extrapolated from them. A form that is only a
   button sits wherever the button would; every dashboard action is a form so
   it works without a script. */
.queue-item .actions form, .row form, .row .actions form, .menu-list form { display: contents; }
.row .actions { display: flex; gap: .25rem; }
.row > .menu > summary { color: var(--text-muted); }

/* Choosing a trip's cover: the thumbs are radio buttons. */
.cover-pick .thumb { display: block; }
.cover-pick .badge.cover { display: none; }
.cover-pick input:checked ~ .badge.cover { display: block; }
.cover-pick .thumb:has(input:checked) { outline: 3px solid var(--accent); outline-offset: -3px; }
.cover-pick .thumb:has(input:focus-visible) { outline: 3px solid var(--text); outline-offset: -3px; }
.thumb .no-photo {
	display: grid;
	place-items: center;
	height: 100%;
	padding: .5rem;
	text-align: center;
	font: 600 .8125rem/1.3 var(--font-ui);
	color: var(--text-muted);
}

/* ── The editor ───────────────────────────────────────────────────────────── */

.editor-bar {
	position: sticky;
	top: 0;
	z-index: 10;
	background: var(--bg);
	border-bottom: 1px solid var(--border);
}
.editor-bar .inner {
	display: flex;
	align-items: center;
	gap: .25rem;
	max-width: calc(var(--measure) + 2 * var(--gutter));
	margin: 0 auto;
	padding: .5rem calc(var(--gutter) - .5rem);
}
.editor-bar .back { font: 600 .9375rem/1 var(--font-ui); color: var(--text); text-decoration: none; display: inline-flex; align-items: center; gap: .15rem; padding: .6rem .5rem; border-radius: 999px; }
.editor-bar .back:hover { background: var(--bg-sunken); }
.save-state {
	font: 500 .875rem/1 var(--font-ui);
	color: var(--text-muted);
	margin-right: auto;
	padding-left: .25rem;
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	white-space: nowrap;
	overflow: hidden;
	min-width: 0;
}
.save-state .dot { width: .5rem; height: .5rem; border-radius: 99px; background: currentColor; flex: none; }
.save-state.unsaved { color: var(--accent); }

.editor {
	max-width: calc(var(--measure) + 2 * var(--gutter));
	margin: 0 auto;
	padding: 1.5rem var(--gutter) 8rem;
	width: 100%;
}

/* The title is a textarea so a long title wraps on a phone. */
.title-input {
	width: 100%;
	border: 0;
	background: none;
	color: var(--text);
	font: 600 2rem/1.15 var(--font-display);
	letter-spacing: -.01em;
	padding: 0;
	resize: none;
	field-sizing: content;
	min-height: 2.5rem;
	overflow: hidden;
}
.title-input::placeholder, .text-block textarea::placeholder { color: var(--text-muted); opacity: .75; }
.title-input:focus { outline: none; }

.post-facts { margin: .6rem 0 1.5rem; }
.post-facts button {
	font: 500 .875rem/1.5 var(--font-ui);
	color: var(--text-muted);
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
	text-align: left;
}
.post-facts button:hover { color: var(--text); text-decoration: underline; }
.post-facts span { white-space: nowrap; }

.block { position: relative; margin-top: 1rem; }
.block-tools {
	position: absolute;
	top: .25rem;
	right: -.5rem;
}
.block-tools > summary {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 999px;
	color: var(--text-muted);
}
.block-tools > summary:hover { background: var(--bg-sunken); color: var(--text); }

.text-block textarea {
	width: 100%;
	border: 0;
	border-left: 2px solid var(--border);
	background: none;
	color: var(--text);
	font: 400 1.125rem/1.65 var(--font-body);
	padding: .25rem 2.25rem .25rem .9rem;
	resize: none;
	field-sizing: content;
	min-height: 3.5rem;
	overflow: hidden;
}
.text-block textarea:focus { outline: none; border-left-color: var(--accent); }

.photo-block {
	border: 1px dashed var(--border-firm);
	border-radius: var(--radius);
	padding: .5rem 2.75rem .5rem .5rem;
}
.thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
@media (min-width: 30rem) { .thumbs { grid-template-columns: repeat(4, 1fr); } }
.thumb {
	position: relative;
	aspect-ratio: 1;
	border: 0;
	padding: 0;
	border-radius: .3rem;
	overflow: hidden;
	background: var(--bg-sunken);
	cursor: pointer;
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb .badge {
	position: absolute;
	left: .3rem;
	bottom: .3rem;
	font: 700 .6875rem/1 var(--font-ui);
	background: var(--bg-raised);
	color: var(--text);
	border-radius: 99px;
	padding: .25rem .4rem;
}
.thumb .badge.cover { left: auto; right: .3rem; top: .3rem; bottom: auto; background: var(--accent); color: var(--on-accent); }
/* Uploading: the photo is dimmed and a ring shows how far it has got. */
.thumb.uploading img { opacity: .45; }
.thumb .ring {
	position: absolute;
	inset: 0;
	margin: auto;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 99px;
	background: conic-gradient(var(--on-accent) calc(var(--p, 0) * 1%), transparent 0);
	-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 0);
	mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 0);
	filter: drop-shadow(0 0 2px rgb(0 0 0 / .6));
}
.thumb.failed { outline: 2px solid var(--danger); outline-offset: -2px; }
.thumb.failed .retry {
	position: absolute;
	inset: auto 0 0;
	background: var(--bg-raised);
	color: var(--danger);
	font: 700 .75rem/1 var(--font-ui);
	padding: .4rem 0;
}
.add-thumb {
	aspect-ratio: 1;
	border: 1px dashed var(--border-firm);
	border-radius: .3rem;
	background: none;
	color: var(--text-muted);
	display: grid;
	place-items: center;
	cursor: pointer;
}
.add-thumb:hover { color: var(--accent); border-color: var(--accent); }

/* The toolbar sits on the bottom edge, in thumb's reach. */
.add-bar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 10;
	background: var(--bg-raised);
	border-top: 1px solid var(--border-firm);
	padding: .6rem var(--gutter) calc(.6rem + env(safe-area-inset-bottom));
}
.add-bar .inner {
	max-width: var(--measure);
	margin: 0 auto;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: .6rem;
}
.add-bar .btn { min-height: 3rem; }

/* Bottom sheets: a dialog that rises from the foot on a phone and sits
   centred on a wider screen. */
.sheet {
	border: 0;
	padding: 0;
	margin: auto auto 0;
	width: 100%;
	max-width: 100%;
	max-height: 92vh;
	background: var(--bg-raised);
	color: var(--text);
	border-radius: 1rem 1rem 0 0;
	box-shadow: var(--shadow);
	font-family: var(--font-ui);
}
.sheet::backdrop { background: rgb(0 0 0 / .45); }
@media (min-width: 40rem) {
	.sheet { margin: auto; max-width: 30rem; border-radius: 1rem; }
}
.sheet-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: .75rem .75rem .25rem 1.25rem;
}
.sheet-head h2 { font-size: 1.125rem; }
.sheet-body { padding: .5rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom)); }
.sheet-photo { width: 100%; max-height: 40vh; object-fit: contain; background: var(--bg-sunken); border-radius: var(--radius); margin-bottom: 1.1rem; }
.sheet-actions { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-top: 1.25rem; }
.sheet-actions .wide { grid-column: 1 / -1; }
.sheet p { font-size: .9375rem; line-height: 1.5; }
