/* ==========================================================================
   SECTION LABELS & MAGAZINE WRAPPERS
   ========================================================================== */

.magazine-layout { max-width: 1300px; margin: 0 auto 30px; padding: 0 20px; }

.search-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 24px;
}

.search-form input {
  flex: 1 1 260px;
  /* A flex item defaults to min-width:auto, so the input's size="32" intrinsic
     width kept it from shrinking and pushed the page into horizontal scroll at
     360px. Same defence as .band-feature > div above. */
  min-width: 0;
  min-height: 44px;
  padding: 8px 16px;
  box-sizing: border-box;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 2px;
}

.homepage-featured-label { max-width: 1300px; margin: 30px auto 16px; padding: 0 20px; }

/* ==========================================================================
   HERO — text-first broadsheet lead. `.has-figure` adds the image column.
   ========================================================================== */

.hero-section { margin-bottom: var(--s-6); }

.hero-card {
  border-top: 3px solid var(--cat, var(--ink));
  border-bottom: 1px solid var(--hairline);
  padding: var(--s-6) 0 var(--s-6);
}

.hero-card.has-figure {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 28px;
  align-items: start;
}

.hero-figure { margin: 0; }

.hero-figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  border-radius: 3px;
}

.hero-content .tag {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.6875rem; /* 11px — decorative uppercase, AA-large via weight */
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--muted);
  margin: 0 0 6px 10px;
}

.hero-content h2 {
  font-family: var(--display);
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.25rem); /* 24–36px */
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.13;
  margin: 4px 0 10px;
  text-align: left;
}

.hero-link { color: inherit; text-decoration: none; }
.hero-link:hover { text-decoration: underline; }

.hero-excerpt {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 62ch;
  margin: 10px 0 16px;
}

.meta, .date {
  font-family: var(--sans);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* ==========================================================================
   NEWSPAPER COLUMNS — compact broadsheet feed rows
   ========================================================================== */

.newspaper-columns {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 0 var(--s-8);
}

.col-primary { border-right: 1px solid var(--hairline); padding-right: var(--s-8); }

/* The right-hand column of a category hub stacks four blocks beside the feed:
   the curated rail, the beat primer, the Amazon picks, then the feed headlines.
   Each is placed explicitly rather than by source order, because DOM order and
   visual order deliberately differ — see category.html.erb and
   _beat_primer.html.erb for why each block sits where it does in the markup.

   Rows are FIXED rather than derived from which blocks are present. The row gap
   is 0, so a block that is absent leaves a zero-height empty row and the ones
   below close up on their own. That is what lets four optional blocks share one
   set of rules; the previous version enumerated `.has-rail` and
   `.has-rail.has-primer` combinations, which a fourth block would have taken to
   eight. The left column spans all four rows so its divider runs the full
   height regardless of which side is taller. */
.newspaper-columns .col-primary          { grid-column: 1; grid-row: 1 / span 4; }
.newspaper-columns .category-rail        { grid-column: 2; grid-row: 1; }
.newspaper-columns .beat-primer          { grid-column: 2; grid-row: 2; }
.newspaper-columns .sidebar-product-box  { grid-column: 2; grid-row: 3; }
.newspaper-columns .col-secondary        { grid-column: 2; grid-row: 4; }

.category-rail { margin-bottom: var(--s-6); }
.category-rail .text-link { display: inline-block; margin-top: 12px; }

/* The rail is ~490px wide, so the page-foot pagination's 18px button padding and
   15px label margins overflow it. Same controls, sized for the column. */
.rail-pagination { margin-top: 14px; }
.rail-pagination .pagination-container { flex-wrap: wrap; gap: 8px; }
.rail-pagination .pagination-btn { padding: 10px 14px; font-size: 0.75rem; }
.rail-pagination .page-info { margin: 0 4px; font-size: 0.75rem; }

/* Order within that column is deliberate. The curated rail keeps the top: it
   holds the only on-site destinations here, and those are the pages that rank.
   The beat primer is evergreen text not competing for a click. The Amazon picks
   are paid placements and sit below both, above the feed headlines. */
.beat-primer { margin-bottom: var(--s-6); }
.newspaper-columns .sidebar-product-box { margin-bottom: var(--s-6); }

/* ==========================================================================
   AMAZON PICKS — sidebar block, shared by the homepage fold, the category
   hubs' right-hand column and the article sidebar. These rules live here
   rather than in article.css because this sheet is the one loaded on all
   three of those surfaces; article.css is not.
   ========================================================================== */

.sidebar-product-box {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 16px 18px;
}

.sidebar-art-tag {
  display: block;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: 10px;
}

.product-item { border-bottom: 1px solid var(--hairline-soft); }
.product-item:last-of-type { border-bottom: none; }

/* These were var(--ink) with text-decoration: none -- pixel-identical to body
   copy -- and only became brass and underlined on :hover, which does not exist
   on a phone. Four of them sit in the one monetised block on the page, so a
   touch reader had no way to tell they were links at all. The underline is now
   always present, drawn in hairline so it reads as an affordance rather than as
   emphasis, and the row is a 44px touch target. */
.product-link {
  display: flex;
  font-size: 0.9375rem;
  line-height: 1.4;
  min-height: 44px;
  align-items: center;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--hairline);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.product-link:hover,
.product-link:focus-visible {
  color: var(--brass);
  text-decoration-color: var(--brass);
}

.affiliate-disclosure {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-style: italic;
  color: var(--muted);
  margin: 12px 0 0;
}

.beat-primer-subhead {
  font-family: var(--display);
  font-size: 0.9375rem; /* 15px */
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  margin: 14px 0 4px;
}

.beat-primer-body {
  font-family: var(--serif);
  font-size: 0.9375rem; /* 15px */
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0;
}

/* Separates the feed headlines from the rail above them in the same column. */
.secondary-label { margin-top: 6px; }

.primary-story, .secondary-story {
  padding: 12px 0 14px;
  border-bottom: 1px solid var(--hairline-soft);
}

.primary-story h3 {
  font-family: var(--display);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem); /* 17–20px */
  font-weight: 700;
  line-height: 1.3;
  margin: 2px 0 4px;
}

