/* sunset-tracker.com — single stylesheet, no framework.
   Spec reference: CLAUDE_CODE_SPEC.md §12 (Phase 2), budget 30 KB.
   Palette carried over from the previous site so the brand stays recognisable. */

/* ---------------------------------------------------------------- fonts

   Self-hosted rather than loaded from Google Fonts. The previous site pulled
   both faces from fonts.googleapis.com; the rebuild kept the names in the font
   stacks and dropped the loading, so every visitor without them installed saw
   system fonts and the brand look quietly changed.

   Self-hosting keeps the CSP at font-src 'self', removes a third-party request
   from the critical path, and avoids sending every reader's IP to another
   company. Variable files, so one download covers every weight in use.

   unicode-range means the latin-ext files only download on pages that need
   them — Tromsø and Reykjavík do, London does not. */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/dm-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/dm-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: dark;

  --bg-base:      #0b0e14;
  --bg-surface:   #12161e;
  --bg-elevated:  #1a1f2b;
  --bg-overlay:   #222838;

  --line-subtle:  rgba(255, 255, 255, 0.06);
  --line:         rgba(255, 255, 255, 0.10);
  --line-strong:  rgba(255, 255, 255, 0.16);

  --text:         #e8eaed;
  --text-dim:     #9aa0ad;   /* 6.97:1 on --bg-surface */
  /* Was #6b7280, which measured 3.74:1 on --bg-surface and failed WCAG AA for
     normal text. #858d9b is 5.47:1 and still reads as the quiet tier. */
  --text-mute:    #858d9b;

  --orange:       #f97316;
  --amber:        #f59e0b;
  --rose:         #f43f5e;
  /* --rose is fine as a swatch but measured 4.43:1 as text on the highlighted
     today row, just under AA. The table text takes a lighter step; the swatch
     keeps the brand colour. */
  --rose-text:    #f65a74;
  --violet:       #8b5cf6;
  --sky:          #38bdf8;
  --emerald:      #34d399;

  --sunset:       linear-gradient(135deg, #f97316, #f43f5e, #8b5cf6);

  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-full: 9999px;

  --sans: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --wrap: 1100px;
}

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

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--bg-base);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--orange); color: #fff; }

a { color: var(--sky); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; }

/* A link sitting inside a sentence cannot rely on colour alone: against the
   body text it only reaches 1.2:1, well under the 3:1 WCAG asks for. Links in
   lists and navigation are unambiguous from position, so they stay clean. */
.faq p a,
.fact a,
.callout a,
.colophon a,
section > p a,
.lede a { text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; }

:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

h1, h2, h3, h4 { line-height: 1.25; margin: 0 0 0.5em; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: clamp(1.55rem, 1.1rem + 2vw, 2.2rem); }
h2 { font-size: clamp(1.25rem, 1.05rem + 0.9vw, 1.55rem); margin-top: 0; }
h3 { font-size: 1.06rem; }
p  { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

small { font-size: 0.85em; }

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--amber); color: #0b0e14;
  padding: 10px 16px; border-radius: 0 0 var(--r-md) 0; font-weight: 600; z-index: 200;
}
.skip-link:focus { left: 0; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: 20px; }

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

.site-header {
  border-bottom: 1px solid var(--line-subtle);
  background: var(--bg-surface);
  position: sticky; top: 0; z-index: 50;
}
.site-header .wrap {
  display: flex; align-items: center; gap: 16px;
  min-height: 60px; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); font-weight: 700; }
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 32px; height: 32px; border-radius: var(--r-sm);
  background: var(--sunset);
  display: grid; place-items: center; font-size: 17px; flex-shrink: 0;
}
.brand-name { font-size: 1.02rem; letter-spacing: -0.02em; }
.site-nav { margin-left: auto; display: flex; gap: 10px; font-size: 0.92rem; }
/* Padding rather than a bigger font: "API" was a 20 px-wide target, under the
   24 px WCAG 2.5.8 asks for. */
.site-nav a { color: var(--text-dim); padding: 4px 8px; min-width: 24px; text-align: center; }
.site-nav a:hover { color: var(--text); }

