/* ---------- Theme tokens ---------- */
:root {
  color-scheme: light;
  --page: #fdf8f0;
  --surface: #ffffff;
  --ink: #2b2118;
  --ink-2: #5f5548;
  --muted: #736859; /* 5.45:1 on white, 5.15:1 on --page — #9a8f80 was 3.17 and failed WCAG AA for the small labels that use it */
  --hairline: #f0e5d4;
  --border: rgba(60, 40, 20, 0.10);
  --accent: #f4743b;
  --accent-text: #a94617; /* the accent as small text: #f4743b is 2.83:1 on white; this is 5.87:1 on white, 4.83:1 on --accent-soft */
  --accent-2: #12a5a0;
  --accent-soft: #ffe4d1;
  --good: #157a37; /* 5.43:1 on white — #1a8f3c was 4.17:1 as the month table's "Good" text */
  --sun: #ffc247;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --page: #191412;
    --surface: #242019;
    --ink: #fff7ec;
    --ink-2: #d8c9b4;
    --muted: #9a8f80;
    --hairline: #362f26;
    --border: rgba(255, 220, 180, 0.12);
    --accent: #ff8b52;
    --accent-text: #ff8b52;
    --accent-2: #2fc4be;
    --accent-soft: #5a2f14;
    --good: #3ecf6a;
    --sun: #ffc247;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --page: #191412;
  --surface: #242019;
  --ink: #fff7ec;
  --ink-2: #d8c9b4;
  --muted: #9a8f80;
  --hairline: #362f26;
  --border: rgba(255, 220, 180, 0.12);
  --accent: #ff8b52;
  --accent-text: #ff8b52;
  --accent-2: #2fc4be;
  --accent-soft: #5a2f14;
  --good: #3ecf6a;
  --sun: #ffc247;
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background:
    radial-gradient(900px 420px at 85% -60px, rgba(255, 194, 71, 0.16), transparent 70%),
    radial-gradient(700px 380px at -60px 30%, rgba(18, 165, 160, 0.08), transparent 70%),
    var(--page);
  background-attachment: fixed;
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.55;
  font-size: 16px;
}
a { color: var(--accent-text); text-decoration: none; }
/* A link inside running text needs more than colour to stand out from the words around it (WCAG 1.4.1). */
p a:not([class]) { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: from-font; }
a:hover { text-decoration: underline; }
.wrap { max-width: 960px; margin: 0 auto; padding: 0 20px; }

/* Tap targets.
   Several links are plain text at 15-21px tall — well under the ~44px a
   fingertip needs. Where there's room the fix is real padding (see
   .activity-main), but the header nav, the hero breadcrumb and the city names
   on country cards are all size-constrained: padding them out would undo the
   compact header or reflow the cards. These grow the *hit area* with a
   transparent overlay instead, so the target gets bigger and nothing moves.
   Kept off .country-cities a::after, which is already the "·" separator. */
.site-nav a,
.hero .crumb a,
.country-cities a { position: relative; }
.site-nav a::before,
.hero .crumb a::before,
.country-cities a::before {
  content: "";
  position: absolute;
  inset: -12px -4px;
}
/* City names sit flush against each other (the "·" separator is part of the
   preceding link's own box) and 10px above the "View more" button, so this one
   gets a tighter overlay: -4px sideways made neighbouring names overlap by 8px
   and -12px down covered the button's top edge. 41px, and every tap
   unambiguous, beats 45px with contested edges. */
.country-cities a::before { inset: -10px 0; }

/* ---------- Country-page jump dropdown ---------- */
.page-jump {
  display: flex;
  justify-content: flex-end;
  margin: 14px 0 0;
}

