/* The Librarian Abroad — travel & food blog.
   Its own stylesheet: nothing here is shared with, or imported from, /style.css,
   and the two sites are never linked. It does borrow the main site's page
   treatment — deep navy under a soft gold top-glow — at Michael's request, while
   keeping terracotta as its own accent so the two still read as different
   publications. */

/* Palette: the deep navy + warm top-glow treatment from the main site (Michael's
   call — he likes those colours), carrying this blog's own terracotta accent so
   the two still read as different publications. Dark-only, like the main site:
   one predictable appearance beats a light/dark pair that renders two ways on
   two phones. The --paper / --ink variable names are kept from the light era so
   every rule below stayed valid. */
:root {
  --paper:      #060b14;   /* page ground */
  --paper-2:    #0d1520;   /* raised panels and cards */
  --paper-3:    #0a0f1a;
  --ink:        #e8dfd2;   /* warm off-white — a shade warmer than the main site */
  --ink-soft:   #c3b7a8;
  --muted:      #94a3b8;
  --line:       rgba(255,255,255,.09);
  --terra:      #e8865c;
  --terra-dk:   #f0a382;
  --olive:      #a3b378;
  --gold:       #e8c968;   /* the main site's gold — also the star colour */
  --shadow:     0 1px 2px rgba(0,0,0,.35), 0 10px 30px rgba(0,0,0,.45);
  --radius:     14px;
  --maxw:       860px;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  /* The glow: a wide, soft gold wash falling from just above the top edge.
     `fixed` anchors it to the viewport, so it reads as light in the room rather
     than a gradient that scrolls away with the content. */
  background:
    radial-gradient(120% 80% at 50% -8%, rgba(232,201,104,0.08), transparent 60%) fixed,
    var(--paper);
  color: var(--ink);
  font: 17px/1.7 Georgia, "Iowan Old Style", "Palatino Linotype", serif;
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 22px 72px;
}

a { color: var(--terra-dk); }
a:hover { color: var(--terra); }

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

/* ------------------------------------------------------------------ header -- */

.site-head { position: relative; padding: 34px 0 14px; text-align: center; }

/* The site name is the h1 on the home page and a plain div elsewhere (where the
   entry title takes that role). This resets the h1's default type so the header
   looks identical either way. */
.brandwrap { margin: 0; font-size: inherit; font-weight: inherit; line-height: 1; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
}
.brand .mark {
  flex: none;
  filter: drop-shadow(0 0 14px rgba(232,201,104,.22));
}

/* The needle swings past north and settles, then rests — a compass finding its
   bearing, not a spinner. Most of the 11s cycle is stillness on purpose: motion
   that never stops is motion you stop seeing, and it would fight the photographs
   for attention. transform-box/-origin are required for the rotation to pivot on
   the SVG's own centre rather than the element box. */
.brand .needle {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: compass-settle 11s cubic-bezier(.28,.9,.32,1) infinite;
}
@keyframes compass-settle {
  0%   { transform: rotate(0deg); }
  6%   { transform: rotate(-19deg); }
  13%  { transform: rotate(13deg); }
  20%  { transform: rotate(-7deg); }
  27%  { transform: rotate(3deg); }
  34%  { transform: rotate(-1deg); }
  40%, 100% { transform: rotate(0deg); }
}
.brand:hover .needle { animation-duration: 3.4s; }

@media (prefers-reduced-motion: reduce) {
  .brand .needle { animation: none; }
}
.brand-name {
  font-size: 30px;
  letter-spacing: .2px;
  font-weight: 400;
}
.brand-name .abroad { color: var(--terra); font-style: italic; }