/* ------------------------------------------------------------ breadcrumbs */

.crumbs { font-size: 0.86rem; color: var(--text-mute); padding: 14px 0 0; }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.crumbs li + li::before { content: "›"; margin-right: 6px; color: var(--line-strong); }
.crumbs a { color: var(--text-dim); }

/* ------------------------------------------------------------------ intro */

.page-head { padding: 10px 0 6px; }
.page-head h1 { margin-bottom: 10px; }
.lede { font-size: 1.06rem; color: var(--text-dim); max-width: 68ch; }
.lede strong { color: var(--text); font-weight: 600; }

main { padding-bottom: 56px; }

section { margin-top: 40px; }
/* Prose gets a reading measure; lists that are navigation do not. Without the
   exclusion the city grid was capped at 72ch inside an 1,100 px container and
   rendered two columns where five fit. */
section > p { max-width: 72ch; }
section > ul:not(.citygrid):not(.chips):not(.linklist) { max-width: 72ch; }

/* ------------------------------------------------------------- today card */

.today {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--line-subtle);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; margin-top: 22px;
}
.today > div { background: var(--bg-surface); padding: 20px 22px; }
.today h2 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-mute); margin-bottom: 14px; }

.rows { display: grid; gap: 9px; }
.row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.row dt, .row .k { color: var(--text-dim); font-size: 0.92rem; }
.row dd, .row .v { margin: 0; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 0.98rem; }
.row.key .v { font-size: 1.28rem; font-weight: 600; }
.row.key .k { color: var(--text); font-weight: 500; }
.v.sunset  { color: var(--orange); }
.v.sunrise { color: var(--amber); }
.v.golden  { color: var(--amber); }
.v.blue    { color: var(--sky); }
.v.dim     { color: var(--text-mute); }

/* Term labels that lead to the glossary entry. Underlined faintly so the link
   is discoverable without turning a table of times into a page of blue text. */
a.gl { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--line-strong); }
a.gl:hover, a.gl:focus-visible { color: var(--amber); border-bottom-color: var(--amber); }
.cond-method { margin: 12px 0 0; font-size: 0.84rem; color: var(--text-mute); }
.cond-method a { text-decoration: underline; text-underline-offset: 0.18em; }

.countdown {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-subtle);
  font-size: 0.95rem; color: var(--text-dim);
}
.countdown b { color: var(--orange); font-family: var(--mono); font-weight: 600; }

.facing {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg-overlay); border-radius: var(--r-full);
  padding: 3px 11px; font-size: 0.85rem; color: var(--text-dim);
}
.compass-rose { width: 14px; height: 14px; flex-shrink: 0; }

/* -------------------------------------------------------------- tomorrow */

.tomorrow {
  margin-top: 14px; padding: 16px 22px;
  background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  display: flex; flex-wrap: wrap; gap: 10px 30px; align-items: baseline;
}
.tomorrow h2 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-mute); margin: 0; width: 100%; }
.tomorrow .pair { display: flex; gap: 8px; align-items: baseline; }
.tomorrow .k { color: var(--text-dim); font-size: 0.88rem; }
.tomorrow .v { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- conditions */

.conditions {
  margin-top: 14px; padding: 16px 22px;
  background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.conditions h2 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-mute); }
.conditions[hidden] { display: none; }
.cond-grid { display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: baseline; }
.cond-score { font-size: 1.3rem; font-weight: 600; font-family: var(--mono); }
.cond-score.excellent { color: var(--emerald); }
.cond-score.good      { color: var(--amber); }
.cond-score.fair      { color: var(--text-dim); }
.cond-score.poor      { color: var(--text-mute); }
.cond-note { color: var(--text-dim); font-size: 0.92rem; width: 100%; margin: 0; }
.cond-fallback { color: var(--text-mute); font-size: 0.9rem; }

/* -------------------------------------------------------------------- map */

