/* Server-rendered content site: no framework, no hydration, small payload.
   Core Web Vitals are a ranking input, so the CSS stays small and the layout
   never shifts. */

:root {
  --ink: #16202a;
  --ink-soft: #55636f;
  --ink-faint: #8896a2;
  --paper: #ffffff;
  --paper-alt: #f6f8f9;
  --line: #e2e7ea;
  --accent: #0b6b5f;
  --accent-soft: #e6f2f0;
  --accent-ink: #084f46;
  /* Rail surface: an accent-tinted panel, deliberately NOT grey. Slightly cooler
     and lighter than --accent-soft so the rail does not read as a CTA box. */
  --rail-surface: #e8f4f1;
  --rail-line: #b6d9d1;
  --rail-head: #0b6b5f;
  --rail-head-ink: #ffffff;
  /* Wordmark tiles: five clearly separate hues, so no two tiles read as a pair.
     Letters are always white, which sets the floor on how bright each hue can go.
     The tile letter is bold at about 20px, which WCAG counts as large text, so the
     bar is 3:1 - the mango is the tightest at 3.26:1. That is fine at this size and
     is the reason the mark should not be rendered much smaller than 1.3rem. */
  --tile-1: #1477d1;   /* azure       - white 4.58:1 */
  --tile-2: #e23b52;   /* flamingo    - white 4.22:1 */
  --tile-3: #d97400;   /* mango       - white 3.26:1 */
  --tile-4: #9b3fd4;   /* orchid      - white 5.18:1 */
  --tile-5: #0f9e56;   /* palm green  - white 3.47:1 */
  --tile-ink: #ffffff;
  --brand-word-ink: #000000;
  /* Header and hero share one blue field, so the top of the page reads as a single
     band rather than two tints meeting at a seam. Deliberately in the tile-1 hue
     family: a blue header under a blue-led wordmark, not a second brand colour. */
  --header-bg: #eaf2fd;
  --header-line: #cfe0f7;
  /* The category strip carries the deeper blue, so the two bars read as a masthead
     with the strip as its base rather than as two washes of the same tint. */
  --subbar-bg: #dcebfb;
  --subbar-line: #c3daf5;
  --subbar-ink: #1f2b38;           /* 13.25:1 on the plate */
  --subbar-label: #125cbf;
  --hero-bg: #dcebfb;
  --warn-bg: #fff8e6;
  --warn-line: #e8d9a8;
  --radius: 10px;
  --wrap: 1080px;
  --measure: 42rem;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e8edf1;
    --ink-soft: #a7b4bf;
    --ink-faint: #7d8b96;
    --paper: #10161b;
    --paper-alt: #171f26;
    --line: #26313a;
    --accent: #4fd1bd;
    --accent-soft: #14312c;
    --accent-ink: #7fe3d3;
    --rail-surface: #10302a;
    --rail-line: #1f4d44;
    --rail-head: #17564c;
    --rail-head-ink: #d6fff7;
    /* The same five hues, held close to their light-mode values. They are already
       bright enough to read as colours against a near-black header, and pushing
       them further would cost the white letters their 3:1 floor. */
    --tile-1: #2b86e0;
    --tile-2: #e84a5f;
    /* Held at the light-mode value: brightening this one broke the 3:1 floor
       (#e08000 measures 2.89:1), and legibility outranks a livelier orange. */
    --tile-3: #d97400;
    --tile-4: #a552de;
    --tile-5: #12a95c;
    /* Black would vanish here, so the word takes the paper's opposite instead. */
    --brand-word-ink: #f4f8fa;
    /* Dark mode keeps the blue *tint* but not the lightness: a pale band would
       glare against a near-black page. */
    --header-bg: #121c28;
    --header-line: #24354a;
    --subbar-bg: #141d28;
    --subbar-line: #22303f;
    --subbar-ink: #cdd8e3;
    --subbar-label: #7fb2f0;
    --hero-bg: #14202e;
    --warn-bg: #2a2413;
    --warn-line: #4a4025;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
}

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 1.25rem; }
.visually-hidden, .skip:not(:focus) {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.skip:focus {
  position: absolute; left: 1rem; top: 1rem; z-index: 100; background: var(--accent);
  color: #fff; padding: .5rem .75rem; border-radius: 6px;
}

a { color: var(--accent-ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent); }
.muted { color: var(--ink-soft); }
.small { font-size: .875rem; }

/* --- header: two tiers ------------------------------------------------------- */
.site-header { border-bottom: 1px solid var(--subbar-line); }
.bar-main { background: var(--header-bg); }
.header-inner {
  display: flex; align-items: center; gap: 1.25rem; padding: 1.15rem 1.25rem; flex-wrap: wrap;
}

.bar-sub { background: var(--subbar-bg); border-top: 1px solid var(--header-line); }
.sub-inner {
  display: flex; align-items: center; gap: 1rem; padding: 0 1.25rem;
}
.sub-label {
  font-size: .8rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--subbar-label); white-space: nowrap;
  padding-right: 1rem; border-right: 1px solid var(--subbar-line);
}
.sub-nav {
  display: flex; align-items: center; gap: 1.25rem;
  /* Sideways scroll beats wrapping: a wrapped strip pushes the page content down by
     an unpredictable amount on every screen width. */
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.sub-nav::-webkit-scrollbar { display: none; }
.sub-nav a {
  padding: .6rem 0; font-size: .92rem; text-decoration: none; white-space: nowrap;
  color: var(--subbar-ink); border-bottom: 2px solid transparent;
}
.sub-nav a:hover { color: var(--subbar-label); }
.sub-nav a.is-current { border-bottom-color: var(--subbar-label); font-weight: 600; }
/* Cities are one level down from their country, and read as such. */
.sub-nav a.sub-city { font-size: .87rem; color: var(--subbar-ink); opacity: .82; }
.sub-nav a.sub-country { font-weight: 600; }
.brand { font-weight: 700; font-size: 1.1rem; text-decoration: none; color: var(--ink); }

/* --- hamburger + drawer -----------------------------------------------------
   The button sits left of the wordmark, which is where a thumb reaches on a phone
   and where every reader now expects it. Hidden above the drawer breakpoint: with
   room for the full nav, a menu button is an extra tap for nothing. */
.nav-toggle {
  display: none;
  width: 2.6rem; height: 2.6rem; padding: 0;
  border: 1px solid var(--header-line); border-radius: 8px;
  background: var(--paper); cursor: pointer;
  place-items: center; flex: 0 0 auto;
}
.nav-toggle:hover { border-color: var(--subbar-label); }
.nav-toggle:focus-visible { outline: 2px solid var(--subbar-label); outline-offset: 2px; }
/* Three bars from one element: the middle is the box, the outer two are its
   pseudo-elements. Fewer nodes than three spans, and no risk of them being styled
   out of alignment by something else. */
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  display: block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--ink); content: "";
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before { position: absolute; top: -6px; }
.nav-toggle-bars::after  { position: absolute; top: 6px; }