/* ---------- Site header ---------- */
.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 0;
}
.site-header .brand {
  font-weight: 800;
  font-size: 18px;
  color: var(--ink);
  letter-spacing: -0.01em;
  margin-right: auto;
}
.site-header .brand::before { content: "🧭 "; }
.site-header .brand:hover { text-decoration: none; color: var(--accent-text); }
.site-nav { display: flex; gap: 14px; }
.site-nav a { color: var(--ink-2); font-size: 13px; font-weight: 600; }
.site-nav a:hover { color: var(--accent-text); }
.theme-btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 6px 14px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.theme-btn:hover { color: var(--accent-text); border-color: var(--accent); }
.currency-select {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.currency-select:hover { border-color: var(--accent); color: var(--accent-text); }
.btn-label-short { display: none; }

/* Narrow header: left to wrap on its own it takes four rows and eats ~23% of
   the first screen before any content shows. Pin it to two — controls share
   line one with the brand, nav links get line two.

   Applied from 800px down, not 640: between those the flex version still
   wrapped into two ragged rows (112px at 700px, with the currency select and
   theme button orphaned below the nav), which is where narrow laptops and
   landscape phones sit. The structure is the same across the whole band; only
   the shrinking below is phone-specific. */
@media (max-width: 800px) {
  /* Explicit grid rather than flex-wrap: wrapping depends on the pixel width
     of the sign-in label, which changes once a user signs in, so the row count
     was not stable. The grid pins it at two rows regardless. */
  .site-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "brand auth  theme"
      "nav   nav   cur";
    padding: 10px 0 10px;
    gap: 8px;
    border-bottom: 1px solid var(--hairline);
  }
  .site-header .brand {
    grid-area: brand;
    min-width: 0;
    margin-right: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .auth-slot { grid-area: auth; justify-self: end; }
  .currency-select { grid-area: cur; justify-self: end; }
  .theme-btn { grid-area: theme; }
  .site-nav {
    grid-area: nav;
    align-items: center;
    gap: 14px;
  }
  .site-nav a { white-space: nowrap; }
}

/* Phones only: the labels and controls also have to shrink to fit one line. */
@media (max-width: 640px) {
  .site-header .brand { font-size: 14px; }
  .site-nav { gap: 14px; }
  .site-nav a { font-size: 12px; }
  .theme-btn,
  .currency-select,
  .auth-btn { padding: 5px 10px; font-size: 12px; }
  .currency-select { padding: 5px 8px; }
  .theme-btn { padding: 5px 9px; font-size: 15px; line-height: 1.1; }
  .btn-label-full { display: none; }
  .btn-label-short { display: inline; }
  /* Signed in, the slot is avatar + name + "Sign out" — wide enough to push
     the brand into an ellipsis. The avatar already identifies the account, so
     the name drops on phones. */
  .auth-user { gap: 6px; }
  .auth-user .auth-name { display: none; }
}

/* ---------- Auth ---------- */
.auth-slot { display: flex; align-items: center; }
.auth-btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  border-radius: 999px;
  padding: 6px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.auth-btn:hover { border-color: var(--accent); color: var(--accent-text); }
.auth-user { display: flex; align-items: center; gap: 8px; }
.auth-user .avatar { width: 24px; height: 24px; border-radius: 50%; }
.auth-user .auth-name { font-size: 13px; color: var(--ink-2); max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Save button (city hero) ---------- */
.save-btn {
  align-self: flex-start;
  margin-top: 14px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  border-radius: 999px;
  padding: 7px 16px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease;
}
.save-btn:hover { background: rgba(255, 255, 255, 0.26); transform: scale(1.04); }
.save-btn.is-saved { background: var(--sun); color: #2b2118; border-color: var(--sun); }
.save-count { align-self: flex-start; margin-top: 8px; font-size: 12px; color: rgba(255, 255, 255, 0.75); }
.save-count:empty { display: none; }

/* Been there / Want to go — same glass pill as Save, a size down, so Save
   stays the primary action in the hero. */
.stamp-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; align-self: flex-start; }
.stamp-btn {
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
  border-radius: 999px;
  padding: 5px 13px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease;
}
.stamp-btn:hover { background: rgba(255, 255, 255, 0.24); transform: scale(1.04); }
.stamp-btn.is-on { background: #ffffff; color: #2b2118; border-color: #ffffff; }

/* ---------- Home-page community panel ---------- */
.community { margin-top: 28px; }
.community-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.community-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--page);
  color: var(--ink);
  transition: border-color 120ms ease, transform 120ms ease;
}
.community-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.community-card strong { font-size: 16px; }
.community-card span { font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.community-icon { font-size: 22px; line-height: 1; }
.community-card .community-go { margin-top: auto; padding-top: 6px; font-weight: 700; color: var(--accent-text); }
.community-foot { margin: 14px 0 0; }
@media (prefers-reduced-motion: reduce) { .community-card { transition: none; } }

/* Visit details under the hero stamps */
.visit-details { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; align-self: flex-start; }
.visit-details[hidden] { display: none; }
.visit-q { font-size: 12px; font-weight: 700; color: rgba(255, 255, 255, 0.85); margin-left: 4px; }
.visit-q:first-child { margin-left: 0; }
.visit-details select {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  height: 28px;
  padding: 0 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(0, 0, 0, 0.35);
  color: #ffffff;
}
.visit-details select option { color: #2b2118; background: #ffffff; }

/* Passport sharing */
.passport-share { margin-top: 28px; }
.passport-link-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.passport-link-row input {
  flex: 1 1 260px;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
}
.passport-cta { margin-top: 24px; }

/* ---------- Itineraries ---------- */
.itin-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 16px; }
.itin-tab {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-2);
  border-radius: 999px;
  padding: 7px 16px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.itin-tab:hover { border-color: var(--accent); color: var(--accent-text); }
.itin-tab.active { border-color: var(--accent); color: var(--accent-text); background: var(--accent-soft); }
.itin-plan[hidden] { display: none; }
.itin-plan > p { margin: 0 0 14px; }
.itin-days { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.itin-days li {
  position: relative;
  padding: 12px 14px 12px 16px;
  border-left: 3px solid var(--accent-soft);
  background: var(--page);
  border-radius: 0 10px 10px 0;
  font-size: 15px;
  line-height: 1.6;
}
.itin-when {
  display: block;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 2px;
}

/* ---------- Scam reports ---------- */
.scam-list li { margin-bottom: 10px; }
.scam-report { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.scam-btn {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-2);
  border-radius: 999px;
  padding: 4px 11px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.scam-btn:hover { border-color: var(--accent); color: var(--accent-text); }
.scam-btn.is-on { background: var(--accent); border-color: var(--accent); color: #ffffff; }
.scam-count:empty { display: none; }

/* ---------- Price check-ins ---------- */
.price-check[hidden] { display: none; }
.pc-rows { display: grid; gap: 12px; margin-top: 14px; }
.pc-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px 16px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
}
.pc-what { display: flex; flex-direction: column; gap: 2px; }
.pc-label { font-size: 13px; color: var(--ink-2); }
.pc-price { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pc-btns { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.pc-btn {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink);
  border-radius: 999px;
  padding: 6px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.pc-btn:hover { border-color: var(--accent); color: var(--accent-text); }
.pc-btn.is-on { background: var(--accent); border-color: var(--accent); color: #ffffff; }
.pc-status, .pc-paid { grid-column: 1 / -1; margin: 0; }
.pc-paid { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
.pc-paid label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.pc-paid input {
  font: inherit;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
  width: 200px;
}
@media (max-width: 640px) {
  .pc-row { grid-template-columns: 1fr; }
  .pc-btns { justify-content: flex-start; }
}

/* ---------- /vs/ poll ---------- */
.vs-poll-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.vs-poll-btn {
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  border-radius: 12px;
  padding: 12px 10px;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 120ms ease, transform 120ms ease;
}
.vs-poll-btn:hover { border-color: var(--accent); transform: translateY(-1px); }
.vs-poll-btn.is-on { border-color: var(--accent); background: var(--accent); color: #ffffff; }
.vs-poll-pct { font-variant-numeric: tabular-nums; opacity: 0.85; }
.vs-poll-bar {
  height: 8px;
  margin-top: 12px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}
.vs-poll-bar[hidden] { display: none; }
.vs-poll-bar span { display: block; height: 100%; background: var(--accent); transition: width 400ms ease; }
.vs-poll-note { margin: 10px 0 0; }
.stamp.is-visited { border-style: double; border-width: 4px; }
@media (prefers-reduced-motion: reduce) {
  .stamp-btn, .vs-poll-btn, .vs-poll-bar span { transition: none; }
}

/* ---------- Suggest-a-country form ---------- */
.request-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  box-sizing: border-box;
}
#request-form .auth-btn { margin-top: 10px; }
#request-form .sub { margin: 8px 0 0; }

/* ---------- Index: intro ---------- */
.intro { margin: 20px 0 8px; }
.intro h1 {
  font-size: 34px;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
  background: linear-gradient(95deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  width: fit-content;
}
.intro p { color: var(--ink-2); max-width: 620px; margin: 0; }
.intro-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.country-select {
  flex: 0 0 auto;
  margin-top: 6px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.country-select:hover { border-color: var(--accent); color: var(--accent-text); }
@media (max-width: 640px) {
  .country-select { width: 100%; }
}

/* ---------- Index: city cards ---------- */
.city-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
  margin: 20px 0;
}
.city-card,
.country-card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  overflow: hidden;
  color: inherit;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
}
.city-card:hover {
  text-decoration: none;
  transform: translateY(-4px) rotate(-0.4deg);
  box-shadow: 0 14px 32px rgba(244, 116, 59, 0.18);
  border-color: var(--accent);
}
.country-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 14px 32px rgba(244, 116, 59, 0.14);
  border-color: var(--accent);
}
.country-card a.banner:hover { text-decoration: none; filter: brightness(1.08); }
.country-cities {
  border-top: 1px solid var(--hairline);
  margin-top: 10px;
  padding-top: 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}
.country-cities a {
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
}
.country-cities a:hover { color: var(--accent-text); text-decoration: none; }
.country-cities a:not(:last-child)::after {
  content: "·";
  color: var(--muted);
  font-weight: 400;
  margin: 0 6px;
}
.country-cities .bud { display: none; }
.view-more-btn {
  display: block;
  text-align: center;
  margin-top: 10px;
  padding: 7px;
  border-radius: 10px;
  background: var(--page);
  color: var(--accent-text);
  font-size: 13px;
  font-weight: 700;
}
.view-more-btn:hover { background: var(--accent-soft); text-decoration: none; }
.city-card .banner.has-photo { height: 156px; }
.country-card .banner.has-photo { height: 110px; }
.city-card .banner,
.country-card .banner {
  height: 88px;
  display: flex;
  align-items: flex-end;
  padding: 12px 16px;
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.city-card .banner .flag,
.country-card .banner .flag { font-size: 26px; margin-right: 10px; }
.city-card .banner h2,
.country-card .banner h2 { margin: 0; font-size: 21px; letter-spacing: -0.01em; }
.city-card .banner .country,
.country-card .banner .country { font-size: 13px; opacity: 0.9; display: block; margin-top: -2px; }
.city-card .body,
.country-card .body { padding: 12px 16px 14px; }
.city-card .tagline,
.country-card .tagline { color: var(--ink-2); font-size: 14px; margin: 0 0 12px; }
/* Taglines run 140-190 characters and a two-line clamp cut most of them
   mid-phrase ("...morna music drifting from..."), which reads as broken text
   rather than as a summary. They're shown in full instead. The clamp was
   holding the city list and CTA on a shared baseline across each row; the
   flex column below does that job without touching the copy. */
/* The bottom margin is the minimum gap; margin-top:auto below only ever adds
   to it, so a tall tagline never butts against the city list's rule. */
.country-card .tagline { margin: 0 0 10px; }
.country-card { display: flex; flex-direction: column; }
.country-card .body { flex: 1; display: flex; flex-direction: column; }
.country-card .country-cities { margin-top: auto; }
.card-stats { display: flex; gap: 0; border-top: 1px solid var(--hairline); padding-top: 10px; }
.card-stats div { flex: 1; }
.card-stats .lbl { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.card-stats .val { font-size: 14px; font-weight: 600; }

/* ---------- Index: budget comparison ---------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 20px;
  margin: 28px 0;
}
.panel h2 { margin: 0 0 4px; font-size: 19px; letter-spacing: -0.01em; }
.panel .sub { color: var(--muted); font-size: 13px; margin: 0 0 16px; }

/* ---------- Home: "Where should I go?" picker ---------- */
/* Three controls on one row on a wide screen, stacked on a phone. The budget
   field is the one that wants room, so it takes the slack while the two
   selects hold a readable minimum. */
.pk-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 16px;
  margin-bottom: 4px;
}
/* min-width:0 because a <select> is as wide as its widest option, and a flex
   item won't shrink below its content by default — "Türkiye & the Middle East"
   would otherwise hold both selects at full width and force every field onto
   its own row. */
.pk-field { display: flex; flex-direction: column; gap: 5px; flex: 1 1 150px; min-width: 0; }
.pk-field-budget { flex: 2 1 280px; }
/* Matches the select height so all three labels sit on one line — the budget
   field's control row is shorter than a select, and bottom-aligning the
   fields would otherwise drop its label a few pixels below the others. */
.pk-field-budget .bf-controls { min-height: 40px; align-items: center; }
.pk-field > label {
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
}
.pk-field select {
  font: inherit;
  font-size: 14px;
  width: 100%;
  min-width: 0;
  /* Room on the right for the native chevron, so a long option name
     ("Türkiye & the Middle East") truncates clear of it rather than under it. */
  padding: 8px 26px 8px 10px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  /* Matches the 44px tap target used elsewhere without making the desktop
     row look chunky. */
  min-height: 40px;
}
.pk-field select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.bf-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 10px;
}
.bf-label { color: var(--ink-2); font-size: 14px; }
.bf-value {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent-text);
  /* Reserved width so the row doesn't jitter as the number changes length
     while dragging — "$25" and "$200+" must occupy the same space. */
  min-width: 84px;
}
.bf-per { color: var(--ink-2); font-size: 14px; margin-left: -4px; }
#bf-range {
  flex: 1 1 220px;
  min-width: 160px;
  accent-color: var(--accent);
  height: 32px;
  cursor: pointer;
}
.bf-count {
  color: var(--muted);
  font-size: 13px;
  margin: 0 0 10px;
  padding-top: 10px;
  border-top: 1px solid var(--hairline);
}
/* Photo cards, replacing the old 106-row text list in a scrollbox — the
   single biggest "reads like a database" offender on the site. Two-ish rows
   render by default (CARD_LIMIT in app.js) with a Show-all button, so the
   country cards below stay within reach without an inner scrollbar. */
.bf-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 14px;
}
.bf-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
  color: inherit;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.bf-card:hover {
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.bf-card:hover .bf-card-name { color: var(--accent-text); }
.bf-card-photo {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--page);
}
.bf-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bf-card-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px 12px;
}
.bf-card-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.bf-card-name { font-size: 15px; font-weight: 700; }
.bf-card-budget { flex: none; font-size: 13px; font-weight: 700; color: var(--ink-2); }
.bf-card-per { font-weight: 400; font-size: 11px; color: var(--muted); }
/* Country plus the months the city is at its best — the one thing the picker
   knows that the country cards below don't. */
.bf-card-meta { font-size: 12px; color: var(--muted); }
.bf-card-hook {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bf-more {
  grid-column: 1 / -1;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--accent-text);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}
.bf-more:hover { background: var(--page); }
.bf-empty { color: var(--ink-2); font-size: 14px; margin: 0; }
@media (max-width: 640px) {
  .bf-results { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
  .bf-card-hook { display: none; }
  .bf-value { font-size: 19px; min-width: 74px; }
  /* Matches the 44px tap target the rest of the site now uses. */
  #bf-range { height: 44px; }
  .pk-field select { min-height: 44px; }
  .pk-controls { gap: 12px; }
  /* When and Where are short enough to share a row on a phone; only the
     budget field takes a line of its own. Stacking all three pushed the first
     result most of a screen down. */
  .pk-field { flex: 1 1 110px; }
  .pk-field-budget { flex: 1 0 100%; }
}
.budget-row {
  display: grid;
  grid-template-columns: 110px 1fr 90px;
  align-items: center;
  gap: 12px;
  padding: 5px 0;
}
.budget-row .name { font-size: 14px; color: var(--ink-2); white-space: nowrap; }
.budget-row .track { position: relative; height: 14px; }
.budget-row .bar {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, var(--sun), var(--accent));
  border-radius: 999px;
  min-width: 3px;
}
.budget-row .val {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
}
.budget-row .val .range { color: var(--muted); font-weight: 400; }

/* ---------- Tables ---------- */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
  padding: 6px 10px;
  border-bottom: 1px solid var(--hairline);
}
td { padding: 8px 10px; border-bottom: 1px solid var(--hairline); vertical-align: top; }
tr:last-child td { border-bottom: none; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.muted { color: var(--ink-2); }
.table-scroll { overflow-x: auto; }

/* Sticky column headers for the long comparison tables.
   Two things have to be true for this to work, and neither is obvious.

   First, position:sticky binds to the nearest scrolling ancestor, and setting
   overflow-x:auto silently makes overflow-y compute to auto as well — so
   .table-scroll was itself the scroll container. Because it has no height
   limit it never scrolls vertically, and a sticky thead inside it simply never
   moved. Dropping the overflow at widths where the table fits makes the
   viewport the container again.

   Second, the table only fits once the headers stop forcing it wider than the
   page: th.num inherited white-space:nowrap, and "Avg. monthly salary" on one
   line pushed the table to 1024px inside a 920px column. Letting headers wrap
   (while the figures keep their nowrap) brings it to exactly 920px.

   Below 980px the table genuinely cannot fit and stays a horizontal scroller,
   which means no sticky header there — that needs the mobile table rethink,
   not a bigger sticky rule. */
.table-scroll th.num { white-space: normal; }
/* Seven columns land ~7px over the 920px column at the default padding, which
   spills into the page gutter. A pixel off each side settles it inside. */
.table-scroll th,
.table-scroll td { padding-left: 9px; padding-right: 9px; }
.table-scroll th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  /* border-collapse:collapse leaves borders behind when a cell sticks, so the
     rule under the header is drawn as an inset shadow instead. */
  border-bottom: none;
  box-shadow: inset 0 -1px 0 var(--hairline);
}
@media (min-width: 980px) {
  .table-scroll { overflow-x: visible; }
}

/* ---------- Cost comparison pages ---------- */
.region-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 4px;
}
.region-nav a,
.region-nav .is-current {
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
}
.region-nav a { color: var(--ink-2); }
.region-nav a:hover { border-color: var(--accent); color: var(--accent-text); text-decoration: none; }
.region-nav .is-current { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); }
.lede { font-size: 15.5px; line-height: 1.55; margin: 0; }
.rank-country { font-size: 12px; color: var(--muted); margin-top: 1px; }

