/* /news/news.css - the Newsroom, on top of brand.css + tools.css.
 *
 * Colours are brand.css tokens, never hexes, because that is what makes
 * the theme switch work: one palette swapped underneath, no dark-mode
 * rule per component. The one exception is the Breaking red, declared
 * once and never redeclared, because a label whose colour changes with
 * the theme is a label nobody learns to trust on sight.
 *
 * LAYOUT, after the redesign review. The index runs the full shell
 * width with a navigation rail beside it: a news index is a scanning
 * surface, and the reading measure that suits one brief is the wrong
 * measure for a list of forty. The reading measure comes back on the
 * story page, where there is one piece of prose to read.
 *
 * Cards are built to be read, not admired: a headline, one short line,
 * and a meta row. The long text lives on the story page. Padding is
 * tight enough that ten cards fit a screen and loose enough that they
 * do not run together.
 */

.nr,
.nr-story {
  --nr-breaking: #b42318;
  --nr-on-breaking: #ffffff;
}

/* ── the page ────────────────────────────────────────────────────── */

.nr {
  max-width: var(--pf-shell);
  margin: 0 auto;
  padding: 1.75rem 16px 3rem;
}

.nr-head {
  margin-bottom: 1.5rem;
}

.nr-head h1 {
  margin: 0;
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.nr-tagline {
  margin: 0.3rem 0 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--pf-primary);
}

/* The lede reads across the page rather than inside a column: there is
   room, and a 60ch rag in the middle of a 1120px header is a hole. */
.nr-lede {
  margin: 0 0 1.1rem;
  max-width: 85ch;
  font-size: 0.97rem;
  line-height: 1.55;
  color: var(--pf-muted);
}

/* ── the controls, at the top, acting on everything ──────────────── */

.nr-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-bottom: 0.7rem;
}

.nr-spacer {
  flex: 1 1 auto;
}

.nr-control {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--pf-line-strong);
  border-radius: 999px;
  background: var(--pf-card);
  padding: 0 0.4rem 0 0.75rem;
}

.nr-control [data-lucide] {
  width: 15px;
  height: 15px;
  color: var(--pf-muted);
  flex: none;
}

.nr-control select {
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--pf-ink);
  padding: 0.38rem 0.3rem 0.38rem 0;
  max-width: 13rem;
  cursor: pointer;
}

.nr-control select:focus-visible {
  outline: 2px solid var(--pf-primary);
  outline-offset: 2px;
  border-radius: 999px;
}

.nr-updated {
  font-size: 0.78rem;
  color: var(--pf-muted);
}

.nr-refresh {
  border: 1px solid var(--pf-line-strong);
  border-radius: 999px;
  background: var(--pf-card);
  color: var(--pf-ink);
  font: inherit;
  font-size: 0.8rem;
  padding: 0.32rem 0.8rem;
  cursor: pointer;
}

.nr-refresh:hover {
  border-color: var(--pf-primary);
  color: var(--pf-primary);
}

.nr-topics {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--pf-line);
}

.nr-topic {
  border: 1px solid var(--pf-line);
  border-radius: 999px;
  background: var(--pf-card);
  color: var(--pf-muted);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.26rem 0.7rem;
  cursor: pointer;
}

.nr-topic small {
  font-size: 0.72rem;
  opacity: 0.7;
}

.nr-topic:hover {
  border-color: var(--pf-line-strong);
}

.nr-topic[aria-pressed="true"] {
  border-color: var(--pf-primary);
  background: var(--pf-ok-soft);
  color: var(--pf-link);
}

.nr-topic:focus-visible {
  outline: 2px solid var(--pf-primary);
  outline-offset: 2px;
}

.nr-locality {
  margin: 0.7rem 0 0;
  font-size: 0.82rem;
  color: var(--pf-muted);
}

/* ── rail + content ──────────────────────────────────────────────── */

.nr-body {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  gap: 2rem;
  margin-top: 1.5rem;
  align-items: start;
}

.nr-side {
  position: sticky;
  top: 84px;
}

.nr-side-head {
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--pf-muted);
}

.nr-side-head + .nr-side-head,
.nr-side-nav + .nr-side-head {
  margin-top: 1.8rem;
}

.nr-side-nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.nr-side-nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  font-size: 0.88rem;
  color: var(--pf-ink);
  text-decoration: none;
}

.nr-side-nav a small {
  font-size: 0.74rem;
  color: var(--pf-muted);
  font-variant-numeric: tabular-nums;
}

.nr-side-nav a:hover {
  background: var(--pf-tint);
}

.nr-side-nav a[aria-current="page"] {
  background: var(--pf-ok-soft);
  color: var(--pf-link);
  font-weight: 700;
}