.nav-drawer {
  /* 70% of the viewport, capped so it does not become a wall on a tablet. */
  width: 70%; max-width: 22rem; min-width: 15rem;
  height: 100%; max-height: 100%;
  margin: 0 auto 0 0;                 /* pinned left, under the button that opened it */
  padding: 1rem 1.1rem 2rem;
  border: 0; border-right: 1px solid var(--line);
  background: var(--paper); color: var(--ink);
  overflow-y: auto;
  /* iOS Safari: without this a long drawer scrolls the page behind it instead. */
  overscroll-behavior: contain;
}
.nav-drawer::backdrop { background: rgb(16 32 42 / .5); }
.nav-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; padding-bottom: .9rem; border-bottom: 1px solid var(--line);
}
.nav-drawer-head .brand-mark { font-size: 1.05rem; }
.nav-close {
  border: 0; background: none; cursor: pointer;
  font-size: 1.9rem; line-height: 1; color: var(--ink-soft); padding: 0 .2rem;
}
.nav-close:hover { color: var(--ink); }

.drawer-search { display: flex; margin: 1rem 0 .5rem; }
.drawer-search input {
  flex: 1; min-width: 0; font-size: .95rem; padding: .5rem .7rem;
  border: 1px solid var(--line); border-right: 0; border-radius: 7px 0 0 7px;
  background: var(--paper-alt); color: var(--ink);
}
.drawer-search button {
  border: 1px solid var(--subbar-label); background: var(--subbar-label); color: #fff;
  border-radius: 0 7px 7px 0; padding: 0 .9rem; font-weight: 600; cursor: pointer;
}

.nav-drawer nav { display: flex; flex-direction: column; }
.drawer-head {
  margin: 1.35rem 0 .5rem;
  font-size: .7rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-faint);
}
.nav-drawer nav a {
  padding: .6rem 0; text-decoration: none; color: var(--ink);
  border-bottom: 1px solid var(--line); font-size: 1rem;
}
.nav-drawer nav a:last-child { border-bottom: 0; }
.nav-drawer nav a.is-current { font-weight: 700; color: var(--subbar-label); }
.drawer-country { display: flex; align-items: center; gap: .5rem; font-weight: 600; }
.drawer-country img {
  width: 20px; height: 14px; object-fit: cover; border-radius: 2px; display: block;
}
.drawer-city { padding-left: calc(20px + .5rem) !important; color: var(--ink-soft) !important; }

/* --- wordmark: A B O U T .travel -----------------------------------------
   Five tiles in five unrelated hues - blue, red, orange, purple, green - so no two
   sit close enough to read as a pair. The colours are named tokens rather than
   literals in the rules, so a second tenant can be recoloured without touching the
   layout. Sizes are in em so the mark scales from .brand-mark's font-size alone. */
.brand-mark {
  display: inline-flex; align-items: center; gap: .05em;
  font-size: 1.3rem; line-height: 1; text-decoration: none;
  /* Contained so the hover lift cannot nudge the nav on the same flex row. */
  padding: .15em 0;
}
/* Tighter than the tiles are wide, so the five letters read as one word rather
   than as five separate badges. */
.brand-tiles { display: inline-flex; gap: .09em; }
.brand-tile {
  display: grid; place-items: center;
  /* Portrait, not square: a taller-than-wide tile reads as a letterform holder.
     Square tiles read as app icons. */
  width: 1.15em; height: 1.62em;
  border-radius: .2em;
  font-weight: 800; font-size: .95em; letter-spacing: .01em;
  color: var(--tile-ink);
  background: var(--tile-1);
  /* A hairline of the tile's own colour, darkened, so tiles stay crisp against
     both the white header and the dark-mode one. */
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .12), 0 1px 2px rgb(16 32 42 / .18);
  transition: transform .16s ease;
}
.brand-tiles .brand-tile:nth-child(5n + 2) { background: var(--tile-2); }
.brand-tiles .brand-tile:nth-child(5n + 3) { background: var(--tile-3); }
.brand-tiles .brand-tile:nth-child(5n + 4) { background: var(--tile-4); }
.brand-tiles .brand-tile:nth-child(5n + 5) { background: var(--tile-5); }

/* ".travel" in flat black beside the tiles: the colour lives in the tiles, and a
   second coloured element would compete with them. Black in light mode literally,
   near-white in dark mode, since black on a near-black header is nothing at all. */
.brand-word {
  font-weight: 700; font-size: 1.02em; color: var(--brand-word-ink);
  letter-spacing: -.015em;
  /* Pulled in tight against the last tile. A leading period carries its own left
     side bearing, so a nominal gap of zero still looks like a small space; the
     negative margin cancels that bearing rather than adding a real gap. */
  margin-left: -.06em;
}
/* Hover runs a wave: each tile hops and settles, one after the next, left to
   right. Done with an animation rather than a transition because a transition can
   only hold the end state - every tile would sit lifted for as long as the pointer
   stayed, and the sequence would only be visible in the first fifth of a second.
   Each tile keeps its own delay, so the eye follows A, B, O, U, T in order. */
@keyframes brand-hop {
  0%   { transform: translateY(0); }
  35%  { transform: translateY(-7px); }
  65%  { transform: translateY(-7px); }
  100% { transform: translateY(0); }
}
.brand-mark:hover .brand-tile,
.brand-mark:focus-visible .brand-tile {
  animation: brand-hop .58s ease both;
}
.brand-tiles .brand-tile:nth-child(1) { animation-delay: 0s; }
.brand-tiles .brand-tile:nth-child(2) { animation-delay: .09s; }
.brand-tiles .brand-tile:nth-child(3) { animation-delay: .18s; }
.brand-tiles .brand-tile:nth-child(4) { animation-delay: .27s; }
.brand-tiles .brand-tile:nth-child(5) { animation-delay: .36s; }
.brand-mark:focus-visible {
  /* Brand blue, not the teal accent: a green ring around a blue-and-red wordmark
     looked like a rendering fault rather than a focus indicator. */
  outline: 2px solid var(--subbar-label); outline-offset: 3px; border-radius: .3em;
}
/* Inside the drawer the mark is decoration - the heading of a panel you already
   opened - so it is not a focus stop at all. Focus goes to the close button, which is
   what someone opening a drawer wants next. */
.nav-drawer .brand-mark:focus-visible { outline: none; }
/* The wrapper is not interactive, so it must not paint a ring either. */
.drawer-mark { display: inline-flex; }
.drawer-mark:focus, .drawer-mark:focus-visible { outline: none; }
.nav-drawer .brand-mark { pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  .brand-tile { transition: none; }
  .brand-mark:hover .brand-tile,
  .brand-mark:focus-visible .brand-tile { animation: none; transform: none; }
}
/* The drawer breakpoint. Below this the inline nav and the header search are gone -
   they are in the drawer instead - so the bar is hamburger, wordmark, and nothing
   else. 900px rather than a phone width because the nav plus the search field stops
   fitting comfortably well before phone size, and a cramped header is worse than a
   menu button. */