/* Relative-cost bar under each daily-budget figure, scaled to the priciest
   city in the current view. */
.cost-bar {
  height: 4px;
  min-width: 90px;
  margin-top: 5px;
  border-radius: 2px;
  background: var(--hairline);
  overflow: hidden;
}
.cost-bar span {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--accent);
}

/* Under 640px the ranked table becomes a stack of cards: seven columns on a
   phone meant four of them lived behind a horizontal scroll nobody found.
   Each row is a grid — rank and city name across the top, then each figure
   as its own labelled line, the label drawn from the cell's data-label since
   the real headers are display:none here. */
@media (max-width: 640px) {
  .rank-table thead { display: none; }
  .rank-table, .rank-table tbody { display: block; }
  .rank-table tr {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 10px;
    align-items: center;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    padding: 12px 14px;
    margin-bottom: 10px;
  }
  .rank-table td { display: block; border-bottom: none; padding: 2px 0; }
  .rank-table td.rank-num {
    font-size: 13px;
    font-weight: 700;
    color: var(--muted);
  }
  .rank-table td.rank-num::before { content: "#"; }
  .rank-table td.num {
    grid-column: 1 / -1;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 4px 0;
  }
  .rank-table td.num::before {
    content: attr(data-label);
    font-size: 12px;
    font-weight: 400;
    color: var(--muted);
    font-variant-numeric: normal;
    white-space: nowrap;
  }
  .rank-table td.rank-city { padding-bottom: 6px; }
  .rank-table td.rank-city + td.num { border-top: 1px solid var(--hairline); margin-top: 4px; padding-top: 8px; }
  .rank-table .cost-bar { display: none; }
}