/* Breadcrumb up to the hub (2026-09-21, Michael's ask, ported from the
   Notebook after he approved it there): "Mister Library › The Librarian
   Abroad" — a page here had no way back to the root hub except the
   browser's back button. This blog's header is its own centered hero
   layout (not the compact two-row .hsm the other four publications share),
   so the crumb sits beside the brand inside the same centered flex row
   rather than in a fixed left position. The .brandwrap (the <h1> on the
   home page) still wraps ONLY this blog's own brand — the hub crumb is a
   sibling, not folded into that heading. The hub mark is a byte-for-byte
   copy of <svg class="mark"> in the root index.html (hand-written, not
   built — nothing to import; keep the two in step by hand if it ever
   changes), sized to match this page's own 62px compass, with the same
   gold gradient text-fill + drop-shadow halo used on every publication's
   crumb, so the hub's identity travels with it rather than borrowing this
   blog's own terracotta accent. */
.brandcrumb { display: inline-flex; align-items: center; gap: 14px; }
.hublink {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  transition: opacity .15s ease;
}
.hublink:hover { opacity: .82; }
.hubmark {
  width: 62px;
  height: 62px;
  flex: none;
  filter: drop-shadow(0 0 6px rgba(232,201,104,.55)) drop-shadow(0 0 14px rgba(232,201,104,.35));
}
.hublink .hubwm {
  font-size: 30px;
  font-weight: 400;
  letter-spacing: .2px;
  white-space: nowrap;
  background: linear-gradient(90deg, #f7931a, #e8865c 45%, #e8c968 85%);
  -webkit-background-clip: text;
  background-clip: text;
  color: #e8c968;
  -webkit-text-fill-color: transparent;
}
.crumbsep { flex: none; }
.shelf-spine {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: spinePop 3.6s ease-in-out infinite;
  animation-delay: var(--d);
}
@keyframes spinePop {
  0%, 84%, 100% { transform: translateY(0); filter: brightness(1); }
  10% { transform: translateY(-2.4px); filter: brightness(1.55); }
}
@media (prefers-reduced-motion: reduce) { .shelf-spine { animation: none; } }
@media (max-width: 560px) {
  .hubmark { width: 45px; height: 45px; }
  .hublink .hubwm { display: none; }
}

/* Used to float absolutely in the header's upper-right corner (see header()'s
   docstring for why it's a real form rather than a JS-only widget). The hub
   breadcrumb (2026-09-21) widened the centered brand row enough that its
   right edge now runs INTO that fixed corner position at every width up to
   .wrap's own 860px cap — not just below some narrow breakpoint the way the
   old mobile fallback assumed. So the corner float is retired: search is now
   always centered, static, in normal flow below the brand row (the same
   treatment the old sub-640px fallback already used, now the only one). */
.headersearch { margin: 18px auto 0; max-width: 220px; }
.headersearch input[type="search"] {
  width: 100%;
  font: 14px/1.3 Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 15px;
  -webkit-appearance: none;
  appearance: none;
  transition: width .15s ease;
}
.headersearch input[type="search"]::-webkit-search-cancel-button { display: none; }
.headersearch input[type="search"]::placeholder { color: var(--muted); }
.headersearch input[type="search"]:focus {
  outline: none;
  border-color: var(--terra);
  box-shadow: 0 0 0 3px rgba(194,94,58,.14);
}

.searchcount {
  text-align: center;
  margin: -14px 0 22px;
  font: 12.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: var(--muted);
  min-height: 1em;
}

.site-head .rule {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent);
  margin: 16px 0 12px;
}

.site-head .tag {
  color: var(--muted);
  font-size: 14.5px;
  font-style: italic;
  letter-spacing: .3px;
}