@media (max-width: 900px) {
  .nav-toggle { display: grid; }
  .header-inner .nav,
  .header-inner .search { display: none; }
  .header-inner {
    gap: .7rem; padding: .75rem 1.1rem; flex-wrap: nowrap;
  }
  .brand-mark { font-size: 1.15rem; }
}

@media (max-width: 620px) {
  .sub-inner { gap: .7rem; padding: 0 1.1rem; }
  .sub-label {
    /* Hidden rather than stacked: on a phone the strip is self-evidently a row of
       places, and the label would cost a third of the width. */
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); padding: 0; border: 0;
  }
}

/* Phones: the mark is the widest fixed thing in the header, so it comes down a step
   rather than pushing the button off the edge. */
@media (max-width: 380px) {
  .brand-mark { font-size: 1rem; }
  .nav-toggle { width: 2.35rem; height: 2.35rem; }
}

.nav { display: flex; gap: 1rem; flex: 1; flex-wrap: wrap; }
.nav a {
  text-decoration: none; color: var(--ink-soft); font-size: .95rem;
  padding: .2rem 0; border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--accent); }
/* Current section marked by a rule as well as weight, not by colour alone. */
.nav a.is-current {
  color: var(--ink); font-weight: 600; border-bottom-color: var(--subbar-label);
}
.search input {
  border: 1px solid var(--header-line); border-radius: 999px; padding: .4rem .85rem;
  /* White, not --paper-alt: the off-white read as a grey patch once the header
     behind it was tinted. */
  background: var(--paper); color: var(--ink); font-size: .9rem; min-width: 12rem;
}

.site-footer { margin-top: 4rem; border-top: 1px solid var(--line); background: var(--paper-alt); }
.footer-grid {
  display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: 2rem;
  padding: 2rem 1.25rem 1rem;
}
.footer-grid nav { display: flex; flex-direction: column; gap: .35rem; }
.footer-grid nav a { font-size: .9rem; text-decoration: none; color: var(--ink-soft); }
.footer-head { font-weight: 600; margin: 0 0 .5rem; }
/* The mark, not a heading, so it gets the tiles' own spacing. Size is held at the
   header's, because shrinking it would drop the letters below the 18.66px bold that
   lets the mango tile pass contrast as large text. */
.footer-brand { margin: 0 0 .7rem; }
/* --- footer destinations column ----------------------------------------------
   A country then its cities, indented, in the same single-column rhythm as the other
   footer navs so all four columns share one baseline grid. */
.footer-dest-col { display: flex; flex-direction: column; gap: .35rem; }
.fd-country {
  display: flex; align-items: center; gap: .4rem;
  font-weight: 600; font-size: .9rem; text-decoration: none; color: var(--ink);
  margin-top: .25rem;
}
.fd-country:first-of-type { margin-top: 0; }
.fd-country img {
  width: 18px; height: 12px; object-fit: cover; border-radius: 2px; display: block;
}
.fd-country:hover { color: var(--accent-ink); }
.fd-city {
  font-size: .88rem; text-decoration: none; color: var(--ink-soft);
  padding-left: calc(18px + .4rem);
}
.fd-city:hover { color: var(--accent); }

.footer-legal { padding: 1.5rem 1.25rem 2rem; }
@media (max-width: 980px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (max-width: 700px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .footer-grid { grid-template-columns: 1fr; } }

/* --- hero + doc --- */
.hero { background: var(--hero-bg); padding: 3rem 0 2.5rem; margin-bottom: 2rem; }
.hero h1 { margin: 0 0 .5rem; font-size: clamp(1.9rem, 5vw, 2.8rem); }

/* --- homepage: heading, then a lead story with three beside it ---------------
   No colour band. The H1 is sized as a page heading rather than a masthead, since
   its job is to say what the site covers, not to fill the first screen. */
.home-head { padding: 1.75rem 0 1.25rem; }
.home-head h1 {
  margin: 0 0 .35rem;
  font-size: clamp(1.5rem, 3.2vw, 2rem);
  line-height: 1.2;
}
.home-head .standfirst { margin: 0; }

.lead-block {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: 1.5rem;
  margin-bottom: 2.25rem;
  align-items: start;
}
/* The lead is the same card component, just given room: one definition to maintain,
   and it cannot drift from the grid below. */
.lead-main .card-title { font-size: 1.45rem; line-height: 1.2; }
.lead-main .card-blurb {
  font-size: .97rem;
  -webkit-line-clamp: 4;
  line-clamp: 4;
}
.lead-main .card-body { padding: 1rem 1.15rem 1.15rem; }

.lead-subs { list-style: none; margin: 0; padding: 0; display: grid; gap: .85rem; }
.lead-subs > li { border-bottom: 1px solid var(--line); padding-bottom: .85rem; }
.lead-subs > li:last-child { border-bottom: 0; padding-bottom: 0; }
.lead-subs a {
  display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: .8rem;
  text-decoration: none; color: var(--ink); align-items: start;
}
.lead-subs .sub-media { position: relative; display: block; }
.lead-subs img {
  width: 108px; aspect-ratio: 16 / 9; height: auto; object-fit: cover;
  border-radius: 7px; display: block; background: var(--paper-alt);
}
.lead-subs .card-flag {
  right: .25rem; bottom: .25rem; width: 24px; height: 16px;
}
.lead-subs .sub-title {
  display: block; font-weight: 600; font-size: .95rem; line-height: 1.3;
}
.lead-subs a:hover .sub-title { color: var(--accent-ink); }
.lead-subs time { display: block; font-size: .72rem; color: var(--ink-faint);
  margin-top: .25rem; text-transform: uppercase; letter-spacing: .05em; }

@media (max-width: 780px) {
  .lead-block { grid-template-columns: 1fr; gap: 1.25rem; }
  .lead-main .card-title { font-size: 1.25rem; }
}

.doc { padding: 1.5rem 0 0; }
.doc-head { margin-bottom: 1.75rem; }
.doc-head h1 {
  font-size: clamp(1.7rem, 4.2vw, 2.4rem); line-height: 1.2; margin: 0 0 .6rem;
  max-width: 30ch;
}
.standfirst {
  font-size: 1.14rem; color: var(--ink-soft); max-width: var(--measure); margin: 0 0 1rem;
}
.byline {
  display: flex; gap: 1rem; flex-wrap: wrap; font-size: .875rem; color: var(--ink-faint);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: .6rem 0;
}

.prose { max-width: var(--measure); font-family: var(--serif); font-size: 1.06rem; }
.prose h2 { font-family: var(--font); font-size: 1.45rem; margin: 2.25rem 0 .6rem; }
.prose h3 { font-family: var(--font); font-size: 1.15rem; margin: 1.75rem 0 .4rem; }
.prose p, .prose ul, .prose ol { margin: 0 0 1.1rem; }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li { margin-bottom: .4rem; }
.prose a[data-il] { text-decoration-style: solid; }

/* --- breadcrumbs --- */
.breadcrumbs { padding: 1rem 0 0; font-size: .85rem; }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; }
.breadcrumbs li + li::before { content: "/"; color: var(--ink-faint); margin-right: .4rem; }
.breadcrumbs a { color: var(--ink-soft); text-decoration: none; }