/* ---------- City page: hero ---------- */
.hero {
  border-radius: 16px;
  color: #ffffff;
  padding: 32px 28px 24px;
  margin-top: 8px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.hero.has-photo {
  /* 340px was under 4% of a typical 8,400px guide. 420 is still a small slice
     but reads as a photograph you arrived at rather than a coloured header. */
  min-height: 420px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.hero .crumb { font-size: 13px; opacity: 0.85; }
.hero .crumb a { color: #ffffff; }
.hero h1 { margin: 6px 0 2px; font-size: 36px; letter-spacing: -0.02em; }
.hero .flag { margin-right: 10px; }
.hero .country { font-size: 15px; opacity: 0.9; }
.hero .tagline { margin: 10px 0 0; max-width: 560px; font-size: 15px; opacity: 0.95; }

/* ---------- City page: boarding-pass snapshot ----------
   The five headline figures used to be plain KPI tiles; they're now dressed
   as the document every trip starts with. Same data, same reading order. The
   .val prices stay $-anchored text so the currency converter wraps and
   reformats them like every other figure on the page. */
.bpass {
  display: flex;
  margin: 16px 0 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
}
.bpass-main { flex: 1; min-width: 0; padding: 14px 18px 12px; }
.bpass-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.bpass-route { display: flex; align-items: center; gap: 16px; margin: 12px 0 2px; }
.bpass-ap { min-width: 0; }
.bpass-code {
  display: block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 32px;
  line-height: 1.05;
}
.bpass-place {
  display: block;
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bpass-ap-to { text-align: right; }
/* The dashed flight line, plane riding it on a surface-coloured pad so it
   reads as sitting on the line rather than skewered by it. */
.bpass-dots { flex: 1; min-width: 36px; border-top: 2px dashed var(--border); position: relative; }
.bpass-dots::after {
  content: "✈";
  position: absolute;
  left: 50%;
  top: -0.7em;
  transform: translateX(-50%);
  padding: 0 7px;
  background: var(--surface);
  color: var(--accent-text);
  font-size: 15px;
  line-height: 1.4;
}
.bpass-cells {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px 14px;
  margin-top: 12px;
  border-top: 1px solid var(--hairline);
  padding-top: 10px;
}
.bpass-cell .lbl { font-family: "Special Elite", "Courier New", monospace; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.bpass-cell .val { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; margin-top: 2px; }
.bpass-cell .note { font-size: 11px; color: var(--ink-2); margin-top: 1px; }
.bpass-fine { margin: 10px 0 0; font-size: 10.5px; color: var(--muted); }
/* Tear-off stub. The dashed rule is the perforation; the notches are
   page-coloured discs hanging half off the card edge, as if punched. */
.bpass-stub {
  flex: 0 0 148px;
  position: relative;
  border-left: 2px dashed var(--border);
  padding: 14px 14px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  text-align: center;
}
.bpass-stub::before,
.bpass-stub::after {
  content: "";
  position: absolute;
  left: -9px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--page);
}
.bpass-stub::before { top: -9px; }
.bpass-stub::after { bottom: -9px; }
.bpass-stub-code { font-family: "Special Elite", "Courier New", monospace; font-size: 30px; line-height: 1; margin-top: 6px; }
.bpass-stub-seat {
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--muted);
  text-transform: uppercase;
}
/* Two stripe periods laid over each other; where they interfere the bars come
   out in the mixed thick-thin runs of a real barcode. */
.bpass-barcode {
  width: 100%;
  height: 32px;
  opacity: 0.75;
  background:
    repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 5px),
    repeating-linear-gradient(90deg, var(--ink) 0 1px, transparent 1px 8px);
}
/* Same five-tile wrap logic the KPI grid needed: three columns in the tablet
   band, two on phones with the odd fifth cell spanning the row. */
@media (max-width: 959px) {
  .bpass-cells { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
  .bpass { flex-direction: column; }
  .bpass-head { font-size: 9.5px; letter-spacing: 0.04em; }
  .bpass-code, .bpass-stub-code { font-size: 26px; }
  .bpass-cells { grid-template-columns: repeat(2, 1fr); }
  .bpass-cells > .bpass-cell:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .bpass-stub {
    flex: none;
    border-left: none;
    border-top: 2px dashed var(--border);
    flex-direction: row;
    justify-content: space-between;
    padding: 12px 16px;
  }
  .bpass-stub::before { top: -9px; left: -9px; }
  .bpass-stub::after { top: -9px; bottom: auto; left: auto; right: -9px; }
  .bpass-barcode { width: 96px; height: 26px; }
  .bpass-stub-code { margin-top: 0; }
}

/* Sits directly under the KPI tiles, which carry a negative bottom margin of
   their own — hence the pull-up, so it reads as a caption on the figures
   rather than as a floating line of its own. */
.freshness {
  margin: -18px 0 24px;
  font-size: 12.5px;
  color: var(--muted);
}
.freshness time { font-weight: 600; color: var(--ink-2); }

/* ---------- City page: jump nav ---------- */
/* Wraps to as many rows as it needs by default so no section is hidden —
   with 12 sections the single-row version overflowed ~360px at desktop
   width, silently hiding Etiquette through FAQs behind a scroll. Narrow
   screens keep the horizontal scroller, where wrapping 12 pills would eat
   several rows of vertical space and push the content further down. */
/* "See also" — the outbound links closing a city guide. */
.see-also { margin: 0; padding-left: 18px; }
.see-also li { margin: 5px 0; }

/* Sticks once the page scrolls: on an ~11,000px guide the section chips are
   the only navigation, and they used to leave the screen immediately. The
   solid page background keeps text from ghosting through; .section's
   scroll-margin-top clears the bar for anchor jumps. */
.jump-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  /* One row at every width — with twelve chips the bar would wrap to two
     rows on desktop, and a two-row sticky bar eats too much screen. */
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
  gap: 8px;
  padding: 10px 0 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--hairline);
  background: var(--page);
}
.jump-nav a {
  flex: 0 0 auto;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.jump-nav a:hover { color: var(--accent-text); border-color: var(--accent); text-decoration: none; }
/* Scroll-spy: the chip for the section under the reading line. */
.jump-nav a.active { color: var(--accent-text); border-color: var(--accent); background: var(--accent-soft); }

/* ---------- City page: sections ---------- */
/* Clears the sticky jump-nav (one chip row ≈ 60px) so an anchor jump doesn't
   land the heading underneath it. flight-band carries an anchor too. */
.section { margin: 26px 0; }
.section, .flight-band { scroll-margin-top: 72px; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Visually hidden, read by screen readers — the repeated cost-table headers
   keep their semantics without restating Item / Local price / USD on screen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.h3-icon { margin-right: 7px; }

.to-top {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 50;
  padding: 10px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.to-top:hover { color: var(--accent-text); border-color: var(--accent); text-decoration: none; }
.section > h2 {
  font-size: 21px;
  letter-spacing: -0.01em;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
  position: relative;
}
.section > h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 44px;
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--sun));
}
.section > h3 { font-size: 15px; margin: 18px 0 6px; }
.section p { color: var(--ink-2); margin: 8px 0; }
.section p strong, .section li strong { color: var(--ink); }
.section ul { margin: 8px 0; padding-left: 20px; color: var(--ink-2); }
.section li { margin: 5px 0; }

.callout {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 12px 16px;
  margin: 12px 0;
  color: var(--ink-2);
  font-size: 14px;
}
.callout strong { color: var(--ink); }

.fact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px;
}
.fact {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
}
.fact .lbl { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.fact .val { font-size: 14px; margin-top: 2px; }
/* The season tile takes the whole row: it carries the 12-month strip under
   its prose, and both need more than one grid cell's width. */
.fact-wide { grid-column: 1 / -1; }
.fact .mo-strip { margin-top: 9px; max-width: 430px; }

/* Full-width photo, dealt between the long text sections of a city guide.
   These replaced a three-up 210px thumbnail grid: at that size the images read
   as database row icons rather than as photographs, and stacking all three in
   one block left the rest of the page bare. See renderCity's photoBreak(). */
.photo-break {
  margin: 26px 0;
}
.photo-break img {
  display: block;
  width: 100%;
  /* 2:1 keeps a 700px-wide image to 350px tall — big enough to land as a
     photograph, short enough that it never pushes a whole section of text off
     the screen. Phones get 3:2, since 2:1 at 335px wide is only a 167px sliver. */
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.photo-break a:hover img { filter: brightness(1.05); }

/* Photos ease in on load instead of popping. Scoped under .img-fade-root,
   which only app.js ever adds — the prerendered first paint and no-JS
   readers see images plainly. The placeholder boxes keep their size either
   way (every photo slot has an aspect-ratio), so nothing shifts. */
.img-fade-root .fade-img { opacity: 0; transition: opacity 0.4s ease; }
.img-fade-root .fade-img.is-loaded { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .img-fade-root .fade-img { transition: none; opacity: 1; }
}
.photo-break figcaption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 12.5px;
  color: var(--ink-2);
  margin-top: 7px;
}
.photo-break .credit {
  color: var(--muted);
  font-size: 11.5px;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .photo-break { margin: 20px 0; }
  .photo-break img { aspect-ratio: 3 / 2; }
}

/* City map */
.map-embed {
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
}
.map-embed iframe {
  display: block;
  width: 100%;
  height: 340px;
  border: 0;
}
.map-links { font-size: 13px; color: var(--ink-2); margin: 8px 0 0; }
@media (max-width: 640px) {
  .map-embed iframe { height: 260px; }
}

/* Trip cost calculator */
.calc-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-end;
  margin: 4px 0 16px;
}
.calc-field { display: flex; flex-direction: column; gap: 6px; }
.calc-field label { font-size: 12px; color: var(--ink-2); }
.calc-field input[type="number"],
.calc-field select {
  width: 90px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  box-sizing: border-box;
}
.calc-field select { width: auto; height: 42px; cursor: pointer; }
.calc-tier-btns { display: flex; gap: 6px; }
.calc-tier-btn {
  padding: 9px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.calc-tier-btn:hover { border-color: var(--accent); color: var(--accent-text); }
.calc-tier-btn.active { border-color: var(--accent); color: var(--accent-text); background: var(--accent-soft); }
.calc-results {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}
.calc-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
}
.calc-card .lbl { font-size: 12px; color: var(--ink-2); }
.calc-card .val { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; margin-top: 2px; }
.calc-card-total { border-color: var(--accent); background: var(--accent-soft); }
.calc-card-total .lbl { color: var(--ink); }
.calc-note { font-size: 13px; color: var(--ink-2); margin: 10px 0 2px; }
.calc-disclaimer { font-size: 12px; color: var(--muted); margin: 4px 0 0; }
@media (max-width: 640px) {
  .calc-controls { flex-direction: column; align-items: stretch; }
  .calc-field input[type="number"],
  .calc-field select { width: 100%; }
}

