@font-face {
  font-family: "DM Serif Display";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/dm-serif-display-400.woff2") format("woff2");
}

@font-face {
  font-family: "Lora";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/lora-400.woff2") format("woff2");
}

:root {
  --ink: #0a0a0a;
  --ink-muted: #585858; /* 7.1:1 on --paper, 5.5:1 on --paper-section — both clear WCAG AA's 4.5:1 (the peach bg is the binding case; #666666 passed white but only 4.44:1 on peach) */
  --paper: #ffffff;
  --paper-section: #f2dfce;
  /* A deeper shade of --paper-section, footer-only — every other section
     on the page (below-fold wraps, team cards, etc.) already uses
     --paper-section itself, so the footer blended into "just more page"
     instead of reading as its own closing zone. Deepest shade that keeps
     --ink-muted (the dimmest text color used here, on the policy links)
     still at 4.94:1 — #e6c8a8 one step darker drops that to 4.47:1,
     under WCAG AA's 4.5:1 floor for normal text. */
  --footer-bg: #ecd3ba;
  --rule: #e0e0e0;
  --accent: #8a1313;
  --accent-deep: #700c0c;

  --font-sans: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --heading-font: "DM Serif Display", Georgia, serif;
  --body-serif-font: "Lora", Georgia, serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

/* Every page's last block before the footer is a .below-fold section —
   let it absorb leftover viewport height so short pages don't trail off
   into blank white space before the footer. */
main > .below-fold:last-child {
  flex: 1 0 auto;
}

.site-footer {
  flex-shrink: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
}

.below-fold {
  background: var(--paper-section);
}

/* ---------- Header ---------- */

.site-header {
  background: var(--paper);
  padding: 28px 0 0;
}

.site-header-row {
  position: relative;
}

.wordmark {
  display: block;
  text-align: center;
  font-family: var(--heading-font);
  font-size: 2.3rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
}

.wordmark .accent {
  color: var(--accent);
}

/* Hamburger toggle — hidden entirely on desktop (.site-nav just shows
   as a normal row there, see below); on narrow viewports it sits over
   the wordmark's own row rather than taking a layout row of its own, so
   it doesn't push the logo off-center. */
.nav-toggle-btn {
  display: none;
}

/* The drawer's own logo header and the About/Advertise/Contact Us block
   only exist for the mobile off-canvas drawer — the desktop nav is just
   the plain category row, so both stay hidden there. */
.site-nav-drawer-head,
.site-nav-extra {
  display: none;
}

.site-nav-backdrop {
  display: none;
}

.site-nav {
  margin-top: 20px;
  border-bottom: 1px solid var(--rule);
}

.site-nav ul {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  justify-content: center;
  gap: 8px;
  list-style: none;
}

/* Scoped to the category list (`.site-nav ul a`), not just `.site-nav
   a` — the mobile drawer has two OTHER <a> tags living inside .site-nav
   (the logo in .site-nav-drawer-head, the About/Advertise/Contact Us
   links in .site-nav-extra) that must NOT pick up this padding; an
   unscoped `.site-nav a` here was stacking an extra 14px onto the
   drawer logo's own container padding and throwing its left edge out
   of alignment with the category links below it. */
.site-nav ul a {
  display: inline-block;
  padding: 14px;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  transition: color 0.15s ease;
}

.site-nav ul a:hover,
.site-nav ul a.active {
  color: var(--accent);
}

/* Below 960px the full single-row nav no longer fits without clipping
   an edge (measured live — 7 categories plus longer labels like
   "Transit & Safety" need that much room), so it collapses into a
   burger menu instead: categories stay in the DOM and in the page's
   link graph either way, just visually hidden until toggled open,
   rather than permanently eating vertical space above the fold on
   every single page. nav-toggle.js (vanilla JS, no framework) flips
   `.is-open`; CSS alone decides what that looks like. */
@media (max-width: 960px) {
  .site-header {
    /* Separates the header from whatever's directly below it (hero
       photo, article body) now that there's no longer always a nav row
       immediately under the logo providing that visual break. Top/bottom
       padding brought close to even — the unconditional 28px top (sized
       for the much taller desktop wordmark+nav stack) read as lopsided
       once the mobile header shrank to a single slim row. */
    padding-top: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--rule);
    /* Sticky only here — mobile's header is one slim logo row, cheap to
       keep pinned while scrolling; desktop's is a much taller
       logo+nav stack that would eat a lot more of the viewport
       permanently, which wasn't asked for and isn't worth the space. */
    position: sticky;
    top: 0;
    z-index: 40;
  }

  /* Logo pinned left — the plain centered-wordmark layout only works
     with a centered nav row under it; once that row is hidden behind a
     toggle, a left-aligned logo (matching the fixed-position toggle
     button over on the right, see below) is the familiar pattern. */
  .site-header-row {
    display: flex;
    align-items: center;
    padding: 0 24px;
  }

  .wordmark {
    display: inline-block;
    text-align: left;
    font-size: 1.5rem;
  }

  /* Fixed to the viewport (not flexed into the header row — see the
     markup comment in layout.js for why) at coordinates matched to
     where the header's own vertical center sits, so it still reads as
     part of that row even though it's a separate element. Sits in the
     sliver of screen the drawer deliberately doesn't cover, so it stays
     reachable as the same open/close control the whole time. */
  .nav-toggle-btn {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    gap: 4px;
    position: fixed;
    top: 26px;
    right: 24px;
    width: 26px;
    height: 20px;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    z-index: 60;
  }

  .nav-toggle-btn span {
    display: block;
    height: 2px;
    background: var(--ink);
    border-radius: 1px;
    transition: transform 0.2s ease, opacity 0.2s ease;
  }

  /* Morphs the three bars into an X once open — a cheap CSS-only cue
     that this same button also closes the menu. */
  .nav-toggle-btn[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(6px) rotate(45deg);
  }
  .nav-toggle-btn[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
  }
  .nav-toggle-btn[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-6px) rotate(-45deg);
  }

  /* Right-anchored off-canvas drawer, sliding right-to-left into view
     (same side as the toggle button that opens it, which sits at
     top:26/right:24 the whole time — closed, it's the burger; once the
     drawer is open it's sitting right at the drawer's own top corner,
     doubling as the X). Sized to most but not all of the screen width
     so a sliver of the dimmed page stays visible on the LEFT as a
     visual "there's more, tap to dismiss" cue. Slides via transform
     rather than the old max-height approach: covering the page instead
     of pushing it means nothing reflows underneath either way, but a
     transform slide reads as a drawer opening, where a height reveal
     reads as a dropdown — matches the mental model better for something
     this tall. */
  .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 82%;
    max-width: 320px;
    margin-top: 0;
    background: var(--paper);
    border-bottom: none;
    box-shadow: -4px 0 28px rgba(0, 0, 0, 0.18);
    transform: translateX(100%);
    transition: transform 0.28s ease;
    overflow-y: auto;
    z-index: 50;
    display: flex;
    flex-direction: column;
  }

  .site-nav.is-open {
    transform: translateX(0);
  }

  /* Dims/blocks the rest of the page while the drawer is open — also
     the click target for "tap outside to dismiss" (nav-toggle.js). */
  .site-nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(10, 10, 10, 0.4);
    z-index: 45;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.28s ease;
  }

  .site-nav-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
  }

  .site-nav-drawer-head {
    display: flex;
    align-items: center;
    padding: 20px 24px 16px;
    border-bottom: 1px solid var(--rule);
    flex-shrink: 0;
  }

  .site-nav-drawer-head .wordmark {
    font-size: 1.3rem;
  }

  .site-nav ul {
    flex-direction: column;
    gap: 0;
    padding: 4px 0;
    max-width: none;
    margin: 0;
  }

  .site-nav li {
    border-top: 1px solid var(--rule);
  }

  .site-nav li:first-child {
    border-top: none;
  }

  /* Scoped to the category list specifically (`.site-nav ul a`, not the
     broader `.site-nav a`) — the drawer also has two OTHER <a> tags
     inside .site-nav (the logo link in .site-nav-drawer-head, the
     About/Advertise/Contact Us links in .site-nav-extra), and a bare
     `.site-nav a` previously matched those too, stacking an unwanted
     extra 24px of padding on top of their own container's padding and
     throwing off the left alignment this very stylesheet is trying to
     keep consistent. */
  .site-nav ul a {
    display: block;
    padding: 14px 24px;
    text-align: left;
  }

  /* About/Advertise/Contact Us — pinned to the actual bottom of the
     drawer (margin-top: auto, inside .site-nav's flex column) as a
     footer strip, rather than sitting right under the category list
     with a fixed gap — no padding between the two groups, the auto
     margin is whatever space is left over instead of a set amount. One
     line with &middot; separators (same plain-text-flow convention as
     the footer's fine-print policy links), not one-per-row like the
     categories above — these are a lighter-weight, lower-priority
     group, and a single row says that without needing a smaller font
     to still fit the drawer's width. */
  .site-nav-extra {
    display: block;
    margin: auto 24px 16px;
    padding-top: 14px;
    border-top: 1px solid var(--rule);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ink-muted);
    text-align: center;
  }

  .site-nav-extra a {
    color: var(--ink-muted);
  }

  .site-nav-extra a:hover {
    color: var(--accent);
  }
}

