/* ============================================================================
   JLA / Diricom — canonical landing-page stylesheet   site.v1.css
   ----------------------------------------------------------------------------
   ONE file for every developed site. Per-site identity lives ONLY in the
   inline :root{} token block in each page's <head> (accent colours, fonts).
   Nothing site-specific belongs in here.

   Versioned filename on purpose: bump to site.v2.css to bust caches. The pages
   are served with cf-cache-status: DYNAMIC and max-age=0, so the HTML is never
   cached — this file is the only part that ever gets cached, which is the whole
   reason it is external.

   Class names are UNCHANGED from the previous inline styles. The nightly
   patchers (v2_content_updater.py, page_enhance_inject.py) emit fixed markup;
   renaming anything here silently unstyles their output.
   ========================================================================== */

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Design tokens ───────────────────────────────────────────────────────── */
:root {
  /* Spacing scale — 4px base. Replaces the ten ad-hoc values (2,4,6,8,10,12,
     14,20,24,32) that produced the off-rhythm Jim reported. Use these ONLY. */
  --s-1:  4px;
  --s-2:  8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  /* Layout constants. --gutter is fluid so the page breathes on phones and
     does not stay pinned at 20px on a 1440px screen. */
  --measure:  1560px;  /* 1100 -> 1240 -> 1560. At 1100 the main column was only
                          ~704px next to the sidebar, so the grid held 2 cards
                          and the page read left-weighted while the hero and Our
                          Picks (both full --measure) looked balanced.

                          1560 lets the content justify across a large monitor.
                          IMPORTANT: max-width never binds below its own value,
                          so every viewport under 1560px is byte-identical to
                          before — phones and tablets are mathematically
                          untouched by this. Verified across 320-1920px. */
  --gutter:   clamp(16px, 4vw, 32px);
  --prose:    68ch;    /* cap running text — a 844px line is ~110 characters */
  --sidebar:  300px;
  --col-min:  280px;   /* card grid minimum column. 280 not 300: at the 1024px
                          breakpoint a 300px minimum leaves only 4px of slack
                          beside the sidebar, so any rounding tips it back to a
                          single column — the exact bug being fixed. 280 gives
                          ~44px of slack and holds 2 columns consistently from
                          640px all the way up. */
  --main-max: 760px;   /* main column cap once the sidebar stacks — see note
                          at .content-with-sidebar for why this exists */

  /* Neutral surface tokens. Per-site files override --accent* only. */
  --bg:         #f8f8f6;
  --surface:    #ffffff;
  --text:       #1a1a1a;
  --text-muted: #6b7280;
  --border:     #e5e7eb;
  --shadow-sm:  0 1px 3px rgba(0,0,0,0.08);
  --shadow-md:  0 4px 16px rgba(0,0,0,0.10);
  --shadow-lg:  0 8px 24px rgba(0,0,0,0.14);
  --radius:     10px;

  --font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Playfair Display', Georgia, serif;
}

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }
a { color: inherit; }

/* ── Top bar ─────────────────────────────────────────────────────────────── */
.topbar {
  background: var(--text); color: #fff;
  font-size: 0.78em; letter-spacing: 0.02em;
  padding: var(--s-2) var(--gutter);
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: var(--s-2);
}
.topbar a { color: #9ca3af; text-decoration: none; }
.topbar a:hover { color: #fff; }

/* ── Header ──────────────────────────────────────────────────────────────
   Previously the gap between nav and first content accumulated ~60px from
   four independent rules (header padding + tagline margin + nav margin +
   datebar margin + container padding). Now the header owns its own block
   spacing and nothing stacks. */
header {
  background: var(--surface);
  border-bottom: 3px solid var(--accent);
  padding: var(--s-5) var(--gutter) 0;
  text-align: center;
}
.site-name {
  /* The site name is an h1 element (it is the page's actual heading). Browsers
     give h1 a 0.67em default margin that would push the whole header down, so
     pin it here — every visual property below is unchanged. */
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.2rem);
  color: var(--text); letter-spacing: -1px; line-height: 1.1;
}
.site-name span { color: var(--accent); }
.tagline {
  font-size: 0.72em; color: var(--text-muted);
  margin: var(--s-1) 0 var(--s-4);
  letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 400; opacity: 0.78;
}

/* ── Nav ─────────────────────────────────────────────────────────────────── */
nav {
  display: flex; gap: var(--s-1); justify-content: center; flex-wrap: wrap;
  padding: 0; margin: 0; border-top: 1px solid var(--border);
}
nav a {
  display: inline-block;
  padding: var(--s-3) var(--s-4);
  font-size: 0.82em; font-weight: 600; color: var(--text-muted);
  text-decoration: none; letter-spacing: 0.04em; text-transform: uppercase;
  border-bottom: 3px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  cursor: pointer;
}
nav a:hover, nav a.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Container ───────────────────────────────────────────────────────────── */
.container { max-width: var(--measure); margin: 0 auto; padding: var(--s-5) var(--gutter); }

/* ── Date bar ────────────────────────────────────────────────────────────── */
.datebar {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: var(--s-5); padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
  font-size: 0.79em; color: var(--text-muted); letter-spacing: 0.02em;
  gap: var(--s-3); flex-wrap: wrap;
}
.datebar-label { font-weight: 500; }
.datebar-updated { opacity: 0.75; text-align: right; }
.datebar-region-mid { text-align: center; flex: 1; }
.live-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: #22c55e; margin-right: var(--s-2); animation: pulse 2s infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@media (prefers-reduced-motion: reduce) {
  .live-dot { animation: none; }
  * { transition: none !important; }
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--s-5); margin-bottom: var(--s-5);
}
.hero-card {
  background: var(--surface); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow-md);
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  transition: transform 0.2s, box-shadow 0.2s;
}
.hero-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.hero-card-img {
  width: 100%; aspect-ratio: 16 / 10; height: auto;
  object-fit: cover; display: block; background: var(--accent-light);
  max-height: 360px;   /* at --measure 1560 the feature card is ~736px wide, and
                          a strict 16:10 would make the hero image 460px tall —
                          it would dominate the fold. object-fit: cover crops
                          rather than distorts. No effect below ~576px wide. */
}
.hero-card-img-placeholder {
  width: 100%; aspect-ratio: 16 / 10;
  background: linear-gradient(135deg, var(--accent-light), var(--accent));
  display: flex; align-items: center; justify-content: center; font-size: 3em;
}
.hero-card-body { padding: var(--s-5); flex: 1; }
.hero-badge {
  display: inline-block; background: var(--accent); color: #fff;
  font-size: 0.7em; font-weight: 700;
  padding: var(--s-1) var(--s-3); border-radius: 20px;
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-bottom: var(--s-3);
}
.hero-card h2 {
  font-family: var(--font-display); font-size: 1.4em; line-height: 1.3;
  color: var(--text); margin-bottom: var(--s-3);
}
.hero-card p {
  font-size: 0.88em; color: var(--text-muted); line-height: 1.6;
  margin-bottom: var(--s-3);
}
.card-meta {
  font-size: 0.75em; color: #9ca3af;
  display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap;
}
.card-meta-source { font-weight: 600; color: var(--accent); }