/* Country page: cost table and multi-city trip calculator */
.country-cost-table th[scope="row"] { font-weight: 600; text-align: left; }
.country-cost-table th[scope="row"] a { color: var(--accent-text); }
.sort-btn {
  all: unset;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: inherit;
  color: inherit;
}
.sort-btn::after { content: "↕"; font-size: 11px; color: var(--muted); }
th[aria-sort="ascending"] .sort-btn::after { content: "↑"; color: var(--accent-text); }
th[aria-sort="descending"] .sort-btn::after { content: "↓"; color: var(--accent-text); }
.sort-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.calc-tier-set { border: 0; padding: 0; margin: 0 0 14px; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.calc-tier-set legend { font-size: 12px; color: var(--ink-2); padding: 0; margin-bottom: 6px; width: 100%; }
.calc-radio { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.country-calc-cities {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
.country-calc-cities .calc-field input[type="number"] { width: 100%; }
.country-calc-out { font-size: 15px; margin: 14px 0 0; }

/* Travel Cost Index */
.download-btn {
  display: inline-block;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--accent);
  color: #1d1408;
  font-weight: 700;
  text-decoration: none;
  margin: 0 10px 8px 0;
}
.download-btn:hover { filter: brightness(1.06); }
.cost-index-filters { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: flex-end; margin: 0 0 14px; }
.cost-index-filters[hidden] { display: none; }
.cost-index-count { font-size: 13px; color: var(--ink-2); margin: 0 0 10px; }
.cost-index-table th[scope="row"] { font-weight: 600; text-align: left; }
.cite-text {
  margin: 10px 0;
  padding: 12px 16px;
  border-left: 3px solid var(--accent);
  background: var(--surface);
  border-radius: 0 8px 8px 0;
  font-size: 14px;
}
.cite-text p { margin: 0; }

/* Things to do (nightlife, restaurants, theater & shows) */
.activity-group { margin: 0 0 4px; }
.activity-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--hairline);
}
.activity-item:last-child { border-bottom: none; }
.activity-photo {
  flex: none;
  /* 64px showed a landmark as an icon rather than as a place. 96 is the most
     the row can carry without the photo becoming taller than its two or three
     lines of text and forcing the list open. */
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.activity-body {
  flex: 1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  min-width: 0;
}
/* The whole name + note block is the link to the venue search. min-height
   carries picks with no note (name alone is only 17px) up to a 44px target. */
.activity-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 44px;
  color: inherit;
}
.activity-main:hover { text-decoration: none; }
.activity-name { font-weight: 600; font-size: 14px; color: var(--accent-text); }
.activity-main:hover .activity-name { text-decoration: underline; }
.activity-note { color: var(--ink-2); font-size: 13.5px; margin-top: 2px; }
.price-tag {
  flex: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
}