/* --- fact strip --- */
.factstrip {
  /* One row, always. Six facts wrapped onto two lines read as two unrelated groups,
     and the second line looked like an afterthought. When the row genuinely will not
     fit it scrolls sideways rather than folding. */
  display: flex; flex-wrap: nowrap; gap: 1.75rem; margin: 0 0 2rem; padding: 1rem 1.25rem;
  background: var(--paper-alt); border: 1px solid var(--line); border-radius: var(--radius);
  overflow-x: auto; scrollbar-width: none;
}
.factstrip::-webkit-scrollbar { display: none; }
.factstrip div { flex: 0 0 auto; white-space: nowrap; }
.factstrip dt { font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); }
.factstrip dd { margin: .15rem 0 0; font-weight: 600; }

/* --- topic nav --- */
.topic-nav {
  margin: 0 0 2rem; padding: 1rem 1.25rem; border: 1px solid var(--line);
  border-radius: var(--radius);
}
.topic-nav-head { margin: 0 0 .6rem; font-weight: 600; font-size: .95rem; }
.topic-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.topic-nav a {
  display: inline-block; padding: .3rem .7rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: .9rem; text-decoration: none; background: var(--paper);
}
.topic-nav a.money { border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* --- cards --- */
.children { margin: 2.5rem 0; }
.children h2 { font-size: 1.35rem; margin: 0 0 1rem; }
.card-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: .85rem;
}
.card a {
  display: flex; flex-direction: column; gap: .2rem; padding: .85rem 1rem;
  border: 1px solid var(--line); border-radius: var(--radius); text-decoration: none;
  background: var(--paper); height: 100%;
}
.card a:hover { border-color: var(--accent); }
.card-title { font-weight: 600; color: var(--ink); }
.card-meta { font-size: .8rem; color: var(--ink-faint); }

.inline-list { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem 1rem; padding: 0; margin: 0; }

.article-list { list-style: none; padding: 0; margin: 0; }
.article-list > li { padding: 1rem 0; border-bottom: 1px solid var(--line); }
.article-list a { font-weight: 600; font-size: 1.05rem; }
.article-list time { display: block; font-size: .8rem; color: var(--ink-faint); margin-top: .15rem; }
.article-list p { margin: .35rem 0 0; font-size: .95rem; }

/* --- sources strip -----------------------------------------------------------
   A continuous marquee: two identical tracks, the second sliding in exactly as the
   first slides out, so the loop has no seam. Pure CSS - a scrolling logo bar is not
   worth a byte of JavaScript. */
.sources {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 1rem 0; margin: 0 0 2.25rem;
  display: flex; align-items: center; gap: 1.25rem;
}
.sources-label {
  margin: 0; flex: 0 0 auto;
  font-size: .72rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-faint);
}
.sources-viewport {
  position: relative; overflow: hidden; flex: 1 1 auto;
  /* Fades at both ends, so items enter and leave rather than being cut off. */
  mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
  display: flex; gap: 2.5rem; width: 100%;
}
.sources-track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: 2.5rem; flex: 0 0 auto;
  animation: sources-scroll 34s linear infinite;
}
.sources-viewport:hover .sources-track { animation-play-state: paused; }
.sources-track li { white-space: nowrap; }
.sources-track a, .sources-track span {
  font-size: .95rem; font-weight: 600; color: var(--ink-soft); text-decoration: none;
  letter-spacing: -.01em;
}
.sources-track a:hover { color: var(--accent-ink); }
@keyframes sources-scroll {
  from { transform: translateX(0); }
  /* The gap belongs to the track, so the shift is width + one gap. */
  to   { transform: translateX(calc(-100% - 2.5rem)); }
}
@media (prefers-reduced-motion: reduce) {
  .sources-track { animation: none; }
  .sources-viewport { overflow-x: auto; }
  /* Duplicated track is decorative; with motion off it is just repetition. */
  .sources-track[aria-hidden="true"] { display: none; }
}
@media (max-width: 620px) {
  .sources { flex-direction: column; align-items: flex-start; gap: .55rem; }
}

/* Press variant: the wordmarks carry more weight than a source credit does, since
   this strip is a claim rather than an attribution. Real SVGs, when supplied, sit at
   24px and keep their own colour. */
.sources--press { padding: 1.15rem 0; }
.sources--press .sources-track { gap: 3.5rem; }
.sources--press .sources-track a,
.sources--press .sources-track span {
  font-size: 1.15rem; font-weight: 700; color: var(--ink); letter-spacing: .01em;
  display: inline-flex; align-items: center;
}
.sources--press .sources-track img {
  height: 24px; width: auto; display: block;
}
@keyframes sources-scroll-press {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% - 3.5rem)); }
}
.sources--press .sources-track { animation-name: sources-scroll-press; }

/* Author stats: the fact strip, but wrapping - a name list of countries has no fixed
   width, and forcing it into one scrolling row would hide the rest. */
.author-stats { flex-wrap: wrap; margin-bottom: 2.25rem; }
.author-stats div { white-space: normal; }
.doc .lede { font-size: 1.08rem; color: var(--ink); }

/* Read next. A rule and generous space above it, so it reads as the end of the article
   rather than more of it. */