/* Hero stack — the 3 headlines beside the lead story.
   The three items are shorter than the feature card next to them, which left a
   block of dead space under the headlines (Jim, 2026-07-27). Stretching the
   items to share the full height squares the hero off against the feature. */
.hero-stack {
  display: flex; flex-direction: column; gap: var(--s-3);
  height: 100%;
}
.hero-stack-item {
  background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: var(--s-3);
  display: flex; gap: var(--s-3); align-items: center;
  flex: 1;                        /* share the hero's height evenly */
  text-decoration: none; color: inherit; transition: box-shadow 0.2s;
}
.hero-stack-item:hover { box-shadow: var(--shadow-md); }
.hero-stack-img {
  width: 80px; height: 70px; object-fit: cover; border-radius: 6px;
  flex-shrink: 0; background: var(--accent-light);
}
.hero-stack-body h3 { font-size: 0.92em; line-height: 1.35; margin-bottom: var(--s-1); }
.hero-stack-body .card-meta { margin-top: var(--s-1); }

/* ── Section header ──────────────────────────────────────────────────────── */
.section-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-3); margin-bottom: var(--s-4);
  padding-bottom: var(--s-2); border-bottom: 2px solid var(--accent);
}
.section-header h2 { font-family: var(--font-display); font-size: 1.5em; color: var(--text); }

/* ── Main / sidebar ──────────────────────────────────────────────────────
   THE 901–991px FIX.
   Before: sidebar collapsed at max-width:900px, but the main column needed
   992px of viewport before two 300px cards could fit beside it. Result: from
   901–991px the card grid rendered ONE card per row at 529–619px wide, i.e.
   shrinking the window improved the layout.

   Now the sidebar collapses at 1023px. At exactly 1024px the main column is
   1024 − gutter*2 − 300 − 32 = ~660px, which comfortably fits two columns.

   --main-max caps the main column once the sidebar stacks, so the grid does
   not jump 2 → 3 columns the instant the sidebar disappears. It also keeps a
   sane reading measure for article text. */
.content-with-sidebar {
  display: grid; grid-template-columns: 1fr var(--sidebar);
  gap: var(--s-6); align-items: start;
}