/* Definition-style lists (getting around, where to stay) */
.dl-row { display: grid; grid-template-columns: 170px 1fr; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--hairline); }
.dl-row:last-child { border-bottom: none; }
.dl-row dt { font-weight: 600; font-size: 14px; margin: 0; }
.dl-row dd { margin: 0; color: var(--ink-2); font-size: 14px; }
dl { margin: 0; }

/* FAQs */
details {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 10px;
  padding: 10px 16px;
  margin: 8px 0;
}
details summary { cursor: pointer; font-weight: 600; font-size: 14px; }
details p { margin: 8px 0 4px; color: var(--ink-2); font-size: 14px; }

/* Footer */
.site-footer {
  margin: 40px 0 32px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
  color: var(--muted);
  font-size: 13px;
}

.error-box { margin: 60px auto; text-align: center; }

@media (max-width: 560px) {
  .dl-row { grid-template-columns: 1fr; gap: 2px; }
  .budget-row { grid-template-columns: 84px 1fr 80px; }
  .hero h1 { font-size: 28px; }
  /* The desktop 420px is over half a phone screen; 340 keeps the title, the
     tagline and the start of the page visible on first paint. */
  .hero.has-photo { min-height: 340px; }
}

/* ---------- Head-to-head comparison pages ---------- */
.vs-crumb { margin: 18px 0 6px; }
.vs-title {
  font-size: 30px;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
}
.vs-title span {
  color: var(--muted);
  font-weight: 600;
  font-size: 0.7em;
  /* Lowercase "vs" kept visually subordinate — the two city names are the
     heading, the joiner isn't. */
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 4px;
}
.vs-hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 8px;
}
.vs-side {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 190px;
  padding: 16px;
  border-radius: 16px;
  color: #fff;
  overflow: hidden;
}
.vs-side:hover { text-decoration: none; }
.vs-side .flag { font-size: 24px; line-height: 1; margin-bottom: 6px; }
.vs-side h2 {
  margin: 0;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: #fff;
}
.vs-budget { font-size: 14px; opacity: 0.92; margin-top: 2px; }
.vs-verdict p { margin: 0; font-size: 15px; line-height: 1.6; }

/* The winning cell is marked by weight and a small word, never by colour
   alone — a green cell says nothing to a reader who can't see green. */
.vs-table th[scope="row"] { text-transform: none; font-size: 13px; color: var(--ink-2); }
.vs-table th[scope="row"] .vs-note {
  display: block;
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
}
/* The shared rule only clears the last row's <td> borders; these tables put a
   <th> in the first column, so its border was left hanging under the row. */
.vs-table tr:last-child th { border-bottom: none; }
.vs-table td.vs-win { font-weight: 700; color: var(--ink); }
.vs-win-tag {
  display: block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-text);
}

/* Month strips */
.vs-months { margin-bottom: 14px; }
.vs-months:last-child { margin-bottom: 0; }
.vs-months-city { font-size: 14px; font-weight: 600; margin-bottom: 5px; }
.mo-strip { display: flex; gap: 3px; }
.mo {
  flex: 1 1 0;
  text-align: center;
  font-size: 11px;
  line-height: 22px;
  height: 22px;
  border-radius: 5px;
  color: var(--muted);
  background: var(--page);
  border: 1px solid var(--hairline);
}
.mo.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
/* Dashed rather than a second colour: "avoid" is the absence of a
   recommendation, and reads better as an outline than as a rival fill. */
.mo.off { border-style: dashed; opacity: 0.6; }
.vs-months-label { font-size: 12px; color: var(--ink-2); margin-top: 4px; }

.vs-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.vs-cols h3 { margin: 0 0 6px; font-size: 16px; }
.vs-tagline { font-size: 14px; color: var(--ink-2); line-height: 1.55; margin: 0 0 10px; }
.vs-picks { margin: 0 0 10px; padding: 0; list-style: none; font-size: 14px; }
.vs-picks li {
  display: grid;
  /* Name takes the room; the price tier and category sit right, so the two
     columns line up against each other row for row. */
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--hairline);
}
.vs-picks li:last-child { border-bottom: none; }
.vs-price { color: var(--ink-2); font-size: 13px; font-weight: 600; }
.vs-cat { grid-column: 1 / -1; font-size: 12px; color: var(--muted); }
.vs-guide-link { font-size: 14px; font-weight: 600; }

.vs-same-intro { margin: 14px 0 8px; }
.vs-same {
  display: grid;
  grid-template-columns: minmax(110px, max-content) 1fr;
  gap: 6px 16px;
  margin: 0;
  font-size: 14px;
}
.vs-same dt { color: var(--muted); font-size: 13px; }
.vs-same dd { margin: 0; color: var(--ink-2); }

/* Pick-any-pair on the /vs/ hub. */
.vs-picker-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.vs-picker-row select {
  flex: 1 1 180px;
  min-width: 0;
  height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.vs-picker-vs { font-size: 13px; font-weight: 700; color: var(--muted); }
.vs-picker-go {
  height: 42px;
  padding: 0 18px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.vs-picker-go:hover { background: var(--accent); color: #fff; }
.vs-picker-note { min-height: 0; margin: 8px 0 0; }

/* ---------- Comparison deep-dive (allowlisted pairs) ---------- */
.vs-deep p { line-height: 1.65; }
.vs-deep ul { margin: 8px 0 0; padding-left: 20px; }
.vs-deep li { margin-bottom: 6px; line-height: 1.6; }
.vs-direct { font-size: 17px; font-weight: 600; margin: 4px 0 10px; }
.vs-month-table { margin-top: 18px; }
.vs-month-table caption {
  caption-side: top;
  text-align: left;
  font-weight: 700;
  font-size: 14px;
  padding: 0 0 8px;
}
.vs-month-table td { font-size: 13px; font-weight: 600; }
.vs-month-table .mo-good { color: var(--good); }
.vs-month-table .mo-avoid { color: var(--muted); }
.vs-month-table .mo-mid { color: var(--ink-2); font-weight: 500; }
.vs-faq h3 { font-size: 16px; margin: 18px 0 6px; }
.vs-faq h3:first-of-type { margin-top: 6px; }
.vs-faq p { margin: 0; }

/* ---------- Home-page compare panel ---------- */
.home-vs { margin-top: 20px; }
.home-vs .vs-picker-row { margin-top: 14px; }

/* Searchable city picker (enhanceCityPicker in app.js) — sized and styled
   like the <select> it stands in for. */
.city-combo { position: relative; flex: 1 1 180px; min-width: 0; }
.city-combo-input {
  width: 100%;
  height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--page);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  box-sizing: border-box;
}
.city-combo-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.city-combo-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: 300px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
}
.city-combo-list[hidden] { display: none; }
.city-combo-list li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
}
.city-combo-list li[aria-selected="true"],
.city-combo-list li[data-i]:hover { background: var(--accent-soft); }
.city-combo-country { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.city-combo-list .city-combo-empty { color: var(--muted); cursor: default; }
.home-vs-preview:empty { display: none; }
.home-vs-preview { margin-top: 16px; }
.home-vs-verdict { margin: 0 0 12px; font-size: 15px; line-height: 1.6; }
.home-vs-months { display: grid; gap: 10px; margin-top: 14px; }
.home-vs-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
}
.home-vs-chips .sub { margin: 0 2px 0 0; font-size: 13px; }
.home-vs-chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--page);
  text-decoration: none;
}
.home-vs-chip span { color: var(--muted); font-weight: 500; }
.home-vs-chip:hover { border-color: var(--accent); color: var(--accent-text); }
.vs-picker-note:empty { display: none; }
@media (max-width: 560px) {
  .vs-picker-row select, .vs-picker-row .city-combo, .vs-picker-go { flex: 1 1 100%; }
  .vs-picker-vs { display: none; }
}