.topnav {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 4px;
  justify-content: center;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 13.5px;
}
.topnav a {
  text-decoration: none;
  color: var(--ink-soft);
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: background .15s, border-color .15s, color .15s;
}
.topnav a:hover { background: var(--paper-2); border-color: var(--line); color: var(--ink); }
.topnav a.on { background: var(--terra); border-color: var(--terra); color: #0a0f1a; }

/* Mobile nav menu (2026-07-27) -- below 640px this REPLACES .topnav (which
   otherwise word-wraps Latest/Archive/Bookmarked/Write/About/RSS/Share into a
   couple of ragged rows) with one collapsed <details> panel, same pattern as
   the Bible site's .mobmenu -- kept as its own copy per this site's
   no-cross-dependency rule. Desktop untouched. MUST come after the base
   .topnav rule above (paid for once already): with equal specificity, CSS
   breaks the tie by source order regardless of media-query nesting, so a
   `.topnav{display:none}` declared BEFORE the unconditional `.topnav{display:
   flex}` gets silently overridden even while the media query matches. */
.mobmenu { display: none; }
@media (max-width: 640px) {
  .topnav { display: none; }
  .mobmenu { display: block; margin: 14px auto 0; max-width: 300px; }
  .mobmenu summary {
    list-style: none; cursor: pointer; user-select: none;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    font: 14px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    font-weight: 600; color: var(--ink);
    padding: 10px 20px; border: 1px solid var(--line); border-radius: 999px;
    background: var(--paper-2);
  }
  .mobmenu summary::-webkit-details-marker { display: none; }
  .mobmenu summary::after { content: "▾"; font-size: 11px; opacity: .7; transition: transform .15s; }
  .mobmenu[open] summary::after { transform: rotate(180deg); }
  .mobmenu-panel {
    margin-top: 8px; padding: 6px; background: var(--paper-2); border: 1px solid var(--line);
    border-radius: 14px; display: flex; flex-direction: column; gap: 2px; text-align: left;
  }
  .mobmenu-panel a {
    font: 14px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    font-weight: 500; color: var(--ink-soft); text-decoration: none;
    padding: 10px 14px; border-radius: 9px;
  }
  .mobmenu-panel a:hover, .mobmenu-panel a.on { color: var(--terra-dk); background: rgba(232,134,92,.08); }
  .mobmenu-sep { height: 1px; background: var(--line); margin: 6px 8px; }
  .mobmenu-panel .share-widget { padding: 6px 14px; }
}

/* -------------------------------------------------------------------- lede -- */

.lede { text-align: center; margin: 40px 0 26px; }
.lede h1 {
  font-size: 34px;
  line-height: 1.25;
  margin: 0 0 10px;
  font-weight: 400;
}
.lede p { color: var(--ink-soft); margin: 0 auto; max-width: 34em; font-size: 17px; }
.pagehits { margin: 14px 0 0; font-size: 12.5px; color: var(--muted); }

/* ----------------------------------------------------------------- filters -- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin: 0 0 30px;
}
.chip {
  font: 13px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  padding: 8px 15px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper-2);
  color: var(--ink-soft);
  cursor: pointer;
  transition: all .15s;
}
.chip:hover { border-color: var(--terra); color: var(--terra); }
.chip.on { background: var(--olive); border-color: var(--olive); color: #0a0f1a; }

/* The long tail of one-off dish tags, folded away until asked for. See
   TAG_BAR_MIN_COUNT in build_travel.py for why. Display only — every tag is
   still in the DOM, still filterable, still linked from the foot of an entry. */
.chip.rare { display: none; }
.filters.tags-open .chip.rare { display: block; }

/* The disclosure itself: dashed, so it reads as "there is more behind this"
   rather than as another tag you could filter by. */
.chip.more {
  border-style: dashed;
  color: var(--muted);
  background: transparent;
}
.chip.more:hover { border-color: var(--terra); color: var(--terra); }

/* A weight cue instead of a tag cloud — the recurring tags read slightly
   stronger so the bar still tells you what the blog is mostly about, but
   nothing is shrunk and nothing loses contrast, so every chip stays an equal
   tap target and screen readers are unaffected. */
.chip.w2 { color: var(--ink); }
.chip.w3 { color: var(--ink); font-weight: 600; border-color: rgba(255,255,255,.18); }
.chip.w2.on, .chip.w3.on { color: #0a0f1a; }
/* A tag list wraps to 6-7 rows once there are ~20 tags -- fine on desktop, but
   on a phone that's most of a screen of filter chips before the first post
   card. A single horizontally-scrolling row keeps every tag reachable in the
   footprint of one line. */
@media (max-width: 560px) {
  .filters { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    justify-content: flex-start; padding-bottom: 4px; margin: 0 0 22px; }
  .chip { flex: 0 0 auto; white-space: nowrap; }
}

/* ------------------------------------------------------------------- cards -- */

.cards { display: grid; gap: 26px; }

.card {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform .18s ease, box-shadow .18s ease;
}
.card:hover { transform: translateY(-2px); border-color: rgba(232,201,104,.28);
  box-shadow: 0 4px 12px rgba(0,0,0,.4), 0 18px 48px rgba(0,0,0,.5); }

.cardlink { text-decoration: none; color: inherit; display: block; }

.card .thumb { margin: 0; }
.card .thumb img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }

.cardbody { padding: 20px 22px 22px; }
.cardbody h2 {
  margin: 8px 0 8px;
  font-size: 23px;
  font-weight: 400;
  line-height: 1.3;
}
.cardbody .summary { margin: 0; color: var(--ink-soft); font-size: 16px; }

@media (min-width: 720px) {
  .cards { grid-template-columns: 1fr 1fr; }
  .cards .card:first-child { grid-column: 1 / -1; }
  .cards .card:first-child .thumb img { aspect-ratio: 21 / 9; }
  .cards .card:first-child .cardbody h2 { font-size: 27px; }
}

/* ------------------------------------------- "keep reading" (foot of post) -- */
/* The related strip under an entry. A reader who lands here from a search
   engine has never seen the index, so the foot of the page is the one place
   left to offer them somewhere to go — see _related_block in build_travel.py
   for how the three are chosen (place first, then shared tags). */

.readnext { margin: 54px 0 0; border-top: 1px solid var(--line); padding-top: 26px; }
.readnext > h2 {
  margin: 0 0 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Smaller than an index card: this is a footnote to the entry above it, not
   the main event. The tag pills are dropped and the summary is clamped for
   the same reason — left full-size, three cards of seven pills each and an
   unclamped summary made the strip taller than the closing section of the
   entry it hangs off, which inverts what the reader should be looking at.
   Nothing is lost: the pills repeat tags the entry above already lists, and
   a card is a teaser, not the piece. */
.readnext .cardbody { padding: 14px 16px 17px; }
.readnext .cardbody h2 { font-size: 19px; margin: 6px 0 7px; }
.readnext .cardbody .summary {
  font-size: 14.5px;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.readnext .cardbody .tags { display: none; }

@media (min-width: 720px) {
  .readnext .cards { grid-template-columns: 1fr 1fr 1fr; }
  /* The index promotes its first card to a full-width hero; a related strip
     wants three equal cards, so that treatment is undone here rather than by
     forking post_card into a second renderer just to drop one class. */
  .readnext .cards .card:first-child { grid-column: auto; }
  .readnext .cards .card:first-child .thumb img { aspect-ratio: 16 / 9; }
  .readnext .cards .card:first-child .cardbody h2 { font-size: 19px; }
}

/* --------------------------------------------------- listing view + pages -- */
/* The cards/list toggle + "show more" pagination on the index page. A whole
   section (#cards, #archiveList, #sortbar, #loadMoreWrap) is shown/hidden via
   the `hidden` attribute from JS — [hidden] on its own loses to a later class
   rule of equal specificity (.cards{display:grid} would win), so each toggled
   container gets an explicit override here rather than relying on the UA
   default. Individual cards/rows still use inline style.display for the
   filter, which already wins on specificity without any of this. */
#cards[hidden], #archiveList[hidden], #sortbar[hidden], #loadMoreWrap[hidden] {
  display: none !important;
}

.listcontrols {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 18px;
  margin: 0 0 26px;
}
.listcontrols .sortbar { margin: 0; }

#archiveList { margin-top: 4px; }

.loadmorewrap { text-align: center; margin: 10px 0 0; }
.loadmore {
  font: 15px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  background: var(--terra);
  color: #0a0f1a;
  border: 0;
  border-radius: 999px;
  padding: 13px 28px;
  cursor: pointer;
  transition: background .15s;
}
.loadmore:hover { background: var(--terra-dk); }
.viewcount {
  margin: 10px 0 0;
  font: 12.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: var(--muted);
}

/* -------------------------------------------------------------- post metas -- */

.postmeta {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 9px;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: #6b7789;
}
.postmeta .upd-stamp { text-transform: none; letter-spacing: 0; font-style: italic; }
a.pill {
  text-decoration: none;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
a.pill:hover,
a.pill:focus-visible {
  color: var(--ink);
  border-color: var(--terra);
  background: var(--paper-2);
}
.postmeta .place { text-transform: none; letter-spacing: 0; }
.postmeta .draftflag {
  color: #0a0f1a;
  background: var(--terra-dk);
  padding: 2px 8px;
  border-radius: 4px;
  letter-spacing: .5px;
}

/* The unmissable banner atop a draft preview page (build_draft_previews) —
   deliberately louder than the small .draftflag pill above, since this is
   the ONE thing standing between a private preview link and a page that
   reads like a normal published entry. */
.draftbanner {
  margin: 0 0 30px;
  padding: 14px 20px;
  background: rgba(232,134,92,.12);
  border: 1px solid var(--terra);
  border-radius: var(--radius);
  color: var(--ink);
  font: 14.5px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  text-align: center;
}
.draftbanner strong { color: var(--terra-dk); }
.draftbanner a { color: var(--terra-dk); }

/* "Publish this entry" — foot of a draft preview only (_publish_box). Olive
   rather than terracotta on purpose: every other draft-only chrome on the page
   is terracotta and means "careful, not live", and this is the one control that
   means "yes, go". Sits AFTER the article because it is meant to be pressed
   having read the thing, not from the top of the page. */
.publishbox {
  margin: 38px 0 30px;
  padding: 22px 20px;
  background: rgba(163,179,120,.09);
  border: 1px solid rgba(163,179,120,.45);
  border-radius: var(--radius);
  text-align: center;
  font: 14.5px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}
.publishbox strong { display: block; color: var(--olive); margin-bottom: 14px; }
.pubbtn {
  display: inline-block;
  padding: 12px 26px;
  border-radius: 999px;
  background: var(--olive);
  color: #0a0f1a;
  font-weight: 700;
  font-size: 15.5px;
  letter-spacing: .2px;
  text-decoration: none;
  box-shadow: var(--shadow);
  transition: transform .12s ease, filter .12s ease;
}
.pubbtn:hover, .pubbtn:focus { filter: brightness(1.08); transform: translateY(-1px); }
.pubbtn:active { transform: translateY(0); }
.pubnote {
  display: block;
  margin-top: 14px;
  color: var(--muted);
  font-size: 13px;
}
@media (prefers-reduced-motion: reduce) {
  .pubbtn { transition: none; }
  .pubbtn:hover, .pubbtn:focus, .pubbtn:active { transform: none; }
  .respond-btn { transition: none; }
  .respond-btn:hover, .respond-btn:focus, .respond-btn:active { transform: none; }
}

/* Share-this-page button (share.js) rides as the last item in .topnav itself
   (see header()) -- sized/padded to match .topnav a so it reads as a native
   nav item, not a separate floating line under the header. */
.share-widget { display: inline-flex; align-items: center; gap: 8px; }
.share-btn {
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink-soft);
  background: transparent;
  padding: 6px 13px;
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  user-select: none;
  transition: background .15s, border-color .15s, color .15s;
}
.share-btn:hover, .share-btn:focus-visible {
  background: var(--paper-2);
  border-color: var(--line);
  color: var(--ink);
}
.share-toast { font-size: 11.5px; font-weight: 600; color: var(--terra-dk); opacity: 0; transition: opacity .15s; white-space: nowrap; }
.share-toast.show { opacity: 1; }

.tags { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; }
.pill {
  font: 12px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  padding: 6px 11px;
  border-radius: 999px;
  background: var(--paper);
  border: 1px solid var(--line);
  color: var(--muted);
}

/* -------------------------------------------------------------------- post -- */

.post { margin: 34px 0 10px; }
.post h1 {
  font-size: 34px;
  line-height: 1.22;
  font-weight: 400;
  margin: 0 0 12px;
}
.post .postmeta { margin-bottom: 28px; }   /* breathing room before the first line */
.post .hero { margin: 26px 0 30px; }
/* max-height keeps a PORTRAIT hero from running the full height of the screen;
   a landscape one is limited by the column width long before it reaches this. */
.post .hero img { width: auto; max-width: 100%; max-height: 640px; margin: 0 auto; border-radius: var(--radius); }
figure img { max-width: 100%; margin: 0 auto; }

figure { margin: 26px 0; }
figure img { border-radius: var(--radius); }
figure video { width: auto; max-width: 100%; max-height: 640px; display: block;
  margin: 0 auto; border-radius: var(--radius); background: #000; }
figcaption, .credit {
  margin-top: 9px;
  font: italic 14px/1.5 Georgia, serif;
  color: var(--muted);
  text-align: center;
}

.postbody { font-size: 18px; }
.postbody p { margin: 0 0 1.15em; }
.postbody h2 {
  font-size: 25px;
  font-weight: 400;
  margin: 1.9em 0 .5em;
  padding-bottom: .28em;
  border-bottom: 1px solid var(--line);
}
.postbody h3 { font-size: 20px; font-weight: 400; margin: 1.6em 0 .4em; color: var(--terra-dk); }
.postbody blockquote {
  margin: 1.6em 0;
  padding: 4px 0 4px 20px;
  border-left: 3px solid var(--gold);
  color: var(--ink-soft);
  font-style: italic;
}
.postbody ul, .postbody ol { padding-left: 1.3em; }
.postbody li { margin: .4em 0; }

/* A two-column photo pair: <div class="pair"><figure>…</figure><figure>…</figure></div> */
.pair { display: grid; gap: 14px; margin: 26px 0; }
.pair figure { margin: 0; }
@media (min-width: 640px) { .pair { grid-template-columns: 1fr 1fr; } }

/* A collage of many small photos — the menu-board / drink-lineup shot. Each
   figure keeps its own caption, unlike .pair which is meant for exactly two. */
.collage {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  margin: 26px 0;
}
.collage figure { margin: 0; }
.collage img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius); }
.collage figcaption {
  margin-top: 5px;
  font-size: 12.5px;
  color: var(--muted);
  text-align: center;
}

/* A short verdict box: <div class="verdict"><strong>Worth it?</strong> …</div> */
.verdict {
  margin: 30px 0;
  padding: 18px 22px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-left: 4px solid var(--olive);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 16.5px;
}
.verdict strong { color: var(--olive); }

/* ------------------------------------------------ librarian's stars (rating) -- */

.stars { display: inline-flex; align-items: center; gap: 2px; line-height: 0; }
.stars svg { display: block; }

.rating {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 16px 0 4px;
  padding: 13px 17px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-left: 4px solid var(--gold);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.rating .ratingnum { font-size: 20px; font-weight: 700; color: var(--ink); }
.rating .ratingnum .of { font-size: 14px; font-weight: 400; color: var(--muted); }
.rating .ratinglabel {
  font-style: italic;
  color: var(--ink-soft);
  font-size: 16px;
}
.rating .ratinghelp {
  margin-left: auto;
  flex: none;
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--muted);
  font: 700 12px/18px -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  text-align: center;
  text-decoration: none;
}
.rating .ratinghelp:hover { border-color: var(--gold); color: var(--gold); }

.cardrating { margin: 9px 0 2px; }
.archstars { margin-left: auto; flex: none; line-height: 0; }

.ratingkey { border-collapse: collapse; margin: 16px 0 6px; width: 100%; }
.ratingkey td { padding: 8px 12px 8px 0; border-bottom: 1px dotted var(--line); vertical-align: middle; }
.ratingkey tr:last-child td { border-bottom: 0; }
.ratingkey .rk-num { color: var(--ink); width: 2.5em; }
.ratingkey td:last-child { color: var(--ink-soft); font-size: 15.5px; }
.half-note { font-size: 14.5px; color: var(--muted); font-style: italic; }

/* ---------------------------------------------------------------- sort bar -- */

.sortbar {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: center;
  margin: 0 0 26px;
  font: 13px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: var(--muted);
}
.sortbtn {
  font: inherit;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: all .15s;
}
.sortbtn:hover { border-color: var(--gold); color: var(--gold); }
.sortbtn.on { background: var(--gold); border-color: var(--gold); color: #0a0f1a; }

/* ------------------------------------------------------- write-in / respond -- */

.respond {
  margin: 38px 0 0;
  padding: 18px 22px;
  background: var(--paper-2);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: 16px;
}
.respond p { margin: 0; color: var(--ink-soft); }
.respond strong { color: var(--ink); }
.respond-actions { display: flex; gap: 12px; margin-top: 16px; flex-wrap: wrap; }
.respond-btn {
  flex: 1 1 180px;
  text-align: center;
  padding: 12px 20px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 14.5px;
  letter-spacing: .2px;
  text-decoration: none;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  transition: transform .12s ease, filter .12s ease;
}
.respond-btn:hover, .respond-btn:focus { filter: brightness(1.1); transform: translateY(-1px); }
.respond-btn:active { transform: translateY(0); }
.respond-btn-primary { background: var(--terra); color: #0a0f1a; box-shadow: var(--shadow); }
.respond-btn-secondary { background: transparent; border: 1px solid var(--terra); color: var(--terra-dk); }
/* Pinned explicitly rather than left to source order: the global `a:hover`
   rule above sets link text to var(--terra) on hover, and a bare pseudo-class
   selector outranks a single class in specificity no matter which comes
   later in the file. Without this, hovering the PRIMARY button (background
   is that same var(--terra)) set its text to match its own background —
   invisible text on hover, caught 2026-09-09. */
.respond-btn-primary:hover, .respond-btn-primary:focus { color: #0a0f1a; }
.respond-btn-secondary:hover, .respond-btn-secondary:focus { color: var(--terra-dk); }

.askform { display: flex; flex-direction: column; gap: 18px; }
.askform label {
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 15px;
  color: var(--ink);
}
.askform .opt, .askform .req { font-size: 13px; color: var(--muted); font-style: italic; }
.askform .req { color: var(--terra); }
.askform input[type="text"],
.askform input[type="email"],
.askform textarea {
  font: 16px/1.5 Georgia, serif;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 11px 13px;
  width: 100%;
}
.askform input:focus, .askform textarea:focus {
  outline: none;
  border-color: var(--terra);
  box-shadow: 0 0 0 3px rgba(194,94,58,.14);
}
.askform textarea { resize: vertical; min-height: 130px; }
.askform .btn {
  align-self: flex-start;
  font: 15px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  background: var(--terra);
  color: #0a0f1a;
  border: 0;
  border-radius: 999px;
  padding: 13px 26px;
  cursor: pointer;
  transition: background .15s;
}
.askform .btn:hover { background: var(--terra-dk); }
.askform .formnote { margin: 0; font-size: 13.5px; color: var(--muted); font-style: italic; }

/* ------------------------------------------------------------------ panels -- */

.panel {
  margin: 44px 0 0;
  padding: 26px 28px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.panel h2 { margin: 0 0 14px; font-size: 22px; font-weight: 400; }
.prose h2 { margin-top: 1.6em; }
.prose p { color: var(--ink-soft); }

.archive { list-style: none; margin: 0; padding: 0; }
.archive li {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px dotted var(--line);
}
.archive li:last-child { border-bottom: 0; }
.archive time {
  font: 12.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted);
  flex: none;
  min-width: 5.6em;
}
.archive a { text-decoration: none; }
.archive a:hover { text-decoration: underline; }
.archive .place { color: var(--muted); font-size: 14px; font-style: italic; }

.bookmarklist { list-style: none; margin: 30px 0 0; padding: 0; display: grid; gap: 16px; }
.bookmarklist li {
  padding: 18px 22px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.bookmarklist h3 { margin: 0 0 3px; font-size: 19px; font-weight: 400; color: var(--ink); }
.bookmarklist .place { display: block; color: var(--muted); font-size: 14px; font-style: italic; margin-bottom: 10px; }
.bookmarklist p { margin: 0; color: var(--ink-soft); font-size: 15.5px; }
.bookmarklist .added {
  display: inline-block;
  margin-top: 12px;
  font: 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted);
}
.bookmarklist a.visit {
  display: inline-block;
  margin-top: 12px;
  margin-left: 14px;
  font-size: 14px;
  color: var(--terra);
  text-decoration: none;
}
.bookmarklist a.visit:hover { text-decoration: underline; }

.bmphotos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  margin: 14px 0 4px;
}
.bmphotos img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--line);
}

a.directions {
  display: inline-block;
  font-size: 14px;
  color: var(--olive);
  text-decoration: none;
  border: 1px solid rgba(163,179,120,.4);
  border-radius: 20px;
  padding: 3px 12px;
}
a.directions:hover { border-color: var(--olive); text-decoration: none; }
.bookmarklist a.directions { margin-top: 12px; margin-right: 6px; }

.empty { text-align: center; color: var(--muted); padding: 40px 0; }
.empty code {
  font: 14px ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--paper-2);
  border: 1px solid var(--line);
  padding: 2px 6px;
  border-radius: 4px;
}