/* ---------- Kicker / meta ---------- */

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.byline {
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-muted);
  margin-top: 6px;
}

/* ---------- Hero / featured (white zone) ---------- */

.hero {
  display: grid;
  grid-template-columns: 2.1fr 1fr;
  gap: 36px;
  padding: 32px 0 40px;
}

@media (max-width: 760px) {
  .hero {
    grid-template-columns: 1fr;
  }
}

.hero-art {
  aspect-ratio: 3 / 2;
  overflow: hidden;
}

.hero-headline {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 2.35rem;
  line-height: 1.18;
  margin: 16px 0 10px;
}

.hero-dek {
  font-size: 1.03rem;
  line-height: 1.5;
  margin: 0 0 12px;
}

.article-dek {
  max-width: 760px;
  font-size: 1.1rem;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0 0 12px;
}

.mission-statement {
  max-width: 700px;
  margin: 36px 0 8px;
  padding-left: 22px;
  border-left: 4px solid var(--accent);
  font-family: var(--heading-font);
  font-size: 1.55rem;
  line-height: 1.38;
  font-style: normal;
}

@media (max-width: 600px) {
  .mission-statement {
    font-size: 1.3rem;
    padding-left: 16px;
  }
}

.empty-note {
  padding: 60px 0;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 36px;
  padding-top: 24px;
  padding-bottom: 48px;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.pagination-link {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}

.pagination-link.is-disabled {
  color: var(--ink-muted);
  opacity: 0.5;
}

.pagination-status {
  font-size: 0.8rem;
  color: var(--ink-muted);
}

.side-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.side-list .card {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 14px;
  padding: 16px 0;
  border-top: 1px solid var(--rule);
}

.side-list .card:first-child {
  border-top: none;
  padding-top: 0;
}

.side-list .card .art {
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.side-list .card h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.08rem;
  line-height: 1.28;
  margin: 6px 0 0;
}

/* ---------- Section grid (peach zone) ---------- */

.section {
  padding: 36px 0;
}

.section + .section {
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 20px;
}

.section-head h2 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.5rem;
  margin: 0;
}