/* :is(h3, h4) because the heading level is a property of where the card sits,
   not of what it looks like -- the fold renders h3 (it follows the h2 lead
   directly) and the hubs render h4 (they follow the h3 primary cards). Keying
   the type on the tag name is what would silently unstyle one of them. */
.secondary-story :is(h3, h4) {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.35;
  margin: 2px 0 4px;
}

.story-excerpt {
  font-size: 0.9375rem; /* 15px */
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 6px 0 8px;
  max-width: 68ch;
}

/* ==========================================================================
   CATEGORY HEADER
   ========================================================================== */

.category-header {
  max-width: 1300px;
  margin: 10px auto var(--s-6);
  padding: 0 20px 18px;
  border-bottom: 4px solid var(--cat, var(--ink));
}

.category-header-title {
  font-family: var(--display);
  font-size: clamp(2rem, 1.4rem + 3vw, 3.5rem); /* 32–56px */
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}

/* A strapline naming what the beat covers -- NOT navigation. It used to be
   painted var(--cat, var(--brass)), which is the site's link colour, and set as
   a dot-separated row of section names sitting directly above the real chip nav.
   Every word of it invited a click and none of them were clickable: measured
   across the eight categories, 30 of the 42 names in these strings are not
   sections at all (on /opinion and /local, none of them are). Muted grey is the
   fix -- the copy keeps its keywords, and nothing about it now reads as a link. */
.category-tagline {
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 10px;
}

.category-description {
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 66ch;
  margin: 0;
}

/* ==========================================================================
   FEED SECTION & SUBCATEGORY CHIPS
   ========================================================================== */

.feed-section { max-width: 1300px; margin: 0 auto 30px; padding: 0 20px; }

.feed-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.feed-count {
  font-family: var(--sans);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.subcat-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 20px;
}

/* Names the chip row's job. Without it the page offered two topic rows -- the
   strapline above and these -- and nothing said which one did something. */
.subcat-chips-label {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 4px;
}

.subcat-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  box-sizing: border-box;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  text-decoration: none;
}

.subcat-chip:hover { border-color: var(--brass); color: var(--brass); }