.nr-side-note {
  margin: 0 0 0.6rem;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--pf-muted);
}

.nr-sources {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.78rem;
}

.nr-sources b {
  font-weight: 600;
}

.nr-sources small {
  color: var(--pf-muted);
}

/* ── sections ────────────────────────────────────────────────────── */

.nr-section {
  margin-bottom: 1.75rem;
}

.nr-section-head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 0.7rem;
}

.nr-section-head h2 {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--pf-muted);
}

.nr-section-head h2 [data-lucide] {
  width: 14px;
  height: 14px;
}

.nr-breaking .nr-section-head h2 {
  color: var(--nr-breaking);
}

.nr-section-note {
  font-size: 0.78rem;
  color: var(--pf-muted);
  margin-left: auto;
}

.nr-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Two across, so a headline has room to wrap inside its own card
   instead of being clipped. Capped at ten by the client. */
.nr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 0.6rem;
}

/* ── the Popular rail ────────────────────────────────────────────── */

/* One row that slides. A native scroller rather than a transformed
   track, because this way the swipe, the keyboard and the scrollbar all
   work without being reimplemented, and nothing is hidden: every card
   stays rendered, focusable and indexable while it is off screen.

   scroll-snap makes each step land on a card edge, so the auto-advance
   never leaves a headline cut in half down the middle. */
.nr-rail {
  display: flex;
  gap: 0.6rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Room for the focus ring, which a hidden overflow would clip. */
  padding: 3px;
  margin: -3px;
  /* The scrollbar is redundant next to the dots and the arrows, and on
     a trackpad it appears over the bottom card edge. The rail is still
     scrollable by every other means. */
  scrollbar-width: none;
}

.nr-rail::-webkit-scrollbar {
  display: none;
}

/* EXACTLY three cards per view, never a sliver of a fourth.

   This was a clamped width, which meant the rail nearly always ended on
   a part-card at each edge: half a headline is not a preview, it is a
   card you cannot read next to cards you can. Deriving the width from
   the rail instead - a third of it, less the two gaps between three
   cards - makes a view a whole number of cards at every window size. */
.nr-rail {
  --nr-rail-gap: 0.6rem;
  --nr-rail-per-view: 3;
  gap: var(--nr-rail-gap);
}

.nr-rail > .nr-card {
  flex: 0 0 calc(
    (100% - (var(--nr-rail-per-view) - 1) * var(--nr-rail-gap)) /
    var(--nr-rail-per-view)
  );
  scroll-snap-align: start;
}

/* Below these widths a third of the rail is too narrow for a headline
   to wrap into, so the view holds fewer whole cards rather than three
   unreadable ones. The count is a custom property because app.js reads
   the rendered width back to decide how far one press moves. */
@media (max-width: 1023px) {
  .nr-rail {
    --nr-rail-per-view: 2;
  }
}

@media (max-width: 719px) {
  .nr-rail {
    --nr-rail-per-view: 1;
  }
}

/* A rail card is a glance, not a read: the full text is one tap away on
   the story page. Tighter type and a three-line cap on the summary,
   because the tallest card in the row sets the height of the whole
   section and one long story was making the rail twice as deep as it
   needed to be. */
.nr-rail > .nr-card {
  padding: 0.7rem 0.8rem 0.6rem;
}

.nr-rail .nr-card-title {
  font-size: 0.92rem;
  line-height: 1.28;
  margin-bottom: 0.3rem;
}

.nr-rail .nr-card-summary {
  font-size: 0.8rem;
  line-height: 1.45;
  margin-bottom: 0.35rem;
  /* width: fit-content on the base rule stops -webkit-box from
     clamping, so the rail card overrides it. */
  width: auto;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.nr-rail:focus-visible {
  outline: 2px solid var(--pf-primary);
  outline-offset: 2px;
}

/* Reduced motion: the rail still works, it just does not glide, and the
   auto-advance is off entirely (handled in app.js). */
@media (prefers-reduced-motion: reduce) {
  .nr-rail {
    scroll-behavior: auto;
  }
}

/* Popular is not Breaking: the marker is the brand colour, not the
   alarm one. */
.nr-popular .nr-dot-btn[aria-current="true"] {
  background: var(--pf-primary);
}

/* ── a card ──────────────────────────────────────────────────────── */

.nr-card {
  position: relative;
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  background: var(--pf-card);
  padding: 0.85rem 1rem 0.75rem;
}

.nr-card:hover {
  border-color: var(--pf-line-strong);
}

.nr-card-top {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-bottom: 0.45rem;
}

.nr-card-top:empty {
  display: none;
}

.nr-card-title {
  margin: 0 0 0.35rem;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.32;
}

.nr-card-title a {
  color: var(--pf-ink);
  text-decoration: none;
}

.nr-card-title a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The whole card is clickable, through the headline's link rather than
   a wrapping <button>. A button's text cannot be selected, which meant
   nobody could quote a brief and no crawler could read one. */
.nr-card-title a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--pf-radius);
}