.section-head a {
  font-size: 0.82rem;
  color: var(--accent);
  font-weight: 700;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
}

@media (max-width: 760px) {
  .grid {
    grid-template-columns: 1fr;
  }
}

.grid .card .art {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  margin-bottom: 12px;
}

.grid .card h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.22;
  margin: 0 0 8px;
}

.grid .card p {
  font-size: 0.92rem;
  line-height: 1.5;
  margin: 0 0 8px;
}

/* ---------- "More Stories" — mobile-only compact list ---------- */

/* Two parallel renders of the same related-articles data (see
   article.js) — the desktop .grid (image on top, see above) and this
   compact photo-left/text-right list — shown one at a time by width
   rather than one shared markup shape reflowed, since the two layouts
   aren't actually the same DOM structure (the list needs a wrapper
   around title+dek to sit next to the photo; the grid doesn't). */
.more-stories-list {
  display: none;
}

@media (max-width: 760px) {
  .more-stories-grid {
    display: none;
  }

  .more-stories-list {
    display: flex;
    flex-direction: column;
  }

  .more-story-card {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 0;
    border-top: 1px solid var(--rule);
  }

  .more-story-card:first-child {
    border-top: none;
    padding-top: 0;
  }

  .more-story-art {
    flex: 0 0 100px;
    width: 100px;
    aspect-ratio: 1 / 1;
    overflow: hidden;
  }

  .more-story-body {
    flex: 1;
    min-width: 0;
  }

  .more-story-body .kicker {
    font-size: 0.66rem;
  }

  .more-story-body h3 {
    font-family: var(--heading-font);
    font-weight: 400;
    font-size: 1rem;
    line-height: 1.26;
    margin: 4px 0 4px;
  }

  .more-story-body p {
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--ink-muted);
    margin: 0;
    /* Clamps the dek to 2 lines — keeps every card the same compact
       height regardless of how long the excerpt runs. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* ---------- Category page ---------- */

.category-head {
  padding: 36px 0 8px;
}

.category-head h1 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 2.1rem;
  margin: 8px 0 8px;
}