.read-next {
  margin: 3rem 0 0;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.read-next > h2 { margin: 0 0 1.1rem; font-size: 1.15rem; }
/* Two columns inside the article measure, three once the rail is gone. */
@media (min-width: 1040px) {
  .read-next .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1400px) {
  .read-next .cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- tool cards --------------------------------------------------------------
   No image, so the badge does the work an image would: currency code or UTC offset,
   set in the brand blue, large enough to scan down a column. */
.tool-section { margin: 0 0 2.5rem; }
.tool-section h2 { margin-bottom: .3rem; }
.tool-section > .muted { margin: 0 0 1.1rem; max-width: var(--measure); }
.tool-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); gap: .85rem;
}
.tool-card {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.tool-card:hover { border-color: var(--accent); box-shadow: 0 2px 10px rgb(0 0 0 / .06); }
.tool-card > a {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .85rem;
  align-items: center; padding: .85rem .95rem; text-decoration: none; height: 100%;
}
.tool-badge {
  display: grid; place-items: center;
  min-width: 3.4rem; height: 2.5rem; padding: 0 .5rem;
  border-radius: 7px; background: var(--tile-1); color: #fff;
  font-weight: 700; font-size: .95rem; letter-spacing: .01em; white-space: nowrap;
}
/* Clocks get their own hue, so the two kinds are distinguishable at a glance in a
   mixed column without needing to read the label. */
.tool-timezone .tool-badge { background: var(--tile-4); font-size: .85rem; }
.tool-text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.tool-title { font-weight: 600; color: var(--ink); line-height: 1.25; }
.tool-card:hover .tool-title { color: var(--accent-ink); }
.tool-desc {
  font-size: .82rem; color: var(--ink-soft); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}

/* --- guides index ------------------------------------------------------------- */
.guide-country { margin: 0 0 2.75rem; }
.guide-country h2 { display: flex; align-items: center; gap: .55rem; margin-bottom: .75rem; }
.guide-country h2 a { text-decoration: none; color: var(--ink); }
.guide-country h2 a:hover { color: var(--accent-ink); }
.gc-flag {
  width: 28px; height: 19px; object-fit: cover; border-radius: 3px;
  border: 1px solid var(--line); display: block;
}
.guide-topics {
  list-style: none; margin: 0 0 1.4rem; padding: 0;
  display: flex; flex-wrap: wrap; gap: .5rem;
}
.guide-topics a {
  display: inline-block; padding: .32rem .75rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: .9rem; text-decoration: none; background: var(--paper);
  color: var(--ink);
}
.guide-topics a:hover { border-color: var(--accent); color: var(--accent-ink); }
.guide-topics a.money { border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.guide-sub {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-faint); margin: 0 0 .7rem;
}

/* The named-provider block. Reads as a statement rather than a banner: it is telling
   the reader who we buy from and that we earn from it, which is a disclosure as much as
   a call to action. */
.provider-cta { border-left: 4px solid var(--tile-1); }
.provider-cta h2 { font-size: 1.05rem; margin-top: 0; }
.provider-cta p { margin-bottom: .9rem; }

/* --- monetization --- */
.disclosure {
  background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: var(--radius);
  padding: .85rem 1.1rem; margin: 0 0 2rem; font-size: .9rem;
}
.disclosure p { margin: 0; }

.offers { margin: 0 0 2.5rem; }
.offer-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.offer {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.25rem;
  background: var(--paper);
}
.offer-head { display: flex; align-items: center; gap: .6rem; }
.offer-partner { font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); }
.badge {
  background: var(--accent); color: #fff; font-size: .7rem; padding: .1rem .45rem;
  border-radius: 999px; text-transform: uppercase; letter-spacing: .04em;
}
.offer-title { margin: .3rem 0 .75rem; font-size: 1.1rem; }
.offer-specs { display: flex; flex-wrap: wrap; gap: 1.25rem; margin: 0 0 1rem; }
.offer-specs dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); }
.offer-specs dd { margin: .1rem 0 0; font-weight: 600; }

.btn {
  display: inline-block; background: var(--accent); color: #fff; padding: .55rem 1.1rem;
  border-radius: 8px; text-decoration: none; font-weight: 600; font-size: .95rem; border: 0;
}
.btn:hover { background: var(--accent-ink); color: #fff; }

.cta-box {
  background: var(--accent-soft); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.25rem 1.4rem; margin: 2.5rem 0;
}
.cta-box h2 { margin: 0 0 .5rem; font-size: 1.2rem; }
.cta-box p { margin: 0 0 1rem; max-width: var(--measure); }

/* --- content blocks --- */
.faq dl { margin: 0; }
.faq-item { border-bottom: 1px solid var(--line); padding: .9rem 0; }
.faq-item dt { font-weight: 600; }
.faq-item dd { margin: .35rem 0 0; color: var(--ink-soft); }

.key-facts ul { list-style: none; padding: 0; }
.key-facts li { padding: .5rem 0; border-bottom: 1px solid var(--line); }

.table-wrap { margin: 2rem 0; overflow-x: auto; }
.table-wrap table { border-collapse: collapse; width: 100%; font-family: var(--font); font-size: .95rem; }
.table-wrap th, .table-wrap td { text-align: left; padding: .55rem .7rem; border-bottom: 1px solid var(--line); }
.table-wrap th { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-faint); }
.table-wrap figcaption { font-size: .85rem; color: var(--ink-faint); margin-bottom: .5rem; }

.pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; margin: 2rem 0; }
.pros-cons > div { border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.2rem; }
.pros-cons h3 { margin: 0 0 .5rem; font-size: 1rem; }
@media (max-width: 640px) { .pros-cons { grid-template-columns: 1fr; } }

.pull-quote {
  margin: 2rem 0; padding-left: 1.1rem; border-left: 3px solid var(--accent);
  font-family: var(--serif); font-size: 1.15rem; color: var(--ink-soft);
}
.figure { margin: 2rem 0; }
.figure picture { display: block; }
.figure img { max-width: 100%; height: auto; border-radius: var(--radius); display: block; }
.figure figcaption { font-size: .85rem; color: var(--ink-faint); margin-top: .5rem; }

.calc-grid { display: grid; gap: .6rem; margin: 1rem 0; max-width: 26rem; }
.calc-grid label { display: flex; justify-content: space-between; gap: 1rem; align-items: center; }
.calc-grid input[type="number"] { width: 6rem; padding: .3rem .5rem; border: 1px solid var(--line); border-radius: 6px; }
.calc-out { font-weight: 600; background: var(--accent-soft); padding: .75rem 1rem; border-radius: 8px; }

.map-static {
  background: var(--paper-alt); border: 1px dashed var(--line); border-radius: var(--radius);
  padding: 2rem; text-align: center;
}
.widget { margin: 2.5rem 0; }
.sibling-nav { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line); font-size: .95rem; }
.sibling-nav p { margin: 0 0 .35rem; color: var(--ink-faint); }
.related { margin: 2.5rem 0; }

.search-page { display: flex; gap: .5rem; margin: 0 0 2rem; }
.search-page input { flex: 1; padding: .6rem .9rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper); color: var(--ink); }
.search-page button { background: var(--accent); color: #fff; border: 0; padding: 0 1.2rem; border-radius: 8px; font-weight: 600; }

/* --- detached FAQ section ---------------------------------------------------
   FAQs sit outside the prose column: they are a reference list, not part of the
   argument, and they carry FAQPage structured data. Native <details> gives
   keyboard and screen-reader behaviour for free, and works with JS disabled. */
.faq-section {
  margin: 3rem 0 0;
  padding: 1.75rem 0 0;
  border-top: 2px solid var(--line);
}
.faq-section > h2 { font-size: 1.4rem; margin: 0 0 1.25rem; }
.faq-list { display: grid; gap: .5rem; max-width: var(--measure); }
.faq-item {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  overflow: hidden;
}
.faq-item > summary {
  cursor: pointer;
  padding: .85rem 1.1rem;
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: "+";
  font-weight: 400;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--accent);
  flex: none;
}
.faq-item[open] > summary::after { content: "\2212"; }
.faq-item[open] > summary { border-bottom: 1px solid var(--line); }
.faq-item > summary:hover { background: var(--paper-alt); }
.faq-answer { padding: .9rem 1.1rem 1.1rem; }
.faq-answer p { margin: 0; color: var(--ink-soft); font-family: var(--serif); }