.nr-card-title a:focus-visible::after {
  outline: 2px solid var(--pf-primary);
  outline-offset: 2px;
}

/* ...and the text sits ABOVE that overlay, so it stays selectable.
   Clicking the words selects them; clicking anywhere else opens the
   story. That is the trade, and it is the right way round. */
.nr-card-summary,
.nr-card-meta {
  position: relative;
  z-index: 1;
  width: fit-content;
  max-width: 100%;
}

.nr-card-summary {
  margin: 0 0 0.45rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--pf-muted);
}

.nr-card-meta {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  font-size: 0.76rem;
  color: var(--pf-muted);
}

.nr-dot {
  opacity: 0.5;
}

.nr-card-breaking {
  border-color: var(--nr-breaking);
  box-shadow: inset 3px 0 0 var(--nr-breaking);
}

.nr-card-release {
  box-shadow: inset 3px 0 0 var(--pf-warn);
}

/* Breaking gets one row and a slightly larger headline. One story at a
   time: three red-bordered cards stacked is a wall of alarm that
   teaches people to scroll past the label. */
.nr-card-breaking .nr-card-title {
  font-size: 1.12rem;
}

/* ── chips ───────────────────────────────────────────────────────── */

.nr-chip {
  display: inline-block;
  border-radius: 999px;
  background: var(--pf-chip);
  color: var(--pf-on-chip);
  padding: 0.08rem 0.5rem;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.055em;
  line-height: 1.65;
}

.nr-chip-breaking {
  background: var(--nr-breaking);
  color: var(--nr-on-breaking);
}

.nr-chip-press-release {
  background: var(--pf-warn);
  color: #ffffff;
}

.nr-chip-local {
  background: var(--pf-primary);
  color: var(--pf-on-primary);
}

/* The country a story belongs to: quieter than a topic, because it
   answers a different question and both are on every card. */
.nr-chip-country,
.nr-chip-archive {
  background: transparent;
  border: 1px solid var(--pf-line-strong);
  color: var(--pf-muted);
}

/* ── the carousel ────────────────────────────────────────────────── */

.nr-carousel-nav {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
}

.nr-count {
  font-size: 0.72rem;
  color: var(--pf-muted);
  font-variant-numeric: tabular-nums;
}

.nr-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--pf-line-strong);
  border-radius: 999px;
  background: var(--pf-card);
  color: var(--pf-ink);
  cursor: pointer;
  padding: 0;
}

.nr-arrow:hover {
  border-color: var(--pf-primary);
  color: var(--pf-primary);
}

.nr-arrow [data-lucide] {
  width: 14px;
  height: 14px;
}

/* [hidden] rather than an offset track: a slide that is off screen but
   still in the DOM is still in the tab order and still read aloud. */
.nr-slide[hidden] {
  display: none;
}

.nr-dots {
  display: flex;
  justify-content: center;
  gap: 0.3rem;
  margin-top: 0.55rem;
}

.nr-dot-btn {
  width: 6px;
  height: 6px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--pf-line-strong);
  cursor: pointer;
  transition: width 0.18s ease, background-color 0.18s ease;
}

.nr-dot-btn[aria-current="true"] {
  width: 18px;
  background: var(--nr-breaking);
}

/* ── the pager ───────────────────────────────────────────────────── */

.nr-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
  margin-top: 1.1rem;
}

.nr-page,
.nr-page-step {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 32px;
  justify-content: center;
  border: 1px solid var(--pf-line);
  border-radius: 8px;
  background: var(--pf-card);
  color: var(--pf-ink);
  font: inherit;
  font-size: 0.82rem;
  padding: 0.3rem 0.5rem;
  cursor: pointer;
}

.nr-page-step {
  padding: 0.3rem 0.7rem;
}

.nr-page:hover:not([aria-current]),
.nr-page-step:hover:not(:disabled) {
  border-color: var(--pf-primary);
  color: var(--pf-primary);
}

.nr-page[aria-current="page"] {
  background: var(--pf-primary);
  border-color: var(--pf-primary);
  color: var(--pf-on-primary);
  font-weight: 700;
}

.nr-page-step:disabled {
  opacity: 0.4;
  cursor: default;
}

.nr-page-step [data-lucide] {
  width: 14px;
  height: 14px;
}

.nr-page-gap {
  padding: 0 0.2rem;
  color: var(--pf-muted);
}

/* ── loading, empty ──────────────────────────────────────────────── */