.category-head p {
  max-width: 640px;
  line-height: 1.5;
}

/* ---------- Author page ---------- */

.author-profile {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: 24px;
  align-items: center;
}

@media (max-width: 600px) {
  .author-profile {
    grid-template-columns: 1fr;
    text-align: center;
  }
}

.author-avatar {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--heading-font);
  font-size: 2.2rem;
  flex-shrink: 0;
}

.author-avatar-photo {
  object-fit: cover;
}

.author-profile h1 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 2rem;
  margin: 6px 0 10px;
}

.author-email {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.85rem;
  color: var(--ink-muted);
  text-decoration: none;
}

.author-email:hover {
  color: var(--accent);
  text-decoration: underline;
}

.author-bio {
  max-width: 560px;
  line-height: 1.55;
  color: var(--ink-muted);
}

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 20px;
  margin-top: 20px;
}

.team-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  color: inherit;
  text-decoration: none;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: 32px 20px 24px;
  /* No transform/position change on hover — the card staying perfectly
     still is what makes the photo crossfade (pose swap) actually readable.
     Moving the card at the same time competed with it for attention and
     read as a flicker instead of a deliberate pose change. */
  transition: background-color 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.team-card:hover {
  /* A faint accent-tinted wash, not the page's own --paper-section peach —
     that would blend the card into the page background instead of
     reading as "this card is highlighted". */
  background: rgba(138, 19, 19, 0.045);
  box-shadow: 0 6px 18px rgba(10, 10, 10, 0.07);
  border-color: transparent;
}

.team-card-photo-wrap {
  display: block;
  position: relative;
  width: 100px;
  height: 100px;
  margin: 0 0 16px;
}

.team-card-photo {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--paper-section);
  box-sizing: border-box;
}

.team-card-photo-wrap .team-card-photo {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  transition: opacity 0.35s ease;
}

.team-card-photo-primary {
  opacity: 1;
}

.team-card-photo-alt {
  opacity: 0;
}

.team-card:hover .team-card-photo-primary {
  opacity: 0;
}

.team-card:hover .team-card-photo-alt {
  opacity: 1;
}

.team-card-photo-fallback {
  background: var(--accent);
}

.team-card-name {
  display: block;
  font-family: var(--heading-font);
  font-size: 1.15rem;
  color: inherit;
  text-decoration: none;
}

.team-card-name:hover {
  text-decoration: underline;
}

.team-card-title {
  margin-top: 2px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}

.team-card-rule {
  width: 28px;
  height: 2px;
  background: var(--accent);
  margin: 10px 0 12px;
  border: none;
}

.team-card-bio {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ink-muted);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.team-card-email {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.76rem;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}

.team-card-email:hover {
  color: var(--accent);
  text-decoration: underline;
}

.author-articles-head {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.4rem;
  margin: 0;
}

.list-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 32px;
  padding: 24px 0 56px;
}

@media (max-width: 700px) {
  .list-grid {
    grid-template-columns: 1fr;
  }
}

.list-grid .card .art {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  margin-bottom: 12px;
}

.list-grid .card h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.22;
  margin: 0 0 8px;
}

.list-grid .card p {
  font-size: 0.95rem;
  line-height: 1.55;
}

/* Everything past the first 4 articles on a category page — same
   3-per-row card used for the homepage's "Around the City"/spotlight
   grids (.grid itself, see above), just set off from the bigger
   list-grid cards above it with its own top rule + padding, the same
   divider treatment `.section + .section` uses elsewhere. */