/* ── Card grid ───────────────────────────────────────────────────────────
   EXPLICIT column counts, not auto-fill. auto-fill derives the count from the
   available width, which is what let the count change unpredictably with the
   sidebar. Jim's spec: 3 per row on a full-size screen, 2 on smaller, 1 on a
   phone. Explicit counts make that exactly what happens at every width. */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5); margin-bottom: var(--s-6);
}
.card {
  background: var(--surface); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
  transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.card-img {
  width: 100%; aspect-ratio: 16 / 10; height: auto;
  object-fit: cover; display: block; background: var(--accent-light);
}
.card-img-placeholder {
  width: 100%; aspect-ratio: 16 / 10;
  background: linear-gradient(135deg, var(--accent-light), var(--accent));
  display: flex; align-items: center; justify-content: center; font-size: 2em;
}
.card-body { padding: var(--s-4); flex: 1; display: flex; flex-direction: column; }
.card-category {
  font-size: 0.68em; font-weight: 700; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: var(--s-2);
}
.card h3 { font-size: 1em; line-height: 1.35; margin-bottom: var(--s-2); }
.card p { font-size: 0.85em; color: var(--text-muted); margin-bottom: var(--s-3); }
.card-footer { margin-top: auto; }

/* ── Affiliate grid ──────────────────────────────────────────────────────── */
.affiliate-section { margin-bottom: var(--s-6); }
.affiliate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--s-4);
}
.affiliate-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s-4);
  text-decoration: none; color: inherit;
  transition: transform 0.2s, box-shadow 0.2s;
}
.affiliate-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.affiliate-card img {
  width: 100%; height: 120px; object-fit: cover;
  border-radius: 6px; margin-bottom: var(--s-2);
}
.affiliate-icon {
  font-size: 2em; text-align: center;
  margin-bottom: var(--s-2); color: var(--accent);
}
.affiliate-title { font-weight: 700; margin-bottom: var(--s-1); }
.affiliate-desc { font-size: 0.85em; color: var(--text-muted); margin-bottom: var(--s-2); }
.affiliate-cta { font-size: 0.82em; font-weight: 600; color: var(--accent); }

/* ── About section ───────────────────────────────────────────────────────── */
.about-section {
  background: var(--surface); border-radius: var(--radius);
  padding: var(--s-6); margin: 0 0 var(--s-6);
  box-shadow: var(--shadow-sm); border-left: 4px solid var(--accent);
}
.about-section h2 {
  font-family: var(--font-display); font-size: 1.3em;
  color: var(--text); margin-bottom: var(--s-3);
}
.about-section p {
  font-size: 0.93em; color: #4b5563; line-height: 1.8; margin-bottom: var(--s-3);
  max-width: var(--prose);   /* running text stays readable in a wide column */
}

/* ── Domain notice ───────────────────────────────────────────────────────
   An empty slot (<div class="domain-notice jla-adslot">) filled by
   page_enhance_inject with the DWS cross-promo. NOT a for-sale banner —
   the no-for-sale-signal rule (K6B-65) is not in tension with this. */
.domain-notice {
  text-align: center; margin: 0 0 var(--s-6);
  font-size: 0.82em; color: var(--text-muted);
}
.domain-notice a {
  color: var(--text-muted); text-decoration: none; font-weight: 500;
  border-bottom: 1px dotted var(--text-muted);
}
.domain-notice a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.domain-notice img.dws-logo-inline {
  display: block; height: 28px; width: auto;
  margin: var(--s-2) auto 0; opacity: 0.6; transition: opacity 0.2s;
}
.domain-notice a:hover img.dws-logo-inline { opacity: 1; }

/* ── Sidebar ─────────────────────────────────────────────────────────────
   Markup is <aside class="sidebar"> containing .sidebar-widget blocks.
   .sidebar-widget carries its own bottom margin, so no flex gap here. */
.sidebar-widget {
  background: var(--surface); border-radius: var(--radius);
  padding: var(--s-4); margin-bottom: var(--s-5);
  box-shadow: var(--shadow-sm); border: 1px solid var(--border);
}
.sidebar-widget h3 {
  font-size: 0.8em; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--text-muted);
  margin-bottom: var(--s-3); padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--border);
}
.sidebar-news-item {
  display: flex; gap: var(--s-3); align-items: flex-start;
  padding: var(--s-2) 0; border-bottom: 1px solid var(--border);
  text-decoration: none; color: inherit;
}
.sidebar-news-item:last-child { border-bottom: none; }
.sidebar-news-item:hover h4 { color: var(--accent); }
.sidebar-news-item h4 { font-size: 0.82em; font-weight: 600; line-height: 1.35; }
.sidebar-news-item span {
  font-size: 0.72em; color: #9ca3af; display: block; margin-top: var(--s-1);
}
.sidebar-num {
  font-size: 1.2em; font-weight: 800; color: var(--border);
  min-width: 24px; line-height: 1;
}