.subcat-chip.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* ==========================================================================
   FEATURED GRID (category pages)
   ========================================================================== */

.featured-section { max-width: 1300px; margin: 0 auto 30px; padding: 0 20px; }

.featured-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}

.featured-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-top: 3px solid var(--cat, var(--brass));
  border-radius: 3px;
  padding: 16px 18px;
}

.featured-card h3 {
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 4px 0 8px;
}


/* Hover motion, gated for reduced-motion users. */
@media (prefers-reduced-motion: no-preference) {
  .featured-card, .subcat-chip, .read-more-btn, .theme-toggle {
    transition: color var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease), background var(--motion-fast) var(--ease);
  }
}

/* ==========================================================================
   THE FOLD — brief rail / lead / curated rail
   ========================================================================== */

.fold {
  display: grid;
  grid-template-columns: 0.85fr 1.5fr 1fr;
  gap: 0 28px;
  max-width: 1300px;
  margin: 0 auto 30px;
  padding: 0 20px;
}

/* Before the first feed refresh there are no briefs; a three-track grid would
   render an empty leftmost column. Two tracks hold the lead:rail ratio (1.5:1)
   the three-track version uses. Below 768px the fold collapses to one column
   and this never applies. */
.fold-no-briefs { grid-template-columns: 1.5fr 1fr; }

.fold-briefs { border-right: 1px solid var(--hairline); padding-right: 28px; }
.curated-rail { border-left: 1px solid var(--hairline); padding-left: 28px; }

/* DOM order is lead, briefs, rail (source/reading order — WCAG 1.3.2). Visual order
   above the 768px single-column collapse puts briefs left of the lead, so reorder with
   `order` here rather than in the markup; below 768px the fold collapses to one column
   and no `order` is set, so DOM order governs the stack unchanged. */
@media (min-width: 769px) {
  .fold-briefs { order: 1; }
  .fold-lead   { order: 2; }
  .curated-rail { order: 3; }

  /* The Amazon picks take a second row under the curated rail, in the fold's
     third column. Placed explicitly, since auto-placement would drop them into
     the next free cell — row 2 column 1, under the briefs — rather than beneath
     the rail. The other two zones span both rows with `grid-row: span 2` rather
     than a fixed start, so they keep the auto column placement `order` above
     gives them and their dividers still run the full height of the fold.

     These picks were a full-width band at 64% page depth; here they are at
     roughly 12%, without displacing anything Trill News wrote. */
  .fold-briefs, .fold-lead { grid-row: span 2; }

  .fold > .sidebar-product-box {
    grid-column: 3;
    grid-row: 2;
    border-left: 1px solid var(--hairline);
    padding-left: 28px;
    margin-top: var(--s-6);
  }

  /* Same source-order override as the columns above: without briefs the picks
     sit under the rail in the second track, not a third that no longer exists. */
  .fold-no-briefs > .sidebar-product-box { grid-column: 2; }
}

/* Heading plus its metadata on one line. The stamp is a sibling of the <h2>,
   never a child — inside it, the timestamp became part of the heading's
   accessible name and churned on every feed refresh. */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 12px;
}

.section-stamp,
.section-label em {
  font-style: normal;
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--brass);
}

/* Retained for any remaining .section-label em; the fold uses .section-head. */
.section-label em { float: right; }

.brief-rail { list-style: none; margin: 0; padding: 0; counter-reset: brief; }

.brief-item {
  counter-increment: brief;
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 0 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--hairline-soft);
}

.brief-item::before {
  content: counter(brief);
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--muted);
  line-height: 1.6;
}

.brief-body { font-size: 0.875rem; line-height: 1.45; color: var(--ink-soft); }

.brief-link {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ink);
}

.brief-link:hover { color: var(--brass); border-bottom-color: var(--brass); }
.brief-support { margin-left: 4px; }

.lead-headline {
  font-family: var(--display);
  font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.1;
  margin: 4px 0 8px;
  text-wrap: balance;
}

.lead-link { color: inherit; text-decoration: none; }
.lead-link:hover { text-decoration: underline; }

.lead-excerpt {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 62ch;
  margin: 10px 0 16px;
  text-wrap: pretty;
}