.category-rest-grid {
  padding-top: 32px;
  padding-bottom: 56px;
  border-top: 1px solid var(--rule);
}

/* ---------- Article page ---------- */

.article-head {
  background: var(--paper);
  padding: 36px 0 20px;
}

.article-head h1 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 2.6rem;
  line-height: 1.16;
  margin: 14px 0 12px;
}

.article-byline {
  font-size: 0.85rem;
  color: var(--ink-muted);
}

.article-byline a {
  color: var(--ink);
  text-decoration: underline;
}

.article-hero {
  background: var(--paper);
  aspect-ratio: 21 / 9;
  overflow: hidden;
}

.share-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 0;
}

.share-row-end {
  justify-content: flex-end;
}

.share-row .label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.share-row a {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
}

.share-row a:hover {
  background: var(--accent);
}

.article-body-wrap {
  max-width: 700px;
  padding-bottom: 50px;
}

.article-body {
  font-family: var(--body-serif-font);
  font-size: 1.1rem;
  line-height: 1.7;
}

.article-body p {
  margin: 0 0 22px;
}

.article-body a {
  color: var(--accent);
  text-decoration: underline;
}

/* Deterministic "Originally reported by X" credit line (see
   articleLinker.js) — appended as a plain trailing <p> same as the rest
   of body_html, but set apart visually (small, sans-serif, muted, same
   recipe as .article-figure figcaption below) so it reads as a
   metadata tag, not another sentence of the actual story. */
.article-body p.source-credit {
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--ink-muted);
  margin-top: -4px;
}

.article-body p.source-credit a {
  color: var(--ink-muted);
  text-decoration: underline;
}

/* First use: a hand-assembled article with inline source charts/links
   (normally body_html is auto-generated plain <p> only — see
   articleGenerator.js's HOUSE_STYLE) — these rules give that figure/link
   markup somewhere real to render. */
.article-figure {
  margin: 8px 0 28px;
}

.article-figure img {
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
}

.article-figure figcaption {
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--ink-muted);
  margin-top: 8px;
  line-height: 1.4;
}

.page-body {
  max-width: 700px;
  font-family: var(--body-serif-font);
  font-size: 1.1rem;
  line-height: 1.7;
  padding: 28px 0 50px;
}

.page-body p {
  margin: 0 0 22px;
}

.page-body h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.3rem;
  margin: 32px 0 14px;
}

.page-body ul {
  margin: 0 0 22px;
  padding-left: 22px;
}

.page-body ul li {
  margin-bottom: 12px;
}

.page-body ul li:last-child {
  margin-bottom: 0;
}

.page-body table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-sans);
  font-size: 0.92rem;
}

.page-body table th,
.page-body table td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}

.page-body table code {
  font-size: 0.9em;
}

.link-accent {
  color: var(--accent);
  font-weight: 700;
}

.article-source {
  margin-top: 8px;
  padding: 16px 18px;
  background: var(--paper);
  border: 1px solid var(--rule);
  font-size: 0.85rem;
  font-family: var(--font-sans);
  color: var(--ink-muted);
}

/* ---------- Comments ---------- */

.comments-section {
  max-width: 700px;
}

.comment-list {
  list-style: none;
  margin: 0 0 28px;
  padding: 0;
}

.comment-thread {
  padding: 20px 0 28px;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.comment-thread:first-child {
  border-top: none;
  padding-top: 0;
}

.comment-thread:last-child {
  padding-bottom: 0;
}

.comment-toggle-replies {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 14px 0 0 24px;
  padding: 0;
  background: none;
  border: none;
  font-family: var(--font-sans);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
  cursor: pointer;
}

.comment-toggle-replies:hover {
  color: var(--accent);
}

.comment-toggle-icon {
  flex-shrink: 0;
  color: inherit;
  transition: transform 0.15s ease;
}

.comment-toggle-replies[aria-expanded="false"] .comment-toggle-icon {
  transform: rotate(-90deg);
}

/* Replies nest one step under their thread's top-level comment — a reply
   to a reply still lands here, flattened, never a third visual level. */
.comment-replies {
  list-style: none;
  margin: 10px 0 0 24px;
  padding: 10px 0 6px 20px;
  border-left: 2px solid rgba(138, 19, 19, 0.35);
}

.comment-reply + .comment-reply {
  margin-top: 16px;
}

.comment-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 6px;
}