.vs-more { display: flex; flex-wrap: wrap; gap: 8px; }
.vs-more a {
  font-size: 13px;
  padding: 7px 12px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  color: var(--ink-2);
}
.vs-more a:hover { border-color: var(--accent); color: var(--accent-text); text-decoration: none; }

/* Comparison links on a city guide. */
.vs-inline { display: flex; flex-wrap: wrap; gap: 8px; }
.vs-inline a {
  font-size: 13px;
  padding: 7px 12px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  color: var(--ink-2);
}
.vs-inline a:hover { border-color: var(--accent); color: var(--accent-text); text-decoration: none; }

@media (max-width: 640px) {
  .vs-title { font-size: 24px; }
  /* The two heroes stay side by side even on a phone — seeing both at once is
     the whole point of the page, and stacking them reads as two separate
     cities rather than a comparison. They just get shorter. */
  .vs-hero { gap: 8px; }
  .vs-side { min-height: 132px; padding: 12px; }
  .vs-side h2 { font-size: 17px; }
  .vs-side .flag { font-size: 19px; }
  .vs-budget { font-size: 12px; }
  .vs-cols { grid-template-columns: 1fr; gap: 18px; }
  .mo { font-size: 10px; }
  .vs-same { grid-template-columns: 1fr; gap: 2px 0; }
  .vs-same dd { margin-bottom: 8px; }
}

/* ==========================================================================
   Travel-documents pass: typography, hero contours, passport stamps
   ========================================================================== */

/* Self-hosted subsets (font-src 'self'; ~22KB + ~37KB woff2), cut by
   scripts/build-fonts.js to the characters each face draws. Fraunces
   600 (OFL) carries the headings; Special Elite (Apache-2.0) is the
   typewriter voice reserved for "document" furniture — boarding-pass labels
   and passport stamps — never body text. Glyphs the subsets lack (flags,
   CJK) fall through to the system stack per-character, so city names with
   emoji render fine. */
/* optional, not swap: a headline that swapped to Fraunces mid-load
   re-wrapped in the wider face, so the hero grew, its photo painted again
   larger (a second, later Largest Contentful Paint) and the content below
   shifted (CLS 0.027 on several country pages). With optional the browser
   uses Fraunces only if it's there almost at once — always from cache after
   the first visit — and otherwise keeps Georgia for that page view, never
   swapping. Preloading it instead slowed mobile LCP by 0.1–0.3 s. */
@font-face {
  font-family: "Fraunces";
  src: url("fonts/fraunces-600-latin.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: "Special Elite";
  src: url("fonts/special-elite-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
h1, h2, h3 {
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-weight: 600;
}
/* 800 would be synthesized — 600 is the only weight shipped. */
.site-header .brand { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 19px; }

/* Faint topographic contours over the gradient heroes and banners — not the
   photo ones, where lines over a photograph are just noise. assets/topo.svg
   is generated island blobs that never touch the tile edge, so the repeat
   needs no seam (scripts: scratchpad contours.js, seeded, rerunnable).
   isolation + z-index:-1 slots the layer above the element's own inline
   gradient but below its text. */
.hero, .banner { position: relative; isolation: isolate; overflow: hidden; }
.hero::before, .banner::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("topo.svg") 0 0 / 340px auto;
  opacity: 0.16;
  pointer-events: none;
}
.banner::before { background-size: 240px auto; opacity: 0.14; }
.hero.has-photo::before, .banner.has-photo::before { content: none; }

/* Hero and banner photos: an <img> under a scrim, both behind the text (see
   coverImg() in app.js). The parents isolate, so negative z-indexes stay
   inside them and above their gradient background. */
.vs-side { isolation: isolate; }
.cover-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}
.cover-shade { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
/* The hero scrim stays strong across the whole text block, not just the
   bottom edge: breadcrumb, title and tagline stack ~200px tall, so the
   breadcrumb sits ~70% of the way up. Holding ~0.55+ to 75% keeps white text
   readable on a bright photo (Tokyo's neon, Cabo Verde's beach) and still
   lets the top of the photo read. */
.hero > .cover-shade {
  background: linear-gradient(to top, rgba(8,8,10,0.78), rgba(8,8,10,0.70) 45%, rgba(8,8,10,0.55) 75%, rgba(8,8,10,0.18));
}
.banner > .cover-shade,
.vs-side > .cover-shade {
  background: linear-gradient(to top, rgba(8,8,10,0.62), rgba(8,8,10,0.22) 55%, rgba(8,8,10,0.05));
}

/* Today every hero and banner carries a photo, so the white-stroke overlay
   above only appears if a future city ships without one. Where the contours
   actually live is on the paper: a watermark on the boarding pass and the
   passport page, the way tickets carry security print. Done as a mask rather
   than a background so the one SVG prints in the current ink colour — white
   strokes would vanish on the light theme's paper. */
.bpass-main { position: relative; isolation: isolate; }
.bpass-main::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: currentColor;
  -webkit-mask: url("topo.svg") 0 0 / 300px auto;
  mask: url("topo.svg") 0 0 / 300px auto;
  opacity: 0.05;
  pointer-events: none;
}
.stamp-grid { position: relative; isolation: isolate; }
.stamp-grid::before {
  content: "";
  position: absolute;
  inset: -10px -6px;
  z-index: -1;
  background: currentColor;
  -webkit-mask: url("topo.svg") 40px 20px / 320px auto;
  mask: url("topo.svg") 40px 20px / 320px auto;
  opacity: 0.06;
  pointer-events: none;
}

/* ---------- Saved page: passport ----------
   Each saved city is an entry stamp: cycling ink colours, each pressed a
   little crooked, every fifth-ish one oval because border posts don't buy
   their kit from one supplier. Markup is a plain link grid in renderSaved();
   everything stampy is CSS. */
:root {
  --stamp-a: #2a4d8f;
  --stamp-b: #9c3b2e;
  --stamp-c: #2c6e49;
  --stamp-d: #64508d;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    --stamp-a: #85a8e8;
    --stamp-b: #e2907f;
    --stamp-c: #86c8a2;
    --stamp-d: #b3a0dd;
  }
}
:root[data-theme="dark"] {
  --stamp-a: #85a8e8;
  --stamp-b: #e2907f;
  --stamp-c: #86c8a2;
  --stamp-d: #b3a0dd;
}
.passport-meta {
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 2px 0 18px;
}
.stamp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 24px 18px;
  margin: 0 0 30px;
}
.stamp {
  --ink-s: var(--stamp-a);
  position: relative;
  display: block;
  color: var(--ink-s);
  border: 2px solid var(--ink-s);
  border-radius: 12px;
  padding: 16px 14px 12px;
  text-align: center;
  transform: rotate(-2.4deg);
  transition: transform 0.15s ease;
}
.stamp::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid var(--ink-s);
  border-radius: 9px;
  opacity: 0.7;
  pointer-events: none;
}
.stamp:hover { text-decoration: none; transform: rotate(0deg) scale(1.03); }
.stamp:nth-child(4n+2) { --ink-s: var(--stamp-b); transform: rotate(1.9deg); }
.stamp:nth-child(4n+3) { --ink-s: var(--stamp-c); transform: rotate(-1.1deg); }
.stamp:nth-child(4n+4) { --ink-s: var(--stamp-d); transform: rotate(2.7deg); }
.stamp:nth-child(4n+2):hover,
.stamp:nth-child(4n+3):hover,
.stamp:nth-child(4n+4):hover { transform: rotate(0deg) scale(1.03); }
.stamp:nth-child(5n+3) { border-radius: 50% / 44%; padding: 22px 20px 16px; }
.stamp:nth-child(5n+3)::before { border-radius: 50% / 44%; inset: 4px; }
.stamp-top {
  display: block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  opacity: 0.75;
}
.stamp-name {
  display: block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 20px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 4px 0 2px;
}
.stamp-sub { display: block; font-size: 12.5px; opacity: 0.9; }
.stamp-no {
  display: block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-top: 9px;
  padding-top: 7px;
  border-top: 1px dashed var(--ink-s);
}
@media (prefers-reduced-motion: reduce) {
  .stamp { transition: none; }
}