.fold-extra {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 20px;
  border-top: 1px solid var(--hairline);
  margin-top: 16px;
  padding-top: 12px;
}

.rail-card {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 0 12px;
  align-items: start;
  padding: 10px 0;
  border-bottom: 1px solid var(--hairline-soft);
}

.rail-thumb { margin: 0; }
.rail-text { min-width: 0; } /* grid items default to min-width:auto; a long unbroken
  headline token (RSS/Google News input) can otherwise blow out the card — see
  article.css:15,100 for the same idiom. */

.rail-thumb img {
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 3px;
  filter: var(--img-filter);
}

.rail-card h3 { font-family: var(--display); font-size: 0.9375rem; font-weight: 700; line-height: 1.3; margin: 2px 0 0; }
.curated-rail .text-link { display: inline-block; margin-top: 12px; }

/* ==========================================================================
   CATEGORY BANDS
   ========================================================================== */

.band-stack { max-width: 1300px; margin: 0 auto; padding: 0 20px; }

.category-band { border-top: 3px solid var(--cat, var(--ink)); padding-top: 10px; margin-top: var(--s-6); }

.band-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  color: var(--cat, var(--ink));
  border-bottom-color: var(--cat, var(--ink));
}

.band-more {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--brass);
  text-decoration: none;
  white-space: nowrap;
}

.band-more:hover { text-decoration: underline; }

.band-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 0 20px; }

.band-feature { display: grid; grid-template-columns: 160px 1fr; gap: 0 14px; align-items: start; }
.band-feature > div { min-width: 0; } /* text column; see .rail-text above for why */
.band-thumb { margin: 0; }

.band-thumb img {
  width: 160px;
  height: 120px;
  object-fit: cover;
  border-radius: 3px;
  filter: var(--img-filter);
}

.band-feature h3 { font-family: var(--display); font-size: 1.0625rem; font-weight: 700; line-height: 1.3; margin: 4px 0 6px; }
.band-link h4 { font-family: var(--display); font-size: 0.9375rem; font-weight: 700; line-height: 1.35; margin: 2px 0 4px; }

/* ==========================================================================
   ARTICLE ARCHIVE (/features)
   The full curated tier on one page: a jump nav, then one section per
   category. Sections use CSS columns rather than a grid so a category with 17
   articles and one with 35 both stay balanced without a per-section rule.
   ========================================================================== */

/* Sticky, because the archive runs to about ten screens across eight sections
   and this was position: static -- so the moment a reader scrolled into Sports,
   the only way to reach Culture was to scroll all the way back up. It carries
   its own --paper background and a hairline, or headlines show through it.

   It stays wrap-free and scrolls horizontally instead: eight 44px chips wrap to
   three rows on a phone, and a 132px bar pinned to the top of a 812px viewport
   costs more than it returns. */
.archive-jump {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-width: 1300px;
  margin: 0 auto 32px;
  padding: 10px 20px;
  background: var(--paper);
  border-bottom: 1px solid var(--hairline);
}

.archive-jump .subcat-chip { flex: 0 0 auto; }

.archive-jump-count {
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
  color: var(--brass);
}

.archive-section {
  max-width: 1300px;
  margin: 0 auto var(--s-10);
  padding: 0 20px;
  /* The jump links land here. The offset has to clear the sticky .archive-jump
     bar above (44px chip + 20px padding + border), or every jump lands with the
     section heading hidden behind it. */
  scroll-margin-top: 88px;
}

.archive-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  border-bottom: 2px solid var(--hairline);
  margin-bottom: 14px;
}

.archive-section-head .section-label { margin: 0 0 6px; }

.archive-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 40px;
}

.archive-item {
  break-inside: avoid;
  padding: 8px 0;
  border-bottom: 1px solid var(--hairline);
}

.archive-link {
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
  text-decoration: none;
}

.archive-link:hover { color: var(--brass); text-decoration: underline; }

.archive-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-top: 4px;
  font-family: var(--sans);
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.archive-meta time { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   404
   ========================================================================== */

.notfound-actions {
  max-width: 1300px;
  margin: 0 auto var(--s-8);
  padding: 0 20px;
}

.notfound-actions .search-form { margin: 0 0 18px; }

.notfound-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