/* ---------------------------------------------------------------- post nav -- */

.postnav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  margin: 40px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-size: 15px;
}
.postnav a { text-decoration: none; max-width: 46%; }
.postnav a:hover { text-decoration: underline; }
.postnav .next { margin-left: auto; text-align: right; }

.backlink { margin-top: 26px; font-size: 15px; }
.backlink a { text-decoration: none; }
.backlink a:hover { text-decoration: underline; }

.pagehits {
  margin: 34px 0 0;
  color: var(--muted);
  font-size: 12.5px;
  text-align: center;
}

/* ------------------------------------------------------------------ footer -- */

.site-foot {
  margin-top: 60px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}
.site-foot p { margin: 0 0 10px; }
.site-foot a { color: var(--ink-soft); text-decoration: none; }
.site-foot a:hover { color: var(--terra); text-decoration: underline; }

/* --------------------------------------------------------------- narrow UI -- */

@media (max-width: 560px) {
  body { font-size: 16px; }
  .brand-name { font-size: 24px; }
  .lede h1, .post h1 { font-size: 27px; }
  .postbody { font-size: 17px; }
  .wrap { padding: 0 16px 56px; }
  .panel { padding: 20px 18px; }
  .postnav a { max-width: 100%; }
}

/* The other publication. Added 2026-08-07 — /travel/ and /finance/ now link to
   each other. The Bible project at the root is still linked from neither, and
   must stay that way (see README). */