/* ---------- Sharing ----------
   One pill row, same shape language as .vs-more. The native "Share…" button
   ships hidden and is revealed by initShare() only where navigator.share
   exists, so [hidden] has to survive the display rule below — hence the
   explicit reset rather than relying on the UA default. */
.share-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 18px 0 4px;
}
.share-lbl {
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 2px;
}
.share-btn {
  font: inherit;
  font-size: 13px;
  padding: 7px 13px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
a.share-btn { text-decoration: none; }
.share-btn:hover { border-color: var(--accent); color: var(--accent-text); text-decoration: none; }
.share-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.share-btn[hidden] { display: none; }

.passport-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}
.passport-img-note { font-size: 12.5px; }

/* ---------- Most-saved strip ----------
   Populated from Firestore after paint, so it can appear a beat late; it's
   below the picker rather than above it for that reason — nothing the reader
   is already looking at moves when it arrives. */
.top-saved { counter-reset: tsc; }
.top-saved-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.top-saved-card {
  counter-increment: tsc;
  position: relative;
  display: block;
  padding: 12px 12px 11px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.top-saved-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  text-decoration: none;
}
.tsc-rank::before {
  content: counter(tsc);
  position: absolute;
  top: 8px;
  right: 10px;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 15px;
  color: var(--muted);
  opacity: 0.6;
}
.tsc-name { display: block; font-weight: 600; font-size: 14.5px; padding-right: 18px; }
.tsc-sub { display: block; font-size: 12px; color: var(--muted); margin-top: 1px; }
.tsc-count {
  display: block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--accent-2);
  margin-top: 7px;
}
@media (prefers-reduced-motion: reduce) {
  .top-saved-card { transition: none; }
  .top-saved-card:hover { transform: none; }
}

@media (max-width: 640px) {
  /* The label is a sentence, not a word, and sharing it a row with the pills
     leaves a single orphan "X" beside it. Its own line reads as a heading. */
  .share-lbl { flex: 0 0 100%; margin: 0 0 2px; }
  .share-row { gap: 7px; }
  .top-saved-strip { grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); }
}

/* ---------- City search ----------
   Sits in the header; the results panel is absolutely positioned off the
   wrap so it overlays the page rather than reflowing it. */
.search-wrap {
  position: relative;
  flex: 1 1 200px;
  min-width: 140px;
  max-width: 300px;
}
.site-search {
  width: 100%;
  padding: 7px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
}
.site-search::placeholder { color: var(--muted); }
.site-search:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-results {
  position: absolute;
  z-index: 40;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 34px rgba(30, 20, 10, 0.18);
  max-height: 60vh;
  overflow-y: auto;
}
.search-opt a {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "flag name" "flag meta";
  column-gap: 10px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 10px;
  color: var(--ink);
  text-decoration: none;
}
.search-flag { grid-area: flag; font-size: 20px; }
.search-name { grid-area: name; font-weight: 600; font-size: 14px; }
.search-meta { grid-area: meta; font-size: 12px; color: var(--muted); }
.search-opt.is-active a,
.search-opt a:hover { background: var(--accent-soft); text-decoration: none; }
.search-empty {
  padding: 10px 12px;
  font-size: 13px;
  color: var(--muted);
}

@media (max-width: 800px) {
  /* The header becomes a grid at this width; give search its own full row
     between the brand row and the nav row rather than fighting for space. */
  .site-header {
    grid-template-areas:
      "brand auth   theme"
      "search search search"
      "nav   nav    cur";
  }
  .search-wrap { grid-area: search; max-width: none; }
}

/* ---------- Daily budget by travel style ----------
   Sits under the boarding pass. Three equal columns; the mid one is tinted
   because it's the researched figure the flanks are derived from. */
.tier-band {
  margin: 14px 0 0;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
}
.tier-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.tier {
  padding: 14px 14px 12px;
  border-radius: 12px;
  text-align: center;
}
.tier.is-mid { background: var(--accent-soft); }
.tier-label {
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.tier.is-mid .tier-label { color: var(--accent-text); }
.tier-val {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 22px;
  margin: 3px 0 2px;
  color: var(--ink);
}
.tier-per {
  font-family: system-ui, sans-serif;
  font-weight: 400;
  font-size: 12px;
  color: var(--muted);
  margin-left: 2px;
}
.tier.is-mid .tier-per { color: var(--ink-2); } /* --muted is 4.48:1 on --accent-soft, 3.57:1 in dark mode */
.tier-sub { font-size: 12px; color: var(--ink-2); }
.tier-note {
  margin: 2px 6px 6px;
  padding-top: 8px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}
.tier-note a { color: var(--ink-2); text-decoration: underline; }
.tier-note a:hover { color: var(--accent-text); }
@media (max-width: 560px) {
  .tier { padding: 11px 6px 10px; }
  .tier-val { font-size: 18px; }
  .tier-per { display: block; margin: 0; }
  .tier-sub { font-size: 11px; }
}

/* ---------- Entry & visa ----------
   A stamped-document callout in the passport/boarding-pass family: accent
   left rule, mono caveat. Reuses the researched FAQ prose, promoted up-page. */
.visa-card {
  position: relative;
  padding: 16px 18px 16px 20px;
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 12px;
  background: var(--surface);
}
.visa-answer {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
}
/* The one place the typewriter face used to carry full sentences — two lines
   of monospace reads as terminal output, not a travel note. The face stays on
   short uppercase labels (boarding pass, stamps, tier/flight headers) where
   it's flavour; running text gets the body font. */
.visa-caveat {
  margin: 12px 0 0;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  font-size: 12.5px;
  font-style: italic;
  line-height: 1.5;
  color: var(--muted);
}

/* ---------- Getting there: flight band ----------
   Sits directly under the budget tiers and prices the route the boarding
   pass draws. Dotted leaders between origin and fare keep it in the
   ticket/manifest family the pass and tiers already live in. */
.flight-band {
  margin: 14px 0 0;
  padding: 14px 18px 12px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
}
.flight-head {
  font-family: "Special Elite", "Courier New", monospace;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 8px;
}
.flight-sub {
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted);
  font-family: system-ui, sans-serif;
  font-size: 12px;
  margin-left: 6px;
}
.flight-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 5px 0;
}
.flight-origin { font-size: 14px; color: var(--ink-2); white-space: nowrap; }
.flight-dots {
  flex: 1;
  border-bottom: 2px dotted var(--border);
  transform: translateY(-4px);
}
.flight-fare {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 17px;
  color: var(--ink);
  white-space: nowrap;
}
.flight-note {
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
  font-size: 12px;
  color: var(--muted);
}
@media (max-width: 560px) {
  .flight-band { padding: 12px 14px 10px; }
  .flight-origin { font-size: 13px; white-space: normal; }
  .flight-fare { font-size: 15px; }
}

/* ---------- 404 ---------- */
.nf-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 6px;
}
.nf-city {
  padding: 9px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 600;
}
.nf-city:hover { color: var(--accent-text); border-color: var(--accent); text-decoration: none; }