/* ── Sidebar DWS ad (taller variant of .dws-ad) ──────────────────────────── */
.dws-ad-sidebar {
  background: linear-gradient(160deg, #0d1b3e 0%, #0a3060 60%, #063d5c 100%);
  border-radius: var(--radius); padding: var(--s-6) var(--s-4);
  margin-bottom: var(--s-5);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: var(--s-3); border: 1px solid #1e3a6e;
  text-decoration: none; min-height: 250px; color: #fff;
  transition: transform 0.2s;
}
.dws-ad-sidebar:hover { transform: translateY(-2px); }
.dws-ad-sidebar img { height: 38px; width: auto; filter: brightness(0) invert(1); opacity: 0.92; }
.dws-ad-sidebar .dws-ad-headline { font-size: 0.92em; }
.dws-ad-sidebar .dws-ad-sub { font-size: 0.78em; color: #93c5fd; }
.dws-ad-sidebar ul { list-style: none; text-align: left; width: 100%; padding: 0 var(--s-2); }
.dws-ad-sidebar ul li {
  font-size: 0.76em; color: #bfdbfe; padding: var(--s-1) 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.dws-ad-sidebar ul li::before { content: '✓ '; color: #34d399; font-weight: 700; }
.dws-ad-headline {
  font-size: 0.88em; font-weight: 700; color: #fff;
  line-height: 1.3; margin-top: var(--s-1);
}
.dws-ad-cta {
  display: inline-block; margin-top: var(--s-2);
  background: #f59e0b; color: #1a1a1a;
  font-size: 0.78em; font-weight: 700;
  padding: var(--s-2) var(--s-5); border-radius: 20px; letter-spacing: 0.02em;
}

/* ── Email capture ───────────────────────────────────────────────────────── */
.capture-block, .email-capture-block {
  background: linear-gradient(135deg, #f4efe9 0%, #fcfbf8 100%);
  border: 1px solid #d7ccc8; border-left: 4px solid var(--accent);
  border-radius: var(--radius); padding: var(--s-5);
  margin: 0 0 var(--s-6); box-shadow: var(--shadow-sm);
}
.capture-copy h3 {
  font-family: var(--font-display); font-size: 1.2em;
  color: var(--text); margin-bottom: var(--s-3);
}
.capture-copy p {
  font-size: 0.92em; color: #475569; line-height: 1.7; margin-bottom: var(--s-4);
}
.capture-fields {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--s-3); margin-bottom: var(--s-3);
}
.capture-form input, .capture-form textarea {
  width: 100%; border: 1px solid #cbd5e1; border-radius: 8px;
  padding: var(--s-3) var(--s-3); font: inherit;
  background: #fff; color: var(--text);
}
.capture-form textarea { min-height: 108px; resize: vertical; margin-bottom: var(--s-3); }
.capture-actions { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; }
.capture-form button {
  background: var(--accent); color: #fff; border: none; border-radius: 999px;
  padding: var(--s-3) var(--s-4); font-weight: 700; cursor: pointer;
}
.capture-secondary { color: var(--accent-dark); font-weight: 600; text-decoration: none; }
.capture-secondary:hover { text-decoration: underline; }

/* ── DWS house ad ────────────────────────────────────────────────────────── */
.dws-ad {
  background: linear-gradient(135deg, #0d1b3e 0%, #0a3060 60%, #063d5c 100%);
  border-radius: var(--radius); padding: var(--s-5) var(--s-4);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: var(--s-3); border: 1px solid #1e3a6e;
  text-decoration: none; color: #fff;
  transition: transform 0.2s, box-shadow 0.2s;
}
.dws-ad:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.dws-logo-text { line-height: 1; margin-bottom: var(--s-1); }
.dws-logo-text span {
  display: block; font-size: 1.1em; font-weight: 800; color: #fff;
  letter-spacing: -0.5px; font-family: var(--font-body);
}
.dws-logo-text em {
  display: block; font-size: 0.65em; font-weight: 600; color: #93c5fd;
  letter-spacing: 0.12em; text-transform: uppercase; font-style: normal;
}

/* ── Disclosure ──────────────────────────────────────────────────────────── */
.disclosure-bar {
  font-size: 0.78em; color: var(--text-muted);
  background: var(--accent-light); border-radius: var(--radius);
  padding: var(--s-3) var(--s-4); margin-bottom: var(--s-5);
}
.disclosure-bar a { color: var(--accent); text-decoration: none; }
.disclosure-bar a:hover { text-decoration: underline; }

/* ── page_enhance_inject blocks ──────────────────────────────────────────
   These were a SECOND design system: hardcoded colours, -apple-system font,
   max-widths of 1080px and 960px against the container's 1100px, and 16px
   gutters against the container's 20px. The visible symptom was the "Our
   Picks" and disclosure blocks not sharing a left edge with the content above
   them. They now inherit --measure, --gutter and the shared tokens. */
.jla-picks {
  max-width: var(--measure); margin: var(--s-6) auto 0;
  padding: 0 var(--gutter); font-family: var(--font-body);
}
.jla-picks h3 { font-size: 1.15em; margin: 0 0 var(--s-3); }
/* Pinned to 3 explicitly. Jim approved this section's look ("centered and 3
   which looks good") — auto-fit would have started returning 4 or 5 across once
   --measure widened to 1240, changing something he already signed off on. */
.jla-picks-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
}
.jla-pick {
  border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
  text-decoration: none; color: var(--text); background: var(--surface);
  display: flex; flex-direction: column;
  transition: transform 0.2s, box-shadow 0.2s;
}
.jla-pick:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.jla-pick img { width: 100%; aspect-ratio: 16 / 10; height: auto; object-fit: cover; }
.jla-pick span {
  padding: var(--s-3); font-size: 0.85em; line-height: 1.45; font-weight: 600;
}
.jla-pick em {
  display: block; font-style: normal; color: var(--accent-dark);
  font-size: 0.78em; margin-top: var(--s-1);
}
.jla-disclosure {
  max-width: var(--measure); margin: var(--s-6) auto var(--s-2);
  padding: 0 var(--gutter);
  font-size: 0.78em; line-height: 1.6; color: var(--text-muted); text-align: center;
}

.jla-fill {
  display: block; border-radius: var(--radius); overflow: hidden; position: relative;
  margin: var(--s-3) 0; text-decoration: none;
  font-family: var(--font-body); font-size: 0.875em; line-height: 1.5;
}
.jla-fill.jla-fill-product {
  border: 1px solid var(--border); padding: var(--s-4); text-align: center;
  background: var(--bg); color: var(--text);
}
.jla-fill.jla-fill-product img {
  max-width: 100%; height: 110px; object-fit: cover;
  border-radius: 6px; margin-bottom: var(--s-2); display: block;
}
.jla-fill .k {
  font-size: 0.7em; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted); display: block; margin-bottom: var(--s-1);
}
.jla-fill.jla-fill-product .jla-fill-title { color: var(--accent-dark); font-weight: 700; }
.jla-fill.jla-promo { min-height: 170px; color: #fff; }
.jla-fill.jla-promo img {
  width: 100%; height: 170px; object-fit: cover; display: block;
  filter: brightness(.62) saturate(1.05);
}
.jla-fill.jla-promo .jla-promo-text {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--s-4) var(--s-4) var(--s-3);
  background: linear-gradient(180deg, rgba(8,12,16,0) 0%, rgba(8,12,16,.85) 88%);
}
.jla-fill.jla-promo .k { color: #e2e6ea; }
.jla-fill.jla-promo strong {
  display: block; font-size: 0.95em; line-height: 1.3;
  margin-bottom: var(--s-1); font-weight: 700;
}
.jla-fill.jla-promo em {
  font-style: normal; font-size: 0.8em; font-weight: 700; color: #fff;
  text-decoration: underline; text-underline-offset: 2px;
}
.jla-fill.jla-psa .jla-promo-text {
  background: linear-gradient(180deg, rgba(6,20,30,0) 0%, rgba(6,20,30,.9) 82%);
}
.jla-fill.jla-psa .k { color: #9fd8ff; }
.jla-fill.jla-psa small {
  display: block; font-size: 0.78em; line-height: 1.45;
  color: #dbe4ea; margin: 0 0 var(--s-2); font-weight: 400;
}

/* ── AdSense hygiene — keep unfilled slots from leaving holes ────────────── */
.adsbygoogle:not([data-adsbygoogle-status]) { min-height: 0 !important; }
.top-ad-slot { min-height: 0; overflow: hidden; }
.top-ad-slot:empty, .top-ad-slot ins:empty { display: none; }
ins.adsbygoogle[data-ad-status="unfilled"],
ins.adsbygoogle:not([data-ad-status]) { display: none !important; }

/* ── Footer ──────────────────────────────────────────────────────────────── */
footer {
  background: #111827; color: #6b7280;
  padding: var(--s-6) var(--gutter); font-size: 0.82em;
}
.footer-inner {
  max-width: var(--measure); margin: 0 auto;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5);
}
footer h4 {
  color: #e5e7eb; font-size: 0.85em; margin-bottom: var(--s-3);
  text-transform: uppercase; letter-spacing: 0.06em;
}
footer a { color: #6b7280; text-decoration: none; display: block; margin-bottom: var(--s-2); }
footer a:hover { color: var(--accent); }
.footer-bottom {
  max-width: var(--measure); margin: var(--s-5) auto 0;
  padding-top: var(--s-4); border-top: 1px solid #1f2937;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--s-2);
}
/* Domain-inquiry link (K6B-65): deliberately plain — no styling, no callout. */
.footer-bottom .domain-inquiry { color: #4b5563; }

/* ============================================================================
   BREAKPOINTS — one coherent ladder, replacing the previous three ad-hoc
   queries at 700/900/700 that left the 901–991px dead zone.
     >= 1024px  full layout with sidebar
     <  1024px  sidebar stacks, main column capped at --main-max
     <   768px  hero stacks
     <   640px  footer stacks, tighter rhythm
   ========================================================================== */

/* On a large monitor the main column reaches ~1164px, where 3 cards would be
   372px each and start to look stretched. A 4th column keeps the card size in
   the same range as the rest of the ladder (273px).
   Our Picks deliberately stays at 3 — build_block only ever samples 3 products,
   so a 4-column track would leave a visible empty cell. */
@media (min-width: 1600px) {
  .grid { grid-template-columns: repeat(4, 1fr); }
}

/* 3 across only while the main column can carry it. Below 1200 the sidebar is
   still present but the column is too narrow for 3 readable cards, so drop to
   2 — Jim: "Mobile and smaller viewers can be two." */
@media (max-width: 1199px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 1023px) {
  .content-with-sidebar { grid-template-columns: 1fr; }
  /* Cap the main column so the card grid does not jump column count the
     instant the sidebar stacks, and so text keeps a readable measure. */
  .content-with-sidebar > .main-content,
  .content-with-sidebar > .sidebar {
    max-width: var(--main-max); width: 100%; margin-left: auto; margin-right: auto;
  }
  /* The stack sits under the feature card here, so stretching it would leave
     three tall, mostly-empty rows. Back to natural height. */
  .hero-stack { height: auto; }
  .hero-stack-item { flex: initial; }
}

@media (max-width: 767px) {
  .hero { grid-template-columns: 1fr; gap: var(--s-4); }
  .grid { gap: var(--s-4); }
  .jla-picks-grid { grid-template-columns: repeat(2, 1fr); }
  .section-header { flex-direction: column; align-items: flex-start; gap: var(--s-1); }
  .datebar { font-size: 0.74em; }
  .datebar-region-mid { display: none; }   /* the first thing to drop when tight */
  .about-section { padding: var(--s-5); }
}

@media (max-width: 639px) {
  .grid { grid-template-columns: 1fr; }
  .jla-picks-grid { grid-template-columns: 1fr; }
  .footer-inner { grid-template-columns: 1fr; gap: var(--s-4); }
  .container { padding: var(--s-4) var(--gutter); }
  .hero-card-body { padding: var(--s-4); }
  .topbar { font-size: 0.72em; }
  nav a { padding: var(--s-2) var(--s-3); }
  .footer-bottom { justify-content: flex-start; }
  .capture-fields { grid-template-columns: 1fr; }   /* two inputs side-by-side is
                                                       unusable at phone width */
}

/* ===== Path-A grid-gap fix (K6B-57) — equal-height news-grid cells ===== */
/* 1) Collapse an unfilled in-feed AdSense wrapper so it never leaves a short/blank cell. */
.grid > div:has(> ins.adsbygoogle:not([data-ad-status])),
.grid > div:has(> ins.adsbygoogle[data-ad-status="unfilled"]) { display: none; }
/* 2) Every remaining grid cell fills its row height; promo/product fills cover the cell
      instead of sitting short and leaving a gap next to taller article cards. */
.grid { align-items: stretch; }
.grid > * { height: 100%; }
.grid > .card.jla-adslot > .jla-fill { margin: 0; height: 100%; min-height: 0; }
.grid .jla-fill.jla-promo { min-height: 0; }
.grid .jla-fill.jla-promo img { height: 100%; }
.grid .jla-fill.jla-fill-product { justify-content: center; }

/* ===== Trailing-cell ordering (K6B-57) =====
   5 domains (fancypickle, dinenow, bringboat, flybrew, picklefancy) carry an
   orphaned hand-injected region-personalisation script that re-appends the
   article cards to the end of .grid. Anything it does not sort — the in-feed
   AdSense wrapper and the jla-adslot fill cell — is left behind at the TOP,
   which pushes a full-height article card into the last row alone next to a
   two-column-wide void. beerfitters has no such script, which is why it looks
   right and they do not.
   `order` is resolved at layout time, so it pins those two cells last no matter
   what the script does to DOM order. Fixes it without touching that JS. */
.grid > * { order: 0; }
.grid > div:has(> ins.adsbygoogle) { order: 1; }
.grid > .card.jla-adslot { order: 2; }

/* ===== Inline-block parity (pre-sweep) =====
   The 62 pages awaiting migration style these inline. site.v1.css did not
   define them, so linking the sheet and dropping the inline block would have
   removed the behaviour with no error anywhere. Measured, not assumed: these
   are the only three classes in the shortfall. */

/* The category tab filter marks non-matching cards. Load-bearing on all 62. */
.card.hidden { display: none; }

/* An unfilled top ad collapses to nothing rather than leaving a hole. */
.top-ad-slot.is-collapsed { display: none !important; }

/* aircheck.com only: gradient caption panel over an affiliate visual. */
.affiliate-visual {
  width: 100%; height: 120px; border-radius: 10px; margin-bottom: 8px;
  display: flex; align-items: flex-end; padding: 12px;
  color: #fff; font-size: 0.96em; font-weight: 700; letter-spacing: 0.02em;
  box-shadow: inset 0 -40px 60px rgba(15, 23, 42, 0.45);
}

/* ===== Trust / disclosure block parity (V3, 2026-08-10) =====
   .trust-grid, .trust-card, .notice-links and .inline-disclosure are emitted by
   the page markup but were never ported into this sheet, so they rendered as
   unstyled stacked text. Rules ported from v2_batch_builder.py's inline block
   (the proven originals), re-expressed on this sheet's spacing scale.

   Not a latent risk to the held 62-page sweep: only 3 of 145 live pages carry a
   .trust-grid today, so nothing currently deployed is losing styling. This is
   parity for pages that DO emit the block. */
.trust-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
              gap: var(--s-4); margin: var(--s-2) 0 var(--s-6); }
.trust-card { background: var(--surface); border: 1px solid var(--border);
              border-radius: var(--radius); padding: var(--s-4); box-shadow: var(--shadow-sm); }
.trust-card h3 { font-size: .88em; font-weight: 700; color: var(--text);
                 margin-bottom: var(--s-2); text-transform: uppercase; letter-spacing: .05em; }
.trust-card p { font-size: .83em; color: var(--text-muted); line-height: 1.6; margin: 0; }

.notice-links { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.notice-links a { display: inline-flex; align-items: center; font-size: .78em; font-weight: 600;
                  color: var(--accent); text-decoration: none; padding: var(--s-1) var(--s-3);
                  background: var(--accent-light); border-radius: 999px; }
.notice-links a:hover { text-decoration: underline; }

/* FTC affiliate disclosure above the product grid — deliberately visible.
   Amazon Associates requires a clear disclosure near affiliate links. */
.inline-disclosure { background: #fff8e1; border: 1px solid #f6d365; border-radius: var(--radius);
                     padding: var(--s-3) var(--s-4); margin: 0 0 var(--s-3); font-size: .8em;
                     color: #5f4b32; line-height: 1.6; }
.inline-disclosure strong { color: #3f2d1c; }

/* ===== House artwork banners (V3, 2026-08-10) =====
   The .jla-banner* family (Diricom 'diricom-stack' + GetMyNameNow
   'getmyname-urgency') renders entirely in HTML/CSS with no photo. Its rules
   lived ONLY inside page_enhance_inject.py's client-injected <style> block,
   so a page that renders these creatives without the enhancer got the markup
   and none of the art. Ported verbatim from that block so the creatives look
   identical to how they shipped. */
.jla-fill.jla-banner { display:block; position:relative; height:170px; min-height:170px; margin:10px 0; overflow:hidden; isolation:isolate; border-radius:10px; text-decoration:none; container-type:inline-size; }
.jla-banner, .jla-banner * { box-sizing:border-box; }
.jla-banner-inner { position:absolute; z-index:4; inset:0; display:flex; align-items:center; padding:0 clamp(15px,3cqw,32px); gap:clamp(14px,3cqw,34px); }
.jla-banner-brand { width:clamp(88px,14cqw,150px); flex:0 0 auto; font:800 clamp(15px,2cqw,23px)/.95 Manrope,"Segoe UI",Arial,sans-serif; letter-spacing:-.055em; }
.jla-banner-brand small { display:block; margin-top:5px; font-size:10px; line-height:1; text-transform:uppercase; letter-spacing:.12em; }
.jla-banner-copy { position:relative; z-index:4; max-width:48cqw; }
.jla-banner-kicker { display:block; font-size:clamp(9px,1.05cqw,12px); font-weight:800; line-height:1; text-transform:uppercase; letter-spacing:.14em; }
.jla-banner-headline { display:block; margin-top:5px; font-weight:900; letter-spacing:-.04em; line-height:.9; }
.jla-banner-headline b { display:block; }
.jla-banner-sub { display:block; margin-top:7px; font-size:clamp(10px,1.25cqw,14px); line-height:1.25; }
.jla-banner-cta { position:relative; z-index:5; display:inline-flex; align-items:center; justify-content:center; gap:9px; min-height:40px; margin-left:auto; padding:10px 14px; font-size:clamp(11px,1.15cqw,14px); font-weight:800; line-height:1; white-space:nowrap; }
.jla-banner-cta::after { content:"→"; font-size:1.15em; }
.jla-banner-art { position:absolute; z-index:2; pointer-events:none; }

/* D2 — The web stack, minus the stack. */
.jla-banner-diricom-stack { color:#fff; background:#0a2032; font-family:Manrope,"Segoe UI",Arial,sans-serif; }
.jla-banner-diricom-stack::before { content:""; position:absolute; z-index:0; inset:0; background:linear-gradient(90deg,rgba(8,127,125,.23),transparent 48%),repeating-linear-gradient(90deg,rgba(255,255,255,.035) 0 1px,transparent 1px 42px); }
.jla-banner-diricom-stack .jla-banner-brand small,.jla-banner-diricom-stack .jla-banner-kicker,.jla-banner-diricom-stack .jla-banner-headline b { color:#79cfcb; }
.jla-banner-diricom-stack .jla-banner-headline { font:700 clamp(22px,3.2cqw,37px)/.9 Manrope,"Segoe UI",Arial,sans-serif; }
.jla-banner-diricom-stack .jla-banner-sub { color:#b9c8d2; }
.jla-banner-diricom-stack .jla-banner-cta { color:#10283e; background:#f4f1e9; border-radius:2px; }
.jla-banner-tab-stack { right:clamp(130px,18cqw,200px); top:18px; width:clamp(150px,22cqw,250px); height:134px; transform:rotate(-2deg); }
.jla-banner-tab { position:absolute; left:0; right:0; height:38px; display:flex; align-items:center; padding:0 12px; border:1px solid rgba(255,255,255,.22); color:#dce6ec; background:#17364c; font:700 clamp(8px,.95cqw,11px)/1 "Segoe UI",Arial,sans-serif; letter-spacing:.05em; }
.jla-banner-tab::before { content:""; width:8px; height:8px; margin-right:8px; background:#79cfcb; }
.jla-banner-tab:nth-child(1) { top:0; transform:translateX(-18px); }
.jla-banner-tab:nth-child(2) { top:31px; transform:translateX(-7px); }
.jla-banner-tab:nth-child(3) { top:62px; transform:translateX(5px); }
.jla-banner-tab:nth-child(4) { top:93px; transform:translateX(17px); color:#fff; background:#087f7d; border-color:#4ec4bd; }

/* G2 — Name it before somebody else does. */
.jla-banner-getmyname-urgency { color:#080a0f; background:#f7df45; border:4px solid #080a0f; font-family:"Arial Narrow",Impact,sans-serif; }
.jla-banner-getmyname-urgency::before { content:""; position:absolute; z-index:0; inset:0; background:repeating-linear-gradient(-45deg,rgba(0,0,0,.035) 0 8px,transparent 8px 16px); }
.jla-banner-getmyname-urgency .jla-banner-brand { font:900 clamp(16px,2.15cqw,25px)/.86 "Arial Narrow",Impact,sans-serif; text-transform:uppercase; letter-spacing:-.04em; }
.jla-banner-getmyname-urgency .jla-banner-brand b { display:inline; padding:0 3px; color:#f7df45; background:#080a0f; }
.jla-banner-getmyname-urgency .jla-banner-brand small { color:#3f3b19; font-family:"Segoe UI",Arial,sans-serif; }
.jla-banner-getmyname-urgency .jla-banner-copy { max-width:48cqw; }
.jla-banner-getmyname-urgency .jla-banner-kicker { color:#7b1f48; font-family:"Segoe UI",Arial,sans-serif; }
.jla-banner-getmyname-urgency .jla-banner-headline { font:900 clamp(23px,3.65cqw,42px)/.9 "Arial Narrow",Impact,sans-serif; text-transform:uppercase; letter-spacing:-.03em; }
.jla-banner-getmyname-urgency .jla-banner-headline b { display:inline-block; padding:0 .1em; color:#fff; background:#ff3d81; }
.jla-banner-getmyname-urgency .jla-banner-sub { color:#423c15; font-family:"Segoe UI",Arial,sans-serif; font-weight:700; }
.jla-banner-getmyname-urgency .jla-banner-cta { color:#fff; background:#080a0f; border-radius:0; text-transform:uppercase; font-family:"Segoe UI",Arial,sans-serif; }
.jla-banner-ticket-stack { right:clamp(130px,18cqw,195px); top:18px; width:clamp(160px,23cqw,255px); height:136px; }
.jla-banner-ticket { position:absolute; width:82%; height:52px; display:flex; align-items:center; justify-content:space-between; padding:0 11px; border:3px solid #080a0f; color:#080a0f; background:#fff; font:900 clamp(10px,1.35cqw,15px)/1 "Segoe UI",Arial,sans-serif; }
.jla-banner-ticket b { color:#ff3d81; }
.jla-banner-ticket:nth-child(1) { top:0; left:0; transform:rotate(-4deg); }
.jla-banner-ticket:nth-child(2) { top:38px; left:12%; transform:rotate(2deg); background:#36f4ff; }
.jla-banner-ticket:nth-child(3) { top:78px; left:3%; transform:rotate(-1deg); background:#b6ff4d; }


/* ===== Banner copy/art collision fix (V3, 2026-08-10) =====
   The headline runs UNDER the absolutely-positioned ticket/tab artwork once the
   banner's container drops below ~1200px. Measured live: boatburg.com at a
   1440px container is clean; aircheck.com and toddybrook.com at 728px overlap,
   as did the V3 notice slot at 1044px. Pre-existing width-dependent bug in the
   shared creative, not a V3 regression -- but it makes the ad look broken at
   the most common width.

   SPECIFICITY NOTE, learned the hard way: a first attempt targeting plain
   `.jla-banner-copy` did nothing, because each creative carries its own
   higher-specificity override (`.jla-banner-getmyname-urgency .jla-banner-copy`
   etc.). Container queries add NO specificity, so the generic rule lost. These
   selectors are deliberately specific enough to win.

   Full ad/house-promo design pass remains K6B-83. */
@container (max-width: 1200px) {
  .jla-fill.jla-banner .jla-banner-copy,
  .jla-banner-getmyname-urgency .jla-banner-copy,
  .jla-banner-diricom-stack .jla-banner-copy { max-width: 33cqw; }
}
@container (max-width: 820px) {
  .jla-fill.jla-banner .jla-banner-copy,
  .jla-banner-getmyname-urgency .jla-banner-copy,
  .jla-banner-diricom-stack .jla-banner-copy { max-width: 30cqw; }
  .jla-fill.jla-banner .jla-banner-art { opacity: .5; }
}

/* ===== Mobile overflow fixes (V3 rollout, 2026-08-11) =====
   Found by the 47-domain rollout, invisible on the three pilots because they
   all have SHORT names. Measured at 390x844:

     <span>.COM</span>  right=476  on radiostationservices.com (20 characters)
     .jla-banner-cta    right=421  wherever an artwork banner is dealt

   1) .site-name clamps to a 2rem FLOOR. At 390px that is ~32px, and 20 caps of
      the display face is ~476px — the floor itself is the overflow. Give narrow
      viewports a real floor and a hard backstop so no future long domain can
      overflow again regardless of length.

   2) The banner lays out brand + copy + CTA in one absolute flex row with the
      CTA nowrap and margin-left:auto. Below ~520px of container there is not
      room for three columns, so the CTA pushes out. Drop the brand lozenge and
      tighten the CTA at that width — the copy and CTA are what carry the ad,
      and the whole banner is a link anyway. */
@media (max-width: 639px) {
  .site-name {
    font-size: clamp(1.25rem, 6.5vw, 2rem);
    letter-spacing: -.5px;
    overflow-wrap: anywhere;   /* backstop: wrap rather than overflow, ever */
  }
}

@container (max-width: 520px) {
  .jla-banner-brand { display: none; }
  .jla-banner-inner { padding: 0 12px; gap: 10px; }
  .jla-banner-copy  { max-width: 58cqw; }
  .jla-banner-cta   { padding: 8px 10px; font-size: 11px; min-height: 34px; gap: 6px; }
}