/* Figure credits: CC BY and CC BY-SA require visible attribution. */
.figure figcaption { display: flex; flex-direction: column; gap: .2rem; }
.fig-caption { color: var(--ink-soft); }
.fig-credit a { color: var(--ink-faint); }

/* --- share bars --------------------------------------------------------------
   Two per article, top and bottom, so a reader who finishes the page does not
   have to scroll back up. Icons are inline SVG: no icon font, no extra request,
   no layout shift. */
.share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem .9rem;
  margin: 1.5rem 0;
  padding: .8rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* Directly under the byline the share bar is part of the same meta block, so it
   reuses the byline's bottom rule instead of drawing a second one across a gap.
   Both sides have to give: .share-top drops its own top margin and border, and
   .doc-head drops the margin-bottom that would otherwise hold the gap open.
   :has() is the only way to reach backwards to the preceding sibling. */
.doc-head:has(+ .share-top) { margin-bottom: 0; }
.doc-head + .share-top {
  margin-top: 0;
  border-top: none;
}
.share-bottom {
  margin-top: 2.5rem;
  border-top: 2px solid var(--line);
  border-bottom: none;
  padding-bottom: 0;
}
.share-label {
  margin: 0;
  font-size: .8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-faint);
}
.share-list {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.15rem;
  height: 2.15rem;
  border: 0;
  border-radius: 50%;
  background: var(--share-bg, var(--ink));
  color: #fff;
  cursor: pointer;
  padding: 0;
  transition: transform .12s ease, filter .12s ease;
}
.share-btn:hover, .share-btn:focus-visible { transform: translateY(-1px); filter: brightness(1.1); }
.share-btn svg { width: 1.05rem; height: 1.05rem; fill: currentColor; display: block; }
.share-btn.x         { --share-bg: #000000; }
.share-btn.facebook  { --share-bg: #1877f2; }
.share-btn.pinterest { --share-bg: #e60023; }
.share-btn.whatsapp  { --share-bg: #25d366; }
.share-btn.telegram  { --share-bg: #229ed9; }
.share-btn.reddit    { --share-bg: #ff4500; }
.share-btn.linkedin  { --share-bg: #0a66c2; }
.share-btn.email     { --share-bg: #5b6675; }
.share-btn.copy      { --share-bg: var(--accent); }
.share-feedback {
  margin: 0;
  font-size: .8rem;
  color: var(--accent-ink);
  min-height: 1.1em;
  flex-basis: 100%;
}
.share-feedback:empty { min-height: 0; }
.share-fallback { display: block; font-size: .8rem; width: 100%; }
.share-fallback input { width: 100%; padding: .35rem .5rem; }

/* --- place maps -------------------------------------------------------------
   Generated ahead of time and served locally. Dimensions are always set so the
   map cannot shift the page while it loads. */
/* The map lives in the rail from the breakpoint where the rail appears; below it
   the rail is display:none and this is the only copy. Exactly one is visible at
   any width, and both point at the same file. */
@media (min-width: 1040px) { .place-map-inline { display: none; } }

/* --- map in the rail, and its expanded view ---------------------------------
   Drag-to-pan inside an overflow container rather than a slippy map: the raster
   is already stitched and stored locally, so this costs one request to our own
   origin and keeps the no-third-party-tiles guarantee that build-maps exists for. */
.rail-map-open {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  position: relative;
  line-height: 0;
}
.rail-map-open img,
.rail-map-open svg {
  width: 100%;
  height: auto;
  display: block;
  background: var(--paper-alt);
}
.rail-map-hint {
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  padding: .15rem .45rem;
  border-radius: 4px;
  background: rgba(0, 0, 0, .62);
  color: #fff;
  font-size: .68rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.6;
}
.rail-map-open:hover .rail-map-hint,
.rail-map-open:focus-visible .rail-map-hint { background: var(--accent); }
.rail-map-credit { margin: 0; padding: .45rem .85rem .5rem; font-size: .7rem; }

.map-dialog {
  border: 0;
  border-radius: var(--radius);
  padding: 0;
  width: min(92vw, 1100px);
  max-width: 92vw;
  background: var(--paper);
  color: var(--ink);
}
.map-dialog::backdrop { background: rgba(0, 0, 0, .55); }
.map-pan {
  overflow: auto;
  max-height: min(72vh, 720px);
  cursor: grab;
  background: var(--paper-alt);
  /* The image sits at its natural size so there is something to pan to; without
     this it would shrink to fit and panning would be a no-op. */
  overscroll-behavior: contain;
}
.map-pan.is-dragging { cursor: grabbing; user-select: none; }
.map-pan img, .map-pan svg { display: block; max-width: none; }
.map-dialog-foot { margin: 0; padding: .55rem .9rem .7rem; font-size: .74rem; }

@media (prefers-reduced-motion: reduce) {
  .map-pan { scroll-behavior: auto; }
}

.place-map { margin: 0 0 2rem; }
.place-map img,
.place-map svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper-alt);
}
.place-map figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .5rem;
  margin-top: .45rem;
  font-size: .8rem;
}
.place-map-outline svg { padding: .5rem; }
.outline-shape {
  fill: var(--accent-soft);
  stroke: var(--accent);
  stroke-width: 1.2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.outline-pin { fill: var(--accent); stroke: var(--paper); stroke-width: 2; }

/* --- article + cluster rail --------------------------------------------------
   Single column until there is genuinely room for a second one. The rail is
   navigation, so it may collapse away entirely on small screens; the floating
   button below carries the same links there. */
.doc-layout { display: block; }

@media (min-width: 1040px) {
  .doc-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 288px;
    gap: 2.5rem;
    align-items: start;
  }
  .doc-layout > .doc { min-width: 0; }
  .rail {
    /* Not sticky, on purpose.
       It was `top: 1.5rem` with `max-height` + `overflow-y: auto`, which pinned it and
       gave it a scrollbar inside the page's scrollbar. Anchoring to the bottom instead
       did nothing, because bottom-sticky only stops an element going too low. Holding it
       in view with a measured negative offset worked, and still left a panel frozen
       beside a moving article.
       It is a list of links, not a control panel, so it scrolls with the column like
       everything else. */
    padding: 1.1rem 0 1.5rem;
    font-size: .9rem;
  }
}
.rail { display: none; }
@media (min-width: 1040px) { .rail { display: block; } }

.rail-group { margin-bottom: 1.4rem; }
.rail-group-title {
  margin: 0 0 .5rem;
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--ink-faint);
}
.rail-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.rail-item a {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr);
  gap: .6rem;
  align-items: center;
  text-decoration: none;
  color: var(--ink);
}
.rail-item a:hover .rail-title { color: var(--accent); text-decoration: underline; }
.rail-item img {
  width: 80px; height: 45px; object-fit: cover;
  border-radius: 6px; display: block; background: var(--paper-alt);
}
.rail-item a:not(:has(img)) { grid-template-columns: minmax(0, 1fr); }
.rail-title { font-size: .875rem; line-height: 1.35; }

/* "See all 14" had no rule of its own, so it rendered as a default paragraph:
   full inherited margin, flush against the panel edge while the list above it
   was inset. Treated as a footer action instead - same inset as the list, its
   own line, and weighted enough to read as the control it is. */
.rail-more { margin: .55rem 0 0; font-size: .8rem; }
.rail-more a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.rail-more a:hover { text-decoration: underline; }

/* --- mobile: floating button + dialog ---------------------------------------
   Hidden wherever the sticky rail is visible, so the two never both appear. */
.rail-fab {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 60;
  width: 3.1rem;
  height: 3.1rem;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  box-shadow: 0 3px 14px rgba(0, 0, 0, .28);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.rail-fab svg { width: 1.4rem; height: 1.4rem; fill: currentColor; }
.rail-fab:active { transform: scale(.96); }
@media (min-width: 1040px) { .rail-fab { display: none; } }

.rail-dialog {
  border: 0;
  border-radius: 14px 14px 0 0;
  padding: 0;
  width: 100%;
  max-width: 34rem;
  max-height: 82vh;
  margin: auto auto 0;
  background: var(--paper);
  color: var(--ink);
}
.rail-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.rail-dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.1rem .75rem;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--paper);
}
.rail-dialog-head h2 { margin: 0; font-size: 1.05rem; }
.rail-dialog-close {
  border: 0; background: none; font-size: 1.7rem; line-height: 1;
  color: var(--ink-soft); cursor: pointer; padding: 0 .25rem;
}
.rail-dialog-body { padding: 1rem 1.1rem 1.5rem; overflow-y: auto; }
.rail-dialog .rail-item img { width: 80px; height: 45px; }

/* --- disclosure -------------------------------------------------------------
   Compact line next to the links, fuller block at the foot. Only rendered on
   pages that actually carry affiliate links. */
.disclosure-inline {
  margin: 0 0 1rem;
  padding: .55rem .8rem;
  border-left: 3px solid var(--warn-line);
  background: var(--warn-bg);
  border-radius: 0 6px 6px 0;
  font-size: .85rem;
  max-width: var(--measure);
}
.disclosure { margin: 2.5rem 0 0; }

/* --- card thumbnails --------------------------------------------------------
   Real resized derivatives, dimensions always set so a grid cannot reflow. */
.card a { padding: 0; overflow: hidden; }
.card-thumb {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  /* `height: auto` is doing real work. The markup carries width="480" height="270"
     so the browser can reserve space before the file arrives, and that attribute
     becomes a presentation hint that beats `aspect-ratio` unless height is released.
     Without this every card image rendered exactly 270px tall whatever its column
     width, so a grid of cards had images at three different shapes. */
  height: auto;
  display: block; background: var(--paper-alt);
}
.card-body { padding: .75rem .9rem .85rem; display: flex; flex-direction: column; gap: .2rem; }
.card-credit { font-size: .65rem; color: var(--ink-faint); }
.article-list .al-item { display: grid; grid-template-columns: 160px minmax(0,1fr); gap: 1rem; }
.article-list .al-item img {
  width: 160px; aspect-ratio: 16/9; object-fit: cover; border-radius: 8px; display: block;
}
@media (max-width: 560px) {
  .article-list .al-item { grid-template-columns: 96px minmax(0,1fr); }
  .article-list .al-item img { width: 96px; }
}

/* --- byline + top share bar are one meta block -------------------------------
   The byline closes with a rule and the share bar opens with one, so stacking
   them produced two horizontal lines separated by the share bar's top margin.
   Collapse the pair: the block is bounded by the byline's top rule and the share
   bar's bottom rule, with nothing between them.

   The :has() rules keep the byline's own bottom rule on the rare page that has a
   byline and no share bar, so removing the border here cannot leave that case
   looking unfinished. */
.doc-head:has(+ .share) .byline {
  border-bottom: 1px solid var(--line);
  padding-bottom: .55rem;
}
.doc-head:has(.byline) + .share.share-top {
  border-top: 0;          /* the byline's bottom rule is the divider */
  margin-top: 0;
  padding-top: .55rem;    /* matches the byline's, so the rule sits centred */
  padding-bottom: .7rem;
}

/* The live-region paragraph is empty until a copy happens. As a flex item with
   flex-basis:100% it still forced a second row and picked up the container's row
   gap, padding the bar out by ~10px for no visible content. */
.share-feedback:empty { display: none; }

/* Browsers without :has() keep both rules, which is a cosmetic fallback rather
   than a broken layout. */
@supports not selector(:has(*)) {
  .share-top { border-top: 0; margin-top: 0; }
}

/* --- place cards ------------------------------------------------------------
   A name and a population number is a table row, not a card. Each card carries an
   image, a compact fact line and a sentence saying why you would go. Aspect ratio
   is fixed so a grid of them cannot reflow as images arrive. */
.place-card .card-body { gap: .3rem; }
.card-blurb {
  font-size: .85rem;
  color: var(--ink-soft);
  line-height: 1.45;
}
.card-thumb-empty {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background:
    linear-gradient(135deg, var(--accent-soft) 0%, var(--paper-alt) 100%);
}
.card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  overflow: hidden;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.card a { border: 0; border-radius: 0; background: none; }
.card:hover { border-color: var(--accent); box-shadow: 0 2px 10px rgba(0, 0, 0, .06); }
.card:hover .card-title { color: var(--accent-ink); }
.card-grid {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1rem;
}
/* One or two children should not stretch to fill a wide row. */
.card-grid { justify-content: start; }
.card-grid > .card { max-width: 340px; }
.card .card-meta {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-faint);
}
.card .card-title { font-size: 1.02rem; line-height: 1.25; }

/* --- rail panels ------------------------------------------------------------
   Boxed so the rail reads as a distinct column of modules rather than a list
   floating beside the article. Kept light: a filled panel that competed with the
   body copy would pull the eye away from the thing people came to read. */
@media (min-width: 1040px) {
  .rail { border-top: 0; padding-top: .25rem; }
  /* No frame. A heading and a list, divided from the next group by a hairline - the
     same treatment the footer columns get. Boxed, the column read as a widget bolted to
     the side of the article; flush, it reads as part of it. */
  .rail-panel {
    border: 0;
    background: none;
    border-radius: 0;
    padding: 0 0 1.1rem;
    margin-bottom: 1.1rem;
    border-bottom: 1px solid var(--line);
  }
  .rail-panel:last-of-type { border-bottom: 0; margin-bottom: 0; }
  .rail-panel .rail-group-title {
    margin: 0 0 .6rem;
    padding: 0;
    background: none;
    color: var(--ink-faint);
    letter-spacing: .07em;
  }
  .rail-panel > ul { padding: 0; }
  .rail-panel .rail-more { margin: .6rem 0 0; padding: 0; border-top: 0; }
  .rail-panel .rail-title { color: var(--ink); }
  .rail-panel .rail-item img { border-radius: 5px; }
  .rail-panel .rail-item a:hover .rail-title { text-decoration: none; }
  .rail-panel .rail-item a:hover { color: var(--accent-ink); }
}
/* Inside the mobile dialog the panels would be boxes within a box. */
.rail-dialog .rail-panel {
  border: 0; background: none; padding: 0; margin-bottom: 1.25rem;
}
.rail-dialog .rail-group-title {
  border-bottom: 1px solid var(--line); padding-bottom: .4rem;
}

/* --- entity cards, final pass ------------------------------------------------
   The previous version had two faults visible on the attractions grid: whole
   sentences were landing in the small-caps `meta` slot and rendering in capitals,
   and cards stepped raggedly because descriptions differ in length.

   `meta` is now strictly a short label (small caps) and `blurb` is a sentence in
   normal case, clamped to three lines so a row keeps one baseline. */
.entity-card { display: flex; }
.entity-card > a {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  gap: 0;
}
.card-grid { align-items: stretch; }

.entity-card .card-body {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .8rem .95rem 1rem;
  flex: 1;
}
.entity-card .card-meta {
  order: -1;                         /* label sits above the title */
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-weight: 700;
  color: var(--accent-ink);
}
.entity-card .card-title {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.25;
  text-transform: none;              /* never inherit the meta casing */
  letter-spacing: normal;
}
.entity-card .card-blurb {
  text-transform: none;
  letter-spacing: normal;
  font-size: .875rem;
  color: var(--ink-soft);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  line-clamp: 3;
  overflow: hidden;
}
.entity-card .card-credit { margin-top: auto; padding-top: .4rem; }

/* --- three-column card grid --------------------------------------------------
   Column count by available width: one on a phone, two from about a tablet, three
   once the wrap is wide enough that a card is not squeezed. Explicit breakpoints
   rather than auto-fill, because auto-fill on a 1080px wrap can land on four thin
   columns, and a 250px-wide card crops its title to two ragged lines.

   Used by both home-page grids so destinations and articles share one column
   rhythm; two grids at different card widths read as an accident. The `.card-grid`
   max-width cap is lifted here, since these cards should fill their column. */
.cols-3 { grid-template-columns: 1fr; gap: 1.1rem; }
.cols-3 > .card { max-width: none; }
@media (min-width: 620px) {
  .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 940px) {
  .cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* A date is a label, not a heading: keep it quieter than the entity-card meta,
   which is a category. */
.article-grid .card-meta {
  color: var(--ink-faint);
  font-weight: 600;
  letter-spacing: .06em;
}
.article-grid .card-title { font-size: 1.02rem; }

/* --- flag badge on a card image ---------------------------------------------
   Sits over the photograph's bottom-right corner so the destination is readable
   before the title is. A white plate and a hairline keep it legible on any
   photograph, since a flag dropped straight onto a busy image disappears. */
.card-media { position: relative; display: block; }
.card-flag {
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  width: 30px;
  height: 20px;
  object-fit: cover;
  border-radius: 3px;
  /* Flat: no plate, no padding, no shadow. The flag sits on the photograph as it is.
     Its own corner radius is the only treatment. */
}

/* Placeholder for a card with no photograph yet. A designed tile with the
   initial, rather than a street map standing in as a hero. */
.card-thumb-empty {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-ink) 100%);
}
.card-thumb-initial {
  font-size: 2.4rem;
  font-weight: 700;
  color: rgba(255, 255, 255, .82);
  line-height: 1;
}