.location {
  display: grid; grid-template-columns: minmax(260px, 1.1fr) 1fr; gap: 24px; align-items: center;
  background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 20px 22px;
}
.citymap { position: relative; line-height: 0; border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--line-subtle); }
.citymap img { width: 100%; height: auto; display: block; }
.citymap-dot {
  position: absolute;
  left: var(--x); top: var(--y);
  width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%; background: var(--orange);
  box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.28), 0 0 12px 2px rgba(249, 115, 22, 0.5);
}

/* --------------------------------------------------------------- tables */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 16px; border: 1px solid var(--line); border-radius: var(--r-lg); }

table { border-collapse: collapse; width: 100%; font-size: 0.88rem; }
caption { text-align: left; padding: 14px 16px 10px; color: var(--text-dim); font-size: 0.9rem; }
th, td { padding: 8px 12px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line-subtle); }
th:first-child, td:first-child { text-align: left; position: sticky; left: 0; background: var(--bg-surface); }
thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-elevated); color: var(--text-dim);
  font-weight: 500; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em;
}
thead th:first-child { z-index: 3; background: var(--bg-elevated); }
tbody tr:nth-child(odd) td { background: rgba(255, 255, 255, 0.014); }
tbody tr:nth-child(odd) td:first-child { background: var(--bg-surface); }
tbody tr.is-today td { background: rgba(249, 115, 22, 0.09); }
tbody tr.is-today td:first-child { background: rgba(249, 115, 22, 0.14); color: var(--orange); font-weight: 600; }
tbody tr.is-weekend td:first-child { color: var(--text-dim); }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
td.delta-plus  { color: var(--emerald); }
td.delta-minus { color: var(--rose-text); }

details { margin-top: 14px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--bg-surface); }
details > summary {
  cursor: pointer; padding: 13px 18px; color: var(--text-dim); font-size: 0.93rem;
  list-style: none;
}
details > summary::-webkit-details-marker { display: none; }
details > summary::before { content: "▸ "; color: var(--text-mute); }
details[open] > summary::before { content: "▾ "; }
details > summary:hover { color: var(--text); }
details .table-scroll { margin: 0; border: 0; border-top: 1px solid var(--line-subtle); border-radius: 0; }

/* --------------------------------------------------------------- charts */

figure { margin: 16px 0 0; }
figure svg { width: 100%; height: auto; display: block; border-radius: var(--r-lg); background: var(--bg-surface); border: 1px solid var(--line); }
figcaption { color: var(--text-mute); font-size: 0.86rem; margin-top: 10px; }