/* Author, location and date used to fight for space on one line and
   wrap mid-element on a phone-width screen. Below 600px, the author
   name gets forced onto its own full-width line (flex-basis: 100% beats
   its own content width, so flex-wrap puts everything after it on the
   next line) — location and date then wrap together underneath it,
   tight against each other via the smaller row-gap. */
@media (max-width: 600px) {
  .comment-head {
    gap: 2px 10px;
  }

  .comment-author {
    flex-basis: 100%;
  }

  /* Whichever of location/date now starts the wrapped second line no
     longer needs its leading "· " — that dot existed to separate it
     from the author name, which pushed to its own line above. Targeted
     by "immediately follows .comment-author" rather than a blanket
     first-child rule, so the dot BETWEEN location and date (when both
     are present) is untouched — only the one at the very start of line
     two disappears, whichever element that turns out to be. */
  .comment-author + .comment-location::before,
  .comment-author + .comment-date::before {
    content: none;
  }
}

.comment-author {
  font-weight: 700;
  font-size: 0.92rem;
}

.comment-location {
  font-size: 0.78rem;
  color: var(--ink-muted);
}

.comment-location::before {
  content: "· ";
}

.comment-date {
  font-size: 0.78rem;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}

.comment-date:hover {
  color: var(--accent);
  text-decoration: underline;
}

.comment-date::before {
  content: "· ";
}

/* Lets a comment permalink (#comment-<id>) land below the sticky mobile
   header instead of right under it — see .site-header's position:sticky
   in the same @media block above. */
@media (max-width: 960px) {
  .comment {
    scroll-margin-top: 76px;
  }
}

.comment-body {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  line-height: 1.6;
  margin: 0;
}

.comment-reply-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
}

.comment-votes {
  display: flex;
  align-items: center;
  gap: 14px;
}

.comment-vote {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  color: var(--ink-muted);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s ease;
}

.comment-vote-icon {
  display: block;
  flex-shrink: 0;
}

@media (hover: hover) and (pointer: fine) {
  .comment-vote:not(:disabled):hover {
    color: var(--accent);
  }
}

/* Added by comments.js once IndexedDB confirms this browser already
   voted on this comment (or the server says so via a 409) — the voted
   direction stays highlighted, the OTHER button in the pair is just
   disabled/dimmed via :disabled below, not restyled, so it's clear which
   way the vote went. */
.comment-vote.is-voted {
  color: var(--accent);
  font-weight: 700;
}

.comment-vote.is-voted .comment-vote-icon {
  fill: var(--accent);
}

.comment-vote:disabled {
  cursor: default;
  opacity: 0.5;
}

.comment-reply-link {
  display: inline-block;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted);
  transition: color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .comment:hover .comment-reply-link {
    color: var(--accent);
  }
}

.comment-reply-notice {
  font-size: 0.85rem;
  color: var(--ink-muted);
  margin: 0 0 16px;
}

.comment-reply-notice strong {
  color: var(--ink);
}

.comment-reply-notice a {
  color: var(--accent);
  font-weight: 700;
}

.comment-empty {
  font-size: 0.92rem;
  color: var(--ink-muted);
  font-style: italic;
  margin: 0 0 28px;
}

.comment-form {
  padding-top: 28px;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.comment-form-title {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.4rem;
  margin: 0 0 20px;
}

.comment-form-row {
  margin-bottom: 18px;
}

.comment-form-row label {
  display: block;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 8px;
}

.comment-form-row input,
.comment-form-row textarea {
  width: 100%;
  padding: 13px 16px;
  background: var(--paper);
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--ink);
  resize: vertical;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.comment-form-row input::placeholder,
.comment-form-row textarea::placeholder {
  color: #b2b2b2;
}

.comment-form-row input:hover,
.comment-form-row textarea:hover {
  border-color: rgba(0, 0, 0, 0.2);
}

.comment-form-row input:focus,
.comment-form-row textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(138, 19, 19, 0.12);
}

.comment-form-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.comment-form-disclaimer {
  font-size: 0.8rem;
  color: var(--ink-muted);
  margin: 0;
}

.comment-form-disclaimer a {
  color: var(--accent);
}

