/* Front Pages — single stylesheet, no build step, no framework.
   Light theme only, by design: this is a reading surface and it commits to one
   look. There is deliberately no prefers-color-scheme block. If you add a dark
   theme later, note that the vendored outlet SVGs have had their internal
   dark-mode rules stripped (see scripts/fetch-icons.mjs) and would need them. */

:root {
  --bg: #f4f5f7;
  --bg-raised: #ffffff;
  --bg-sunken: #fafbfc;
  --border: #e3e6ea;
  --border-strong: #ccd2da;
  --text: #16191d;
  --text-muted: #565f6b;
  --text-faint: #8b939e;
  --accent: #1a4fd0;
  --accent-soft: #f0f4fe;

  --radius: 12px;
  --radius-sm: 7px;
  --shadow: 0 1px 2px rgb(16 24 40 / 5%), 0 1px 3px rgb(16 24 40 / 4%);
  --maxw: 1400px;

  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", serif;

  color-scheme: light;
}

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

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

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

a {
  color: inherit;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: #fff;
  padding: 0.6rem 1rem;
  z-index: 20;
  border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
  left: 0;
}

:where(a, button, select):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ---------- Masthead ---------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgb(255 255 255 / 88%);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.masthead__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1rem 1.25rem 0.85rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem 1.5rem;
}

.masthead__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.1;
}

.masthead__tagline {
  margin: 0.3rem 0 0;
  color: var(--text-muted);
  font-size: 0.875rem;
  max-width: 48ch;
}

.country-picker {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 15rem;
}