/* Fact-strip values that are links should read as values first, links second.
   A dotted underline signals "there is more here" without turning a data table
   into a wall of blue: the same convention as an abbreviation or a glossary term. */
/* Flag beside its ISO code: the image alone is a guessing game for anyone who
   does not recognise it. */
.fact-flag { display: flex; align-items: center; gap: .4rem; }
.fact-flag img {
  width: 30px; height: 20px; object-fit: cover;
  border: 1px solid var(--line); border-radius: 3px; display: block;
}

.factstrip dd a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
  padding-bottom: 1px;
  cursor: help;
}
.factstrip dd a:hover,
.factstrip dd a:focus-visible {
  color: var(--accent-ink);
  border-bottom-style: solid;
}

/* --- time tool --------------------------------------------------------------- */
.tz-now { display: flex; flex-direction: column; gap: .15rem; margin: 0 0 1.25rem; }
.tz-clock {
  font-size: clamp(2.2rem, 7vw, 3rem);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;   /* stops the clock jittering as it ticks */
  color: var(--accent-ink);
}
.tz-date { font-size: .9rem; }
.tz-notes { margin: 1.25rem 0 0; padding-left: 1.1rem; font-size: .92rem; color: var(--ink-soft); }
.tz-notes li { margin-bottom: .5rem; }
.tz-cell { font-variant-numeric: tabular-nums; }