.comment-hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.comment-form-error {
  background: var(--paper);
  border: 1px solid var(--accent);
  border-radius: 4px;
  color: var(--accent-deep);
  padding: 10px 14px;
  font-size: 0.88rem;
  margin: 0 0 16px;
}

.comment-submit {
  display: inline-block;
  background: var(--accent);
  color: var(--paper);
  border: none;
  border-radius: 4px;
  padding: 13px 30px;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: background 0.15s ease, transform 0.15s ease;
}

.comment-submit:hover {
  background: var(--accent-deep);
}

.comment-submit:active {
  transform: translateY(1px);
}

/* ---------- Newsletter ---------- */

.newsletter-band {
  background: var(--ink);
  color: var(--paper);
  padding: 34px 0;
}

.newsletter-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
}

.newsletter-copy h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.4rem;
  margin: 0 0 4px;
}

.newsletter-copy p {
  margin: 0;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.6);
}

.newsletter-form {
  flex: 1 1 380px;
  max-width: 480px;
}

.newsletter-fields {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.newsletter-fields input {
  flex: 1 1 160px;
  padding: 11px 14px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  color: var(--paper);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.newsletter-fields input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.newsletter-fields input:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.13);
}

.newsletter-fields button {
  flex: 0 0 auto;
  background: var(--accent);
  color: var(--paper);
  border: none;
  border-radius: 4px;
  padding: 11px 24px;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s ease;
}

.newsletter-fields button:hover {
  background: var(--accent-deep);
}

.newsletter-flash {
  margin: 10px 0 0;
  font-size: 0.82rem;
}

.newsletter-flash.is-success {
  color: #8fd19e;
}

.newsletter-flash.is-error {
  color: #ff9b9b;
}

.newsletter-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (max-width: 760px) {
  .newsletter-wrap {
    flex-direction: column;
    align-items: stretch;
    text-align: center;
  }

  .newsletter-form {
    flex-basis: auto;
    max-width: none;
  }
}

/* ---------- Subscribe confirmation modal ---------- */

.sc-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
  animation: sc-modal-fade-in 0.15s ease;
}

@keyframes sc-modal-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.sc-modal {
  background: var(--paper);
  max-width: 380px;
  width: 100%;
  padding: 36px 32px 28px;
  text-align: center;
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}

.sc-modal-message {
  font-family: var(--heading-font);
  font-size: 1.3rem;
  font-weight: 400;
  color: var(--ink);
  margin: 0 0 24px;
  line-height: 1.4;
}

.sc-modal-message.is-error {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--accent-deep);
}

.sc-modal-close {
  display: inline-block;
  background: var(--accent);
  color: var(--paper);
  border: none;
  border-radius: 4px;
  padding: 11px 28px;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s ease;
}

.sc-modal-close:hover {
  background: var(--accent-deep);
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--footer-bg);
  padding: 48px 0;
  text-align: center;
}

.site-footer .wordmark {
  font-size: 1.6rem;
  margin-bottom: 14px;
}

.site-footer-tagline {
  max-width: 480px;
  margin: 20px auto 0;
  font-size: 0.85rem;
  color: #4a4a4a;
  line-height: 1.6;
}