.country-picker__label {
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.country-picker__control {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.5rem;
}

/* Flags are PNGs rasterised by Wikimedia (see scripts/fetch-flags.mjs for why
   not SVG). Aspect ratios differ per country — Canada 2:1, Brazil 10:7, India
   and China 3:2, the US 19:10 — so object-fit: contain fits each one whole
   inside a fixed box. Using cover would crop a national flag, which is not
   an acceptable thing to do. */
.country-picker__flag {
  width: 32px;
  height: 22px;
  object-fit: contain;
  border-radius: 2px;
  flex: none;
  background: transparent;
}

.country-picker__flag:not([src]),
.country-picker__flag[src=""] {
  visibility: hidden;
}

.country-picker__select {
  flex: 1;
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.15rem 1.4rem 0.15rem 0.1rem;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.55rem center, right 0.28rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.country-picker__hint {
  margin: 0;
  font-size: 0.75rem;
  color: var(--text-faint);
  min-height: 1.1em;
}

/* ---------- Translate control ---------- */

.translate {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
  margin-top: 0.35rem;
}

.translate__label {
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.translate__select {
  flex: 1;
  min-width: 9rem;
  appearance: none;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.2rem 1.4rem 0.2rem 0.45rem;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.55rem center, right 0.28rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.translate__select:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

.translate__status {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.72rem;
  color: var(--text-faint);
}

/* ---------- Google's translate widget ----------

   The widget insists on drawing its own toolbar: an iframe pinned to the top of
   the viewport, plus `body { top: 40px }` inline to make room for it. That
   toolbar duplicates the control we already have, covers the masthead, and
   fights the sticky header, so it is suppressed here and `body` is pinned back.

   `!important` is load-bearing on the `top` rule specifically: the widget sets
   it as an inline style, and nothing weaker wins against that.

   These class names are Google's, not ours. If the widget is ever replaced,
   this whole block goes with it. */

#translate-widget {
  display: none;
}

.skiptranslate iframe,
iframe.skiptranslate {
  display: none !important;
}

body {
  top: 0 !important;
}

/* The widget wraps every translated text node in <font>. Left alone, those
   inherit nothing and reset the inherited weight and colour mid-headline. */
font[style] {
  background: none !important;
  box-shadow: none !important;
  color: inherit !important;
  font: inherit !important;
}

/* ---------- Ad slots ----------

   Sized before the creative arrives. An ad that loads late and pushes the page
   down is the reason Cumulative Layout Shift is a ranking signal, and it is
   also just unpleasant to read against — `min-height` on the wrapper and an
   explicit height on the frame mean nothing moves when the ad lands.

   The slot deliberately does not try to look like a card. Making an ad
   resemble the news around it is the one thing a news site should not do. */

.ad {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 0.5rem 0;
  overflow: hidden;
}

.ad__label {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.ad__frame {
  display: block;
  border: 0;
  max-width: 100%;
  background: transparent;
  color-scheme: light;
}

/* Every unit in use is a fixed size, so the frame is sized by ads.js and needs
   no per-placement rule. If the native unit is ever reinstated it is responsive
   and wants `width: 100%` here. */

/* ---------- Status bar ---------- */

.statusbar {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 1.25rem 0.7rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.1rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.statusbar__item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.statusbar__refresh {
  margin-left: auto;
  background: var(--bg-sunken);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font: inherit;
  font-size: 0.78rem;
  padding: 0.25rem 0.7rem;
  cursor: pointer;
}

.statusbar__refresh:hover {
  color: var(--text);
  border-color: var(--accent);
}

.statusbar__refresh[disabled] {
  opacity: 0.55;
  cursor: progress;
}

/* ---------- Layout ---------- */

main {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
}

.loading {
  color: var(--text-muted);
  padding: 3rem 0;
  text-align: center;
}

.outlets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 23rem), 1fr));
  gap: 1.1rem;
  align-items: start;
}

/* ---------- Outlet card ---------- */

.outlet {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.outlet__header {
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

/* Outlet icon, vendored into assets/outlets/. Sits on a white chip with a hair
   border so pale and transparent logos stay visible against the header. */
.outlet__icon {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 6px;
  object-fit: contain;
  background: #fff;
  border: 1px solid var(--border);
  padding: 2px;
}

.outlet__monogram {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 6px;
  background: var(--accent-soft);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
}

.outlet__identity {
  min-width: 0;
  flex: 1;
}

.outlet__name {
  margin: 0;
  font-size: 1rem;
  font-weight: 660;
  letter-spacing: -0.012em;
  line-height: 1.25;
  overflow-wrap: break-word;
}

.outlet__name a {
  text-decoration: none;
}

.outlet__name a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.outlet__fetched {
  display: inline-flex;
  align-items: center;
  gap: 0.32rem;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.outlet__fetched::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #1f9254;
  flex: none;
}

.outlet__fetched--aging::before {
  background: #c08423;
}

.outlet__fetched--stale::before {
  background: #c0392b;
}

/* ---------- Stories ---------- */

.stories {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
}

.story {
  border-bottom: 1px solid var(--border);
}

.story:last-child {
  border-bottom: 0;
}

.story__link {
  display: flex;
  gap: 0.7rem;
  padding: 0.75rem 1rem;
  text-decoration: none;
  transition: background-color 0.12s ease;
}

.story__link:hover,
.story__link:focus-visible {
  background: var(--accent-soft);
}

.story__position {
  flex: none;
  width: 1.15rem;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 0.2rem;
}

.story--lead .story__position {
  color: var(--accent);
}

.story__body {
  min-width: 0;
  flex: 1;
}

.story__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.005em;
  overflow-wrap: break-word;
}

.story--lead .story__title {
  font-size: 1.06rem;
  font-weight: 700;
}

/* The opening lines of the article, so the headline is not the only signal.
   Deliberately small and clamped: it is a glimpse, not the story. */
.story__excerpt {
  margin: 0.28rem 0 0;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--text-muted);
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.story--lead .story__excerpt {
  font-size: 0.815rem;
  -webkit-line-clamp: 3;
  line-clamp: 3;
}

.story__time {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.7rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.outlet__error {
  padding: 1rem;
  font-size: 0.82rem;
  color: var(--text-muted);
}

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

.footer {
  border-top: 1px solid var(--border);
  background: var(--bg-raised);
}

.footer p {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0.9rem 1.25rem;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.footer p + p {
  padding-top: 0;
}

/* Prose links in the footer. Scoped away from .footer__nav, which styles its
   own. Without this, a link inside .footer__credit inherits the faint credit
   colour and stops looking like a link at all. */
.footer p:not(.footer__nav) a {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer p:not(.footer__nav) a:hover {
  color: var(--accent);
}

/* ---------- Footer nav (shared by every page) ---------- */

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-size: 0.82rem;
}

.footer__nav a {
  color: var(--text-muted);
  text-decoration: none;
}

.footer__nav a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer__nav a[aria-current="page"] {
  color: var(--text);
  font-weight: 640;
}

.footer__credit {
  padding-bottom: 1.6rem !important;
  color: var(--text-faint) !important;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

@media (max-width: 34rem) {
  .masthead__inner {
    padding-inline: 1rem;
  }

  main {
    padding-inline: 1rem;
  }

  .country-picker {
    width: 100%;
  }
}