/* --- programmatic tool panels ---
   The converter and clock are the reason these pages exist, so they are given a
   surface of their own rather than floating on the page background. Sitting the
   tool in a panel also separates "the answer" from the prose explaining it. */
.tool {
  background: var(--paper-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem 1.4rem;
  margin: 1.75rem 0 2.25rem;
}
.tool > h2 {
  margin: 0 0 1rem;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-faint);
}
.tool .conv-row,
.tool .tz-row {
  display: flex; flex-wrap: wrap; gap: .9rem; align-items: flex-end;
}
.tool .conv-field { display: flex; flex-direction: column; gap: .3rem; flex: 1 1 8rem; }
.tool .conv-field > span {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-faint);
}
.tool input,
.tool select {
  font: inherit; padding: .55rem .6rem;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper); color: inherit; width: 100%;
}
.tool input:focus, .tool select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The answer, given the weight it deserves. */
.tool .conv-result,
.tool .tz-clock {
  font-size: 1.6rem; font-weight: 650; line-height: 1.2;
  margin: 1.1rem 0 .3rem; color: var(--accent-ink);
}
.tool .conv-unit,
.tool .tz-meta { color: var(--ink-faint); font-size: .9rem; margin: 0; }
.tool .tool-note {
  margin: 1rem 0 0; padding-top: .85rem; border-top: 1px solid var(--line);
  font-size: .85rem; color: var(--ink-faint);
}
@media (prefers-color-scheme: dark) {
  .tool .conv-result, .tool .tz-clock { color: var(--accent); }
}

/* The FAQ question is an h3 for outline purposes; it must not inherit h3 sizing. */
.faq-item > summary h3 {
  display: inline;
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  font-family: var(--font);
  line-height: 1.4;
}