.site-footer-nav {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 20px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.site-footer-nav a:hover {
  color: var(--accent);
}

/* One visually distinct block below a divider, instead of a second
   nav row stacked directly under the first one with no clear boundary
   (the thing that read as confusing before) — a copyright line and four
   policy links, both unmistakably "fine print", not a second menu. On
   desktop they sit side by side (copyright left, policy links right,
   the common convention for this exact pairing); narrow screens don't
   have the width for that, so they stack back to centered, same as the
   rest of the footer. */
.site-footer-fine-print {
  margin-top: 32px;
  padding-top: 26px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px 24px;
  text-align: left;
  /* var(--rule) itself (#e0e0e0) nearly vanished here — 1.09:1 against
     the new --footer-bg, versus the 1.32:1 this same divider convention
     already gets on white elsewhere. A translucent black instead of a
     fixed gray adapts to whatever it's drawn on, landing close to that
     same established subtlety (~1.35:1) regardless of background. */
  border-top: 1px solid rgba(10, 10, 10, 0.15);
}

.site-footer-fine-print p {
  max-width: 480px;
  margin: 0;
  font-size: 0.85rem;
  color: #4a4a4a;
  line-height: 1.6;
}

/* Plain text flow with literal &middot; separators (same convention as
   bylines/kickers elsewhere) rather than flex+pseudo-elements — normal
   inline text wrapping puts even space on both sides of each dot for
   free, no margin/gap arithmetic to get wrong. */
/* Specificity has to beat .site-footer-fine-print p (one class + one
   element) above, or that rule's font-size/color/margin would win over
   this more specific intent despite coming first in the file — so this
   repeats the parent class rather than relying on !important. */
.site-footer-fine-print p.site-footer-legal {
  margin: 0;
  font-size: 0.72rem;
  text-align: right;
  /* var(--ink-muted), not a darker/lighter ad-hoc gray: already
     documented as 5.5:1 against this exact background, clearing WCAG
     AA's 4.5:1 floor for normal text while still reading quieter than
     the bold uppercase nav above. */
  color: var(--ink-muted);
}

@media (max-width: 640px) {
  .site-footer-fine-print {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .site-footer-fine-print p {
    margin: 0 auto;
  }

  .site-footer-fine-print p.site-footer-legal {
    margin-top: 4px;
    text-align: center;
  }
}

/* Underlined on purpose, unlike the main nav above — these links sit
   inside a block of plain-looking small text (the copyright line right
   next to them uses the same size/color), so an underline is what marks
   them as clickable at a glance instead of blending into fine print. */
.site-footer-legal a {
  color: var(--ink-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.site-footer-legal a:hover {
  color: var(--ink);
}

/* ---------- Tourist guide ---------- */

.tg-list {
  display: flex;
  flex-direction: column;
  gap: 56px;
  padding: 36px 0 56px;
}

.tg-stop {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  align-items: center;
}

.tg-stop:nth-child(even) .tg-stop-art {
  order: 2;
}

@media (max-width: 760px) {
  .tg-stop {
    grid-template-columns: 1fr;
  }
  .tg-stop:nth-child(even) .tg-stop-art {
    order: 0;
  }
}

.tg-stop-art {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 4px;
}

.tg-stop-body h2 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.9rem;
  line-height: 1.2;
  margin: 10px 0 12px;
}

.tg-stop-body p {
  font-size: 1rem;
  line-height: 1.6;
  margin: 0 0 12px;
}

.tg-credit {
  font-size: 0.72rem;
  color: var(--ink-muted);
  font-style: italic;
}

.tg-tips {
  background: var(--paper);
  border: 1px solid var(--rule);
  padding: 28px 32px 32px;
  margin-bottom: 44px;
}

.tg-tips h3 {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.3rem;
  margin: 0 0 18px;
}

.tg-tips-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px 32px;
  font-size: 0.92rem;
  line-height: 1.55;
}

@media (max-width: 700px) {
  .tg-tips-grid {
    grid-template-columns: 1fr;
  }
}

.tg-crosslink {
  text-align: center;
  padding-bottom: 50px;
  font-size: 1rem;
}

/* ---------- 404 ---------- */

.notfound-art {
  max-width: 1100px;
  margin: 0 auto;
}

.notfound-body {
  padding: 36px 0 56px;
}

.notfound-home {
  margin-bottom: 8px;
}

.notfound-lead {
  margin-bottom: 20px;
  color: var(--ink-muted);
}

/* ---------- Homepage "More Headlines" (grouped by category, no hero art) ---------- */

/* One panel per category — each panel states its category once in the
   heading, so individual links below don't need a repeated kicker label. */
.brief-groups {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}

@media (max-width: 900px) {
  .brief-groups {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .brief-groups {
    grid-template-columns: 1fr;
  }
}

.brief-group-title {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 1.08rem;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--accent);
}

.brief-group-title a:hover {
  color: var(--accent);
}

.brief-link-item {
  padding: 10px 0;
  border-top: 1px solid var(--rule);
}

.brief-link-item:first-child {
  border-top: none;
  padding-top: 0;
}

.brief-link-item a {
  font-family: var(--heading-font);
  font-weight: 400;
  font-size: 0.98rem;
  line-height: 1.32;
  display: block;
}

.brief-link-item a:hover {
  color: var(--accent);
}

.brief-link-item .byline {
  margin-top: 3px;
}

.notfound-sections {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-weight: 700;
  font-size: 0.95rem;
}