.nr-skeleton {
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  background: var(--pf-card);
  padding: 0.9rem 1rem;
}

.nr-skeleton span {
  display: block;
  height: 0.65rem;
  border-radius: 4px;
  background: var(--pf-tint);
  border: 1px solid var(--pf-tint-line);
  margin-bottom: 0.5rem;
  animation: nr-pulse 1.4s ease-in-out infinite;
}

.nr-skeleton span:nth-child(1) { width: 28%; }
.nr-skeleton span:nth-child(2) { width: 86%; height: 0.95rem; }
.nr-skeleton span:nth-child(3) { width: 64%; }

@keyframes nr-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .nr-skeleton span { animation: none; }
}

.nr-notice {
  border: 1px solid var(--pf-line);
  border-radius: var(--pf-radius);
  background: var(--pf-card);
  padding: 1.75rem 1.25rem;
  text-align: center;
}

.nr-notice p {
  margin: 0 0 0.9rem;
  font-size: 0.93rem;
  line-height: 1.55;
  color: var(--pf-muted);
}

.nr-notice p:last-child {
  margin-bottom: 0;
}

/* ── the story page ──────────────────────────────────────────────── */

.nr-story {
  max-width: 72ch;
  margin: 0 auto;
  padding: 1.5rem 16px 4rem;
}

.nr-back {
  margin: 0 0 1.25rem;
  font-size: 0.85rem;
}

.nr-back a {
  color: var(--pf-muted);
  text-decoration: none;
}

.nr-back a:hover {
  color: var(--pf-link);
  text-decoration: underline;
}

.nr-story-body h1 {
  margin: 0 0 0.5rem;
  font-size: clamp(1.7rem, 3.2vw, 2.3rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
}

.nr-story-kicker {
  margin: 0 0 1.4rem;
  font-size: 0.82rem;
  color: var(--pf-muted);
}

.nr-release-note,
.nr-thin {
  margin: 0 0 1.2rem;
  padding-left: 0.75rem;
  border-left: 2px solid var(--pf-warn);
  font-size: 0.86rem;
  color: var(--pf-muted);
}

.nr-story-text p {
  margin: 0 0 1rem;
  font-size: 1.04rem;
  line-height: 1.68;
}

.nr-story-text a {
  color: var(--pf-link);
}

.nr-story-text blockquote {
  margin: 1.2rem 0;
  padding-left: 1rem;
  border-left: 3px solid var(--pf-line-strong);
  font-style: italic;
  color: var(--pf-muted);
}

.nr-told {
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--pf-line);
}

.nr-told h2 {
  margin: 0 0 0.8rem;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--pf-muted);
}

.nr-told ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.nr-told li {
  margin-bottom: 0.85rem;
  line-height: 1.55;
}

.nr-told-source {
  display: block;
  font-weight: 700;
  font-size: 0.85rem;
}

.nr-stance {
  font-weight: 500;
  color: var(--pf-muted);
  text-transform: lowercase;
}

.nr-counter li {
  position: relative;
  padding-left: 1.1rem;
}

.nr-counter li::before {
  content: "\2260";
  position: absolute;
  left: 0;
  color: var(--pf-muted);
  font-weight: 700;
}

.nr-readmore {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.nr-readmore li {
  margin: 0;
}

.nr-readmore a {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 1px solid var(--pf-line-strong);
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
  font-size: 0.84rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--pf-ink);
}

.nr-readmore a:hover {
  border-color: var(--pf-primary);
  color: var(--pf-link);
}

.nr-readmore [data-lucide] {
  width: 13px;
  height: 13px;
}

.nr-about {
  margin: 1.1rem 0 0;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--pf-muted);
}

/* ── narrow ──────────────────────────────────────────────────────── */

@media (max-width: 920px) {
  .nr-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  /* The rail becomes a scrolling row above the news rather than a
     column nobody reaches: on a phone the topics are the first thing
     worth offering, not the last. */
  .nr-side {
    position: static;
    order: -1;
  }

  .nr-side-nav {
    flex-direction: row;
    overflow-x: auto;
    gap: 0.35rem;
    padding-bottom: 0.3rem;
  }

  .nr-side-nav a {
    flex: none;
    border: 1px solid var(--pf-line);
    border-radius: 999px;
    padding: 0.3rem 0.75rem;
    font-size: 0.82rem;
  }

  .nr-side-head:not(:first-child),
  .nr-side-note,
  .nr-sources {
    display: none;
  }
}

@media (max-width: 640px) {
  .nr {
    padding-top: 1.25rem;
  }

  .nr-control select {
    max-width: 8.5rem;
  }

  .nr-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .nr-section-note {
    display: none;
  }
}