.topnav a.sib, .mobmenu-panel a.sib { font-style: italic; opacity: .82; }
.topnav a.sib { border-color: transparent; }
.topnav a.sib:hover, .mobmenu-panel a.sib:hover { color: #5eb3d6; border-color: #2f4257; opacity: 1; }
.sibfoot { margin-top: .55rem; font-size: .82rem; opacity: .72; }

/* m8k mark (2026-10-10, Michael's choice): replaces the round Mister Library badge;
   links to m8k.io, which lists every publication. The 8 tips over into an infinity sign. */
.hublink .hubwm.m8kwm{background:none;-webkit-text-fill-color:currentColor;color:#e8eef7;
  font-family:Georgia,'Times New Roman',serif;font-size:27px;letter-spacing:-.01em;line-height:1}
.m8k8{display:inline-block;margin:0 .05em;color:#00ff9d;-webkit-text-fill-color:#00ff9d;
  text-shadow:0 0 6px rgba(0,255,157,.55),0 0 16px rgba(0,255,157,.35);animation:m8kLie 12s ease-in-out infinite}
@keyframes m8kLie{0%,17.5%{transform:rotate(0)}25%,42.5%{transform:rotate(90deg)}50%,67.5%{transform:rotate(180deg)}75%,92.5%{transform:rotate(270deg)}100%{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.m8k8{animation:none}}
@media (max-width:480px){.hublink .hubwm.m8kwm{display:inline-block}}