.yc-night    { fill: #0a0d14; }
.yc-astro    { fill: #131a2c; }
.yc-nautical { fill: #1b2743; }
.yc-civil    { fill: #2b3a63; }
.yc-day      { fill: #f6b73c; }
.yc-noon     { fill: none; stroke: rgba(255, 255, 255, 0.42); stroke-width: 1; stroke-dasharray: 3 3; }
.yc-grid     { stroke: rgba(255, 255, 255, 0.09); stroke-width: 1; fill: none; }
.yc-dst      { stroke: var(--rose); stroke-width: 1; stroke-dasharray: 2 4; fill: none; }
.yc-tick     { fill: var(--text-mute); font: 10px var(--sans); }

.bc-grid { stroke: rgba(255, 255, 255, 0.09); stroke-width: 1; fill: none; }
.bc-tick { fill: var(--text-mute); font: 10px var(--sans); }
.bc-bar  { fill: #3d5178; }
.bc-best { fill: var(--amber); }

.legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 12px; font-size: 0.83rem; color: var(--text-dim); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }

/* ---------------------------------------------------------------- facts */

.facts { display: grid; gap: 12px; margin-top: 16px; }
.fact {
  background: var(--bg-surface); border: 1px solid var(--line);
  border-left: 3px solid var(--amber);
  border-radius: var(--r-md); padding: 14px 18px;
  color: var(--text-dim); max-width: 78ch;
}
.fact:nth-child(3n+2) { border-left-color: var(--sky); }
.fact:nth-child(3n+3) { border-left-color: var(--violet); }

.callout {
  background: var(--bg-surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 18px 22px; margin-top: 16px;
}
.callout h3 { margin-top: 0; }
.callout p.small { font-size: 0.88rem; color: var(--text-mute); margin-top: 10px; }

/* ------------------------------------------------------------------ FAQ */

.faq { margin-top: 16px; display: grid; gap: 8px; }
.faq h3 { font-size: 1rem; margin: 0 0 4px; color: var(--text); }
.faq > div { padding: 16px 18px; background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-md); }
.faq p { color: var(--text-dim); margin: 0; max-width: 74ch; }

/* ---------------------------------------------------------------- links */

.linklist { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 1px; background: var(--line-subtle); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.linklist li { background: var(--bg-surface); }
.linklist a {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 11px 18px; color: var(--text);
}
.linklist a:hover { background: var(--bg-elevated); text-decoration: none; }
.linklist .meta { color: var(--text-mute); font-size: 0.86rem; }
.linklist .time { margin-left: auto; font-family: var(--mono); color: var(--amber); font-variant-numeric: tabular-nums; }

.chips { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chips a {
  display: inline-block; padding: 6px 13px;
  background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-full);
  color: var(--text-dim); font-size: 0.9rem;
}
.chips a:hover { border-color: var(--line-strong); color: var(--text); text-decoration: none; }

.cross-link {
  display: block; margin-top: 16px; padding: 16px 20px;
  background: linear-gradient(135deg, rgba(249, 115, 22, 0.1), rgba(139, 92, 246, 0.08));
  border: 1px solid var(--line); border-radius: var(--r-lg); color: var(--text);
}
.cross-link:hover { border-color: var(--line-strong); text-decoration: none; }
.cross-link strong { display: block; }
.cross-link span { color: var(--text-dim); font-size: 0.92rem; }

/* ----------------------------------------------------------- hubs & home */

/* The city pages are held together by cards; the homepage had nothing to
   anchor it and read as loose text floating at the left of a wide screen. */
.hero {
  margin-top: 26px;
  padding: 40px 40px 32px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 140% at 88% 0%, rgba(249, 115, 22, 0.10), transparent 58%),
    radial-gradient(100% 130% at 8% 100%, rgba(139, 92, 246, 0.09), transparent 60%),
    var(--bg-surface);
}
/* The heading and the paragraph want different measures: 60ch is a reading
   width for prose and squeezes a short headline onto three cramped lines. */
.hero h1 { margin-bottom: 14px; max-width: 20ch; font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3rem); }
.hero .lede { font-size: 1.12rem; max-width: 58ch; }

.hero-facts {
  list-style: none; margin: 26px 0 0; padding: 22px 0 0;
  border-top: 1px solid var(--line-subtle);
  display: flex; flex-wrap: wrap; gap: 14px 44px;
}
.hero-facts li { display: flex; flex-direction: column; gap: 1px; }
.hero-facts strong {
  font-family: var(--mono); font-size: 1.3rem; font-weight: 600; color: var(--amber);
  font-variant-numeric: tabular-nums;
}
.hero-facts span { color: var(--text-mute); font-size: 0.83rem; }

@media (max-width: 760px) {
  .hero { padding: 26px 20px 22px; }
  .hero-facts { gap: 14px 26px; }
  .hero-facts strong { font-size: 1.12rem; }
}

/* --text-mute sits at 4.39:1 on --bg-overlay, just under AA. These badges are
   the only place the muted tone lands on the lighter surface, so they take the
   next tone up rather than the palette being reshuffled around them. */
h2 .count, .chip-count {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 400;
  color: var(--text-dim); margin-left: 8px;
  background: var(--bg-overlay); border-radius: var(--r-full); padding: 2px 8px;
}
.chip-count { margin-left: 6px; font-size: 0.7rem; padding: 1px 6px; }

/* Country and city lists get columns once they are long enough to need them. */
.linklist.cols {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* ---- finder ---- */

.finder { margin-top: 28px; position: relative; }
.finder-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: stretch; }
.finder-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
/* Matched on the class, not on type=search: the input is type=text because
   ARIA in HTML forbids putting role=combobox on a searchbox, and tying the
   styling to the type meant the field silently collapsed to its default width
   the moment that changed. */
.finder input {
  flex: 1 1 320px; min-width: 0;
  background: var(--bg-base); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: 16px 18px; font: inherit; font-size: 1.1rem;
}
.finder input::placeholder { color: var(--text-mute); }
.finder input:focus {
  border-color: var(--amber); outline: none;
  box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.16);
}

.btn-locate {
  background: var(--bg-elevated); color: var(--text-dim);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: 13px 18px; font: inherit; font-size: 0.95rem; cursor: pointer;
}
.btn-locate:hover { color: var(--text); border-color: var(--amber); }
.btn-locate[aria-busy="true"] { opacity: 0.6; cursor: progress; }

.finder-help { color: var(--text-mute); font-size: 0.88rem; margin: 8px 0 0; min-height: 1.2em; }

.finder-results {
  list-style: none; margin: 8px 0 0; padding: 0;
  background: var(--bg-surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); overflow: hidden; max-height: 340px; overflow-y: auto;
}
.finder-results[hidden] { display: none; }
.finder-results li + li { border-top: 1px solid var(--line-subtle); }
/* The option itself is the target now — ARIA does not allow a focusable link
   inside role="option", and the keyboard highlight has to land on the element
   aria-activedescendant names. */
.finder-results li[data-url] {
  display: flex; gap: 10px; align-items: baseline; padding: 11px 16px;
  color: var(--text); cursor: pointer;
}
.finder-results li[data-url]:hover, .finder-results li.is-active {
  background: var(--bg-elevated);
}
.finder-results .meta { color: var(--text-mute); font-size: 0.86rem; }
.finder-results .time { margin-left: auto; font-family: var(--mono); color: var(--amber); }

/* ---- author block on /about/ ---- */

.author-card {
  display: flex; gap: 20px; align-items: flex-start;
  /* section > p sets the reading measure, but these paragraphs are nested
     inside the card and never match it, so the card carries its own. */
  max-width: 74ch;
  background: var(--bg-surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px 22px; margin-top: 16px;
}
.author-photo {
  width: 96px; height: 96px; border-radius: var(--r-full);
  object-fit: cover; flex-shrink: 0;
  border: 2px solid var(--line-strong);
}
.author-text { min-width: 0; }
.author-text p { margin: 0 0 0.8em; }
.author-text p:last-child { margin-bottom: 0; }
.author-name { font-size: 1.05rem; }
.author-role { color: var(--text-dim); font-weight: 400; margin-left: 10px; font-size: 0.92rem; }
.author-links { font-size: 0.92rem; }
.author-links a { text-decoration: underline; text-underline-offset: 0.18em; }

@media (max-width: 560px) {
  .author-card { flex-direction: column; gap: 14px; }
}

/* ---- popular city grid ---- */

.citygrid {
  list-style: none; margin: 16px 0 0; padding: 0;
  display: grid; gap: 1px; background: var(--line-subtle);
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
}
.citygrid li { background: var(--bg-surface); }
.citygrid a {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline;
  column-gap: 12px; row-gap: 1px; padding: 13px 16px; color: var(--text);
}
.citygrid a:hover { background: var(--bg-elevated); text-decoration: none; }
.cg-name { font-weight: 600; }
/* One long country name would otherwise set the height of an entire grid row:
   "Democratic Republic of the Congo" wraps at this column width and drags the
   four cards beside it down with it. The city name is the identifier here. */
.cg-country {
  color: var(--text-mute); font-size: 0.83rem; grid-column: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.cg-time {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  color: var(--orange); font-size: 1.18rem;
}

/* -------------------------------------------------------------- articles */

.article .lede { max-width: 62ch; }
.byline { color: var(--text-mute); font-size: 0.88rem; margin-top: 12px; }

.toc {
  margin-top: 26px; padding: 18px 22px;
  background: var(--bg-surface); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.toc h2 {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute); margin-bottom: 10px;
}
.toc ol { margin: 0; padding-left: 1.2em; display: grid; gap: 5px; color: var(--text-mute); }
.toc ul.chips { margin-top: 0; }

/* Prose gets a reading measure; the tables inside it do not, because a
   fourteen-city comparison squeezed into 68ch is unreadable. */
.prose { margin-top: 34px; }
.prose > p, .prose > ul, .prose > ol, .prose > blockquote { max-width: 68ch; }
.prose h2 { margin-top: 2em; scroll-margin-top: 80px; }
.prose h3 { margin-top: 1.6em; scroll-margin-top: 80px; }
.prose > ul, .prose > ol { display: grid; gap: 8px; padding-left: 1.3em; }
.prose li { color: var(--text-dim); }
.prose .table-scroll { margin: 22px 0; }
.prose .callout { margin: 24px 0; max-width: 72ch; }
.prose blockquote {
  margin: 24px 0; padding: 4px 0 4px 20px;
  border-left: 3px solid var(--amber); color: var(--text-dim);
}
.prose code {
  font-family: var(--mono); font-size: 0.88em;
  background: var(--bg-overlay); padding: 1px 5px; border-radius: var(--r-sm);
}
.prose pre {
  background: var(--bg-surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 16px 18px; overflow-x: auto;
}
.prose pre code { background: none; padding: 0; }
.prose hr { border: 0; border-top: 1px solid var(--line-subtle); margin: 36px 0; }

/* Glossary: each term is an anchor the city templates link into. */
.glossary h2 {
  font-size: 1.12rem; margin-top: 1.8em; padding-top: 18px;
  border-top: 1px solid var(--line-subtle);
}
.glossary h2:first-child { border-top: 0; padding-top: 0; margin-top: 0; }

/* ------------------------------------------------------------- ad slots */

/* Sized now, empty until enabled. Reserving the height here is the whole point
   of building the slots early: turning one on later must not push the page
   around under a reader who is already looking at it. */
.ad-slot {
  min-height: 280px;
  margin: 32px 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-surface);
  border: 1px solid var(--line-subtle);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.ad-slot::before {
  content: "Advertisement";
  font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-mute);
}
.ad-slot:has(ins)::before, .ad-slot:has(iframe)::before { content: none; }
.ad-slot ins, .ad-slot iframe { width: 100%; }

@media (max-width: 760px) {
  .ad-slot { margin: 24px 0; }
}

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

.site-footer {
  border-top: 1px solid var(--line-subtle); background: var(--bg-surface);
  padding: 32px 0; color: var(--text-mute); font-size: 0.88rem;
}
.footer-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 24px; }
.footer-cols h2 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-dim); margin-bottom: 10px; }
.footer-cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.footer-cols a { color: var(--text-mute); }
.footer-cols a:hover { color: var(--text); }
.colophon { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line-subtle); display: grid; gap: 6px; max-width: 80ch; }

/* ----------------------------------------------------------- responsive */

@media (max-width: 760px) {
  body { font-size: 15px; }

  /* WCAG 2.5.8: links sitting in a list, rather than inline in a sentence,
     need a 24 px tappable box. Padding rather than font size, so the visual
     density of the footer survives. */
  .footer-cols ul { gap: 2px; }
  .footer-cols a,
  .site-nav a,
  .crumbs a,
  .crumbs span { display: inline-block; padding-block: 4px; min-height: 24px; }
  .today { grid-template-columns: 1fr; }
  .location { grid-template-columns: 1fr; }
  .site-nav { gap: 14px; font-size: 0.86rem; }
  .wrap { padding-inline: 16px; }
  th, td { padding: 7px 10px; }
  .today > div { padding: 16px 18px; }
}

@media (max-width: 460px) {
  .site-header .wrap { min-height: 54px; }
  .brand-name { font-size: 0.95rem; }
  .row.key .v { font-size: 1.15rem; }
}

@media print {
  .site-header, .site-footer, .site-nav, .conditions { display: none; }
  body { background: #fff; color: #000; }
}
