/* Hallmark · genre: editorial · macrostructure: Bento Grid (home) / Index-First (category) /
 * Long Document (article) / Letter (about) · theme: TrundlePaw (kept brand, OKLCH) ·
 * enrichment: none (typography only) · nav: N6 Newspaper masthead · footer: Ft7 Newsletter-first
 * design-system: design.md · designed-as-app
 * pre-emit critique: P4 H4 E4 S4 R4 V4
 * ========================================================================== */

@import url("tokens.css");

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
body { overflow-x: clip; }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
h1, h2, h3, h4, p, li, blockquote, figcaption { overflow-wrap: break-word; }
ul[class], ol[class] { padding: 0; list-style: none; }
img, picture, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
a { color: inherit; text-decoration-skip-ink: auto; }
button { cursor: pointer; background: none; border: 0; font: inherit; }

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

body {
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--page-gutter); }
.measure { max-width: 65ch; }

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.1; color: var(--color-ink); font-style: normal; }
h1 { font-weight: 700; letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.1rem); margin-top: var(--space-2xl); margin-bottom: var(--space-md); letter-spacing: -0.01em; }
h3 { font-size: 1.3rem; margin-top: var(--space-xl); margin-bottom: var(--space-sm); }
p { margin-bottom: var(--space-md); }
em { font-style: italic; } /* body-copy emphasis only — headings never receive this */

a.text-link { color: var(--color-accent-text); text-underline-offset: 3px; text-decoration-thickness: 1px; transition: text-decoration-thickness var(--dur-micro) var(--ease-out); }
a.text-link:hover, a.text-link:focus-visible { text-decoration-thickness: 2px; }

.byline, .tabular {
  font-family: var(--font-outlier);
  font-variant-numeric: tabular-nums;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

.skip-link {
  position: absolute; top: -100px; left: var(--space-md); z-index: var(--z-toast);
  background: var(--color-ink); color: var(--color-paper); padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-input); font-weight: 700; transition: top var(--dur-micro) var(--ease-out);
}
.skip-link:focus { top: var(--space-md); }

/* ---- Focus ---- */
:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* ---- CTA voice ----
 * Primary = filled amber pill, reserved for the one real transactional action
 * (newsletter subscribe). Secondary/internal = typographic link or outlined chip.
 * No "Learn more →" card-footer links; no gradient fills.
 */
.cta-fill {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  padding: var(--space-sm) var(--space-lg); border-radius: var(--radius-pill);
  background: var(--color-accent); color: var(--color-paper); font-weight: 700; font-size: var(--text-sm);
  white-space: nowrap; min-height: 44px;
  transition: transform var(--dur-micro) var(--ease-out), box-shadow var(--dur-short) var(--ease-out);
}
.cta-fill:hover { transform: translateY(-1px); box-shadow: 0 6px 16px -8px oklch(50% 0.15 50 / 0.55); }
.cta-fill:active { transform: translateY(0) scale(0.98); box-shadow: none; }

.cta-chip {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill);
  border: var(--rule-hair) solid var(--color-rule); font-weight: 700; font-size: var(--text-sm);
  min-height: 44px; white-space: nowrap;
  transition: border-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
.cta-chip:hover { border-color: var(--color-accent-text); color: var(--color-accent-text); }
.cta-chip:active { transform: scale(0.97); }

.cta-link {
  position: relative; display: inline-flex; align-items: center; gap: var(--space-3xs);
  font-weight: 700; color: var(--color-accent-text); padding-bottom: 2px;
}
.cta-link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: currentColor; transform: scaleX(0.35); transform-origin: left;
  transition: transform var(--dur-short) var(--ease-out);
}
.cta-link:hover::after, .cta-link:focus-visible::after { transform: scaleX(1); }
.cta-link svg { transition: transform var(--dur-short) var(--ease-out); }
.cta-link:hover svg { transform: translateX(2px); }

.icon-btn {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill); flex-shrink: 0;
}
.icon-btn { transition: background var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out); }
.icon-btn:hover { background: var(--color-paper-2); }
.icon-btn:active { transform: scale(0.92); }
.icon-btn svg { width: 19px; height: 19px; }

/* ==========================================================================
 * N6 Newspaper masthead — site-wide nav
 * ========================================================================== */
.nav-mast {
  /* z-tooltip (highest named level) on purpose: .nav-mast establishes its
     own stacking context (position + z-index), so its z-index rank — not
     the mobile panel's internal z-index — is what decides whether the open
     menu paints above sibling fixed elements elsewhere in the document
     (.cookie-banner, .mobile-anchor-ad). Those live outside .nav-mast's
     subtree, so only outranking the header itself, not just the panel
     inside it, keeps the open menu on top of everything else on the page.
     NO backdrop-filter/filter/transform here — any of those on an ancestor
     makes a descendant's position:fixed act relative to THAT ancestor
     instead of the viewport, which is exactly why the mobile menu was
     scrolling with the page instead of staying pinned full-screen. */
  position: sticky; top: 0; z-index: var(--z-tooltip);
  background: var(--color-paper);
  padding: var(--space-sm) var(--page-gutter) 0;
  transition: box-shadow var(--dur-short) var(--ease-out);
}
.nav-mast.is-scrolled { box-shadow: 0 1px 0 var(--color-rule), 0 8px 20px -18px oklch(20% 0.02 60 / 0.4); }
.mast-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); max-width: var(--wrap); margin-inline: auto; }
.mast-line {
  font-family: var(--font-body); font-variant-caps: all-small-caps; font-weight: 700;
  letter-spacing: 0.08em; font-size: var(--text-xs); color: var(--color-muted);
}
.mast-center { text-align: center; padding: var(--space-2xs) 0; }
.mast-name {
  font-family: var(--font-display); font-weight: 700; font-style: normal;
  font-size: clamp(1.9rem, 4vw, 2.9rem); letter-spacing: -0.01em; line-height: 0.95;
  display: inline-block;
}
.mast-name:hover { color: var(--color-accent-text); }

.mast-nav-row { display: flex; align-items: center; justify-content: center; padding-top: var(--space-xs); position: relative; }
.mast-nav ul { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2xs) var(--space-lg); }
.mast-nav > ul > li { position: relative; }
.mast-nav a {
  position: relative; display: block; padding: var(--space-xs) var(--space-2xs);
  font-weight: 700; font-size: var(--text-sm); color: var(--color-muted);
  transition: color var(--dur-short) var(--ease-out);
}
.mast-nav > ul > li > a::after {
  content: ''; position: absolute; left: var(--space-2xs); right: var(--space-2xs); bottom: 2px; height: 2px;
  background: var(--color-accent); transform: scaleX(0); transform-origin: center;
  transition: transform var(--dur-short) var(--ease-out);
}
.mast-nav > ul > li > a:hover, .mast-nav > ul > li > a[aria-current="page"] { color: var(--color-ink); }
.mast-nav > ul > li > a:hover::after, .mast-nav > ul > li > a[aria-current="page"]::after { transform: scaleX(1); }
.has-dropdown { display: flex; align-items: center; }
.has-dropdown > a::after {
  content: '▾'; display: inline-block; font-size: .7em; margin-left: 4px;
  transition: transform var(--dur-short) var(--ease-out);
}
.has-dropdown.is-open > a::after { transform: rotate(180deg); }
.dropdown {
  /* Explicit column, not inherited: .mast-nav ul (the generic nav-row rule)
     also matches this element — it's a <ul> nested inside .mast-nav — and
     would otherwise lay Dog Breeds / Cat Breeds out as a side-by-side row
     instead of one under the other. */
  display: flex; flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0;
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(4px);
  min-width: 190px; background: var(--color-paper-2); border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card); padding: var(--space-xs); margin-top: var(--space-xs);
  opacity: 0; visibility: hidden;
  box-shadow: 0 10px 24px -12px oklch(20% 0.02 60 / 0.28);
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out);
  z-index: var(--z-dropdown);
}
/* Small pointer triangle — the plainest possible signal that this panel
   belongs to the link above it, not a floating unrelated box. */
.dropdown::before {
  content: ''; position: absolute; top: -5px; left: 50%; transform: translateX(-50%);
  width: 10px; height: 10px; background: var(--color-paper-2);
  border-left: var(--rule-hair) solid var(--color-rule); border-top: var(--rule-hair) solid var(--color-rule);
  border-radius: 2px 0 0 0; rotate: 45deg;
}
.has-dropdown:hover .dropdown, .has-dropdown:focus-within .dropdown, .has-dropdown.is-open .dropdown {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
.dropdown a {
  display: block; width: 100%; border-radius: var(--radius-input); border-bottom: none; text-align: left;
  font-size: var(--text-sm); padding: var(--space-xs) var(--space-sm) var(--space-xs) var(--space-md);
  border-left: 2px solid var(--color-rule); margin-left: var(--space-2xs);
}
.dropdown a:hover, .dropdown a:focus-visible { background: var(--color-paper); border-left-color: var(--color-accent); }

.mast-rule { border: 0; height: 4px; margin: var(--space-sm) 0 0; }
.mast-rule.double { border-top: var(--rule-hair) solid var(--color-rule); border-bottom: var(--rule-hair) solid var(--color-rule); }

.mast-actions { display: flex; align-items: center; gap: var(--space-2xs); }
.nav-toggle {
  display: none; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  width: 44px; height: 44px; border-radius: var(--radius-pill); flex-shrink: 0;
  transition: background var(--dur-short) var(--ease-out);
}
.nav-toggle:hover { background: var(--color-paper-2); }
.nav-toggle span { display: block; width: 20px; height: 2px; background: var(--color-ink); border-radius: 2px; transition: transform var(--dur-short) var(--ease-out), opacity var(--dur-short) var(--ease-out); }

.search-panel { border-top: var(--rule-hair) solid var(--color-rule); background: var(--color-paper-2); }
.search-panel form { display: flex; gap: var(--space-xs); padding: var(--space-md) var(--page-gutter); max-width: var(--wrap); margin-inline: auto; }
.search-panel input[type="search"] {
  flex: 1; padding: var(--space-sm) var(--space-md); border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-input); background: var(--color-paper); color: var(--color-ink); min-height: 44px;
}

@media (max-width: 26rem) {
  /* Decorative issue line — drop it on the narrowest phones so the header
     row never risks wrapping to two lines. */
  .mast-line { display: none; }
  .mast-top { justify-content: flex-end; }

  /* .cta-fill/.cta-chip are nowrap by design (a pill button that wraps looks
     broken) — but that means a long enough label has nowhere to go except
     past the edge of the screen on the narrowest phones. Letting it wrap
     here only, as a last resort, keeps the pill shape everywhere realistic
     while guaranteeing it can never push the page wider than the viewport. */
  .cta-fill, .cta-chip { white-space: normal; text-align: center; }
}

@media (max-width: 62rem) {
  /* Full-viewport layer, fixed for real now that .nav-mast no longer has a
     backdrop-filter forcing a different containing block. Always laid out
     as flex (fixed elements don't take up page space regardless of
     display), so opacity/transform/visibility can animate cleanly — no
     display:none jump. Visibility (not display) is what makes it
     un-clickable and unfocusable while closed; its transition is delayed
     on the way in and on the way out, so it only "exists" for interaction
     exactly while it's actually visible. Max usable z-index so nothing
     else on the page (cookie banner, ad slots) can ever paint above it. */
  .mast-nav {
    display: flex; flex-direction: column;
    position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 2147483646;
    background: var(--color-paper);
    padding: calc(var(--space-3xl) + var(--space-md)) var(--page-gutter) var(--space-lg);
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    opacity: 0; visibility: hidden; pointer-events: none;
    transform: scale(0.98);
    transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out),
                visibility 0s linear var(--dur-short);
  }
  .mast-nav.is-open {
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
    transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out),
                visibility 0s linear 0s;
  }
  @media (prefers-reduced-motion: reduce) { .mast-nav { transform: none; } }

  .mast-nav ul { flex-direction: column; align-items: stretch; }
  .mast-nav a { padding: var(--space-md) var(--space-2xs); font-size: 1.05rem; border-bottom: var(--rule-hair) solid var(--color-rule); }

  /* Accordion pattern — reused for every nav item that gets children later,
     not just Breed Guides. Closed by default, opens only on tap. The parent
     link stops navigating on mobile (it always has children here) and
     becomes a pure toggle instead; the hub page is still reachable from the
     home page and from the breadcrumb on its own sub-pages.
     .has-dropdown MUST switch to column: the base rule makes it a row flex
     container (for desktop, where .dropdown is absolutely-positioned and
     escapes the flow anyway) — on mobile .dropdown is back in normal flow,
     so without this override it renders beside the link instead of below it. */
  .has-dropdown { flex-direction: column; align-items: stretch; }
  .has-dropdown > a {
    display: flex; align-items: center; justify-content: space-between;
    border-bottom: var(--rule-hair) solid var(--color-rule);
  }
  .has-dropdown.is-open > a { border-bottom-color: transparent; }
  .dropdown {
    position: static; transform: none; opacity: 0; visibility: visible; border: 0;
    margin: 0; overflow: hidden; max-height: 0;
    background: var(--color-paper-2); border-radius: 0 0 var(--radius-input) var(--radius-input);
    transition: max-height var(--dur-short) var(--ease-in-out), opacity var(--dur-short) var(--ease-out);
  }
  .has-dropdown.is-open .dropdown { max-height: 7rem; opacity: 1; border-bottom: var(--rule-hair) solid var(--color-rule); }
  /* Indented + a hairline left rail, so a sub-link visibly reads as
     "belongs to the item above", not a sibling of the same rank. */
  .dropdown a {
    padding-left: calc(var(--space-lg) + var(--space-xs)); border-left: 2px solid var(--color-rule);
    margin-left: var(--space-md); border-bottom: var(--rule-hair) solid var(--color-rule);
  }
  .dropdown a:last-child { border-bottom: 0; }

  .nav-toggle { display: flex; position: relative; z-index: 2147483647; }
  .nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(7px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] span:last-child { transform: translateY(-7px) rotate(-45deg); }
}
@media (min-width: 62.01rem) { .nav-toggle { display: none; } }

/* ==========================================================================
 * Bento Grid — home
 * ========================================================================== */
.hero-fixed { padding: var(--space-2xl) 0 var(--space-xl); text-align: center; }
.hero-fixed .kicker { font-family: var(--font-body); font-weight: 700; font-size: var(--text-sm); color: var(--color-accent-text); }
.hero-fixed h1 { font-size: var(--text-display); max-width: 20ch; margin-inline: auto; margin-top: var(--space-sm); }
@media (max-width: 26rem) { .hero-fixed h1 { font-size: clamp(2.1rem, 9vw, 2.6rem); max-width: 16ch; } }
.hero-fixed .lede { font-size: var(--text-md); color: var(--color-muted); max-width: 52ch; margin: var(--space-md) auto 0; }
.hero-actions { display: flex; gap: var(--space-sm); flex-wrap: wrap; align-items: center; }
.hero-fixed .hero-actions { justify-content: center; margin-top: var(--space-lg); }

/* flexbox, not grid: with grid, an incomplete last row (say 2 cards left
   over out of 3 columns) just sits flush left with dead space beside it —
   grid has no built-in way to center leftover items in a partial row.
   flex-wrap + justify-content:center centers whatever ends up on each
   line, full or partial, for free. flex-basis stands in for the old
   grid-column spans (roughly 1 column vs. roughly 2). */
.bento { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-md); padding-block: var(--space-xl); }
.cell {
  background: var(--color-paper-2); border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-card);
  padding: var(--space-lg); display: flex; flex-direction: column; gap: var(--space-sm); min-width: 0;
  flex: 1 1 18rem;
  opacity: 0; transform: translateY(8px); animation: reveal var(--dur-long) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 55ms);
}
@keyframes reveal { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cell { animation-duration: 150ms; } }

/* Width-only variety (no row-height spans) — mixed widths still give the
   bento its "not uniform cards" rhythm, without the row-height bookkeeping
   that broke across breakpoints. */
.cell.span-2x1 { flex: 2 1 38rem; }
/* Mobile: always one card per row, no exceptions — every card becomes a
   full-width line on its own, whatever its flex-basis on wider screens. */
@media (max-width: 40rem) {
  .cell, .cell.span-2x1, .cell.tone-ink { flex-basis: 100%; max-width: 100%; }
}

.cell .cell-icon { width: 30px; height: 30px; color: var(--color-accent-text); flex-shrink: 0; }
.cell h3 { margin: 0; font-size: 1.1rem; overflow-wrap: break-word; }
.cell.span-2x2 h3 { font-size: clamp(1.4rem, 1.1rem + 1vw, 1.9rem); }
.cell p { color: var(--color-muted); font-size: var(--text-sm); margin: 0; overflow-wrap: break-word; }
.cell .cta-link { margin-top: auto; align-self: flex-start; }
.cell { transition: transform var(--dur-short) var(--ease-out), border-color var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out); }
.cell:hover { border-color: var(--color-accent-text); transform: translateY(-3px); box-shadow: 0 10px 24px -16px oklch(20% 0.02 60 / 0.4); }
.cell.tone-ink:hover { box-shadow: 0 10px 24px -14px oklch(10% 0.02 60 / 0.6); }
.cell h3 a { transition: color var(--dur-short) var(--ease-out); }
.cell.tone-ink {
  background: var(--color-ink); color: var(--color-paper); border-color: var(--color-ink);
  align-items: center; text-align: center;
  /* Its own full line (nothing fits beside a 100%-basis item), then capped
     and centered on that line by the container's justify-content:center. */
  flex-basis: 100%; max-width: 46rem;
}
.cell.tone-ink h3, .cell.tone-ink p { color: inherit; }
.cell.tone-ink p { opacity: .82; max-width: 42ch; }
.cell.tone-ink .cta-link { color: var(--color-paper); }
.cell.tone-ink .byline-row { justify-content: center; }

.byline-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-sm); font-family: var(--font-outlier); font-size: 0.72rem; color: var(--color-muted); max-width: 100%; overflow-wrap: break-word; }
.byline-row .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--color-rule); }

/* ==========================================================================
 * Index-First — category / listing pages
 * ========================================================================== */
.breadcrumb { padding: var(--space-md) 0 0; }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--space-2xs); font-size: var(--text-xs); color: var(--color-muted); font-weight: 700; }
.breadcrumb a:hover { color: var(--color-accent-text); }
.breadcrumb li:not(:last-child)::after { content: '/'; margin-left: var(--space-2xs); color: var(--color-rule); }
.breadcrumb li[aria-current] { color: var(--color-ink); }

.index-head { padding: var(--space-lg) 0 var(--space-xl); border-bottom: var(--rule-hair) solid var(--color-rule); margin-bottom: var(--space-xl); }
.index-head h1 { font-size: var(--text-display-s); margin-bottom: var(--space-sm); }
.index-head .intro { max-width: 68ch; color: var(--color-muted); font-size: var(--text-md); }

.index-list { display: flex; flex-direction: column; }
.index-row {
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-md) var(--space-lg); align-items: baseline;
  padding-block: var(--space-lg); padding-inline: var(--space-sm); margin-inline: calc(var(--space-sm) * -1);
  border-bottom: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-input);
  transition: background var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out);
}
.index-row:hover { background: var(--color-paper-2); transform: translateX(3px); }
.index-row:first-child { padding-top: 0; }
.index-row h3 { margin: 0 0 var(--space-2xs); font-size: 1.2rem; }
.index-row h3 a { border-bottom: 1px solid transparent; transition: border-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out); }
.index-row h3 a:hover, .index-row h3 a:focus-visible { border-bottom-color: currentColor; color: var(--color-accent-text); }
.index-row p { color: var(--color-muted); font-size: var(--text-sm); margin: 0; max-width: 62ch; }
.index-row .index-meta { text-align: right; white-space: nowrap; }
@media (max-width: 40rem) {
  .index-row { grid-template-columns: 1fr; }
  .index-row .index-meta { text-align: left; }
}

/* ==========================================================================
 * Callouts — hairline discipline, EXCEPT the emergency banner which is
 * deliberately high-contrast (safety content, not decoration; see design.md).
 * ========================================================================== */
.callout { border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-card); padding: var(--space-md) var(--space-lg); margin: var(--space-lg) 0; display: flex; gap: var(--space-sm); align-items: flex-start; background: var(--color-paper-2); }
.callout svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: 2px; }
.callout p { margin: 0; font-size: var(--text-sm); }
.callout strong { display: block; margin-bottom: 3px; font-family: var(--font-body); }
.callout--tip svg { color: var(--color-accent-text); }
.callout--vet { border-color: var(--color-accent-2); }
.callout--vet svg, .callout--vet strong { color: var(--color-accent-2); }
.callout--affiliate svg { color: var(--color-muted); }
.callout--emergency { background: var(--color-danger); border-color: var(--color-danger); color: var(--color-paper); }
.callout--emergency svg, .callout--emergency strong { color: var(--color-paper); }
.callout--emergency p { color: var(--color-paper); opacity: .95; }

.compare-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: var(--space-lg) 0; border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-card); }
.compare-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); min-width: 560px; }
.compare-table th, .compare-table td { text-align: left; padding: var(--space-sm) var(--space-md); border-bottom: var(--rule-hair) solid var(--color-rule); }
.compare-table thead th { font-family: var(--font-body); text-transform: uppercase; font-size: 0.7rem; letter-spacing: .04em; color: var(--color-muted); }
.compare-table tbody tr:last-child td { border-bottom: 0; }
.compare-table td.num, .compare-table th.num { font-family: var(--font-outlier); font-variant-numeric: tabular-nums; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-sm); margin: var(--space-lg) 0; }
.stat-card { border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-card); padding: var(--space-md); }
.stat-card .num { font-family: var(--font-outlier); font-size: 1.4rem; font-weight: 600; color: var(--color-accent-2); }
.stat-card .label { font-size: var(--text-xs); color: var(--color-muted); font-weight: 700; }

/* ==========================================================================
 * Ad slots
 * ========================================================================== */
.ad-slot {
  border: 1.5px dashed var(--color-rule); border-radius: var(--radius-card); background: var(--color-paper-2);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3xs);
  padding: var(--space-lg); min-height: 100px; margin: var(--space-xl) auto; text-align: center;
}
.ad-slot .ad-label { font-family: var(--font-outlier); font-size: 0.68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--color-muted); }
.ad-slot .ad-note { font-size: var(--text-xs); color: var(--color-muted); max-width: 46ch; }
.ad-slot--leaderboard { max-width: 728px; min-height: 90px; }
.ad-slot--infeed { max-width: 100%; }

.mobile-anchor-ad {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky);
  background: var(--color-paper-2); border-top: var(--rule-hair) solid var(--color-rule);
  padding: var(--space-xs) var(--space-md); display: none; align-items: center; justify-content: space-between; gap: var(--space-sm);
}
.mobile-anchor-ad.is-visible { display: flex; }
.mobile-anchor-ad .ad-slot { margin: 0; flex: 1; min-height: 50px; padding: var(--space-xs); }
.mobile-anchor-ad .close-ad { flex-shrink: 0; width: 32px; height: 32px; border-radius: 50%; background: var(--color-rule); display: flex; align-items: center; justify-content: center; }
@media (min-width: 47.5rem) { .mobile-anchor-ad { display: none !important; } }

/* ==========================================================================
 * Long Document — article pages
 * ========================================================================== */
.article-header { max-width: 65ch; margin: var(--space-xl) auto var(--space-lg); padding-inline: var(--page-gutter); }
.article-header h1 { font-size: var(--text-display-s); margin-bottom: var(--space-md); }

.prose { max-width: 65ch; margin-inline: auto; padding: 0 var(--page-gutter) var(--space-3xl); }
.prose .lede { font-size: var(--text-md); color: var(--color-muted); line-height: 1.6; }
.prose p { font-size: var(--text-base); line-height: 1.65; }
.prose ul, .prose ol { padding-left: 1.3em; margin-bottom: var(--space-md); }
.prose li { margin-bottom: var(--space-2xs); }
.prose strong { color: var(--color-ink); }
.prose h2 { font-size: 1.5rem; }
.prose h2.inline { font-family: var(--font-body); font-weight: 700; font-size: var(--text-base); font-variant-caps: all-small-caps; letter-spacing: 0.02em; margin-top: var(--space-xl); }
.prose blockquote { border-left: 2px solid var(--color-accent); padding-left: var(--space-md); color: var(--color-muted); font-style: italic; margin: var(--space-xl) 0; font-size: 1.05rem; }
.prose img, .prose figure { margin: var(--space-lg) 0; border-radius: var(--radius-card); }
.prose figcaption { font-size: var(--text-xs); color: var(--color-muted); margin-top: var(--space-2xs); }

.sources { margin-top: var(--space-2xl); padding-top: var(--space-lg); border-top: var(--rule-hair) solid var(--color-rule); font-size: var(--text-sm); color: var(--color-muted); }
.sources h2.inline { margin-top: 0; }
.sources ol { padding-left: 1.3em; }
.sources li { margin-bottom: var(--space-xs); }
.sources .todo { font-style: italic; }

.author-box { display: flex; gap: var(--space-md); border-top: var(--rule-hair) solid var(--color-rule); padding-top: var(--space-lg); margin-top: var(--space-2xl); }
@media (max-width: 22rem) { .author-box { flex-direction: column; } }
.author-box .avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--color-warning-bg); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.author-box .avatar svg { width: 26px; height: 26px; color: var(--color-accent-text); }
.author-box h3 { margin: 0 0 2px; font-size: var(--text-base); }
.author-box .role { font-size: var(--text-xs); color: var(--color-muted); font-weight: 700; margin-bottom: var(--space-xs); }
.author-box p { font-size: var(--text-sm); color: var(--color-muted); margin: 0; }

.related { max-width: 65ch; margin: var(--space-2xl) auto 0; padding-inline: var(--page-gutter); }
.related h2.inline { margin-top: 0; }
.related-list a { display: block; padding: var(--space-sm) 0; border-bottom: var(--rule-hair) solid var(--color-rule); font-weight: 700; }
.related-list a:hover { color: var(--color-accent-text); }

.faq-item { border-bottom: var(--rule-hair) solid var(--color-rule); }
.faq-item summary { padding: var(--space-md) 0; font-weight: 700; font-family: var(--font-body); cursor: pointer; list-style: none; display: flex; justify-content: space-between; gap: var(--space-sm); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: '+'; font-size: 1.2rem; color: var(--color-accent-text); flex-shrink: 0; }
.faq-item[open] summary::after { content: '−'; }
.faq-item .faq-a { padding: 0 0 var(--space-md); color: var(--color-muted); font-size: var(--text-sm); }

.reading-progress { position: fixed; top: 0; left: 0; height: 3px; background: var(--color-accent); z-index: var(--z-toast); width: 0%; }

/* ==========================================================================
 * Letter — About
 * ========================================================================== */
.letter { max-width: 62ch; margin-inline: auto; padding: var(--space-2xl) var(--page-gutter) var(--space-3xl); }
.letter .salutation { font-family: var(--font-display); font-size: 1.6rem; margin-bottom: var(--space-lg); }
.letter p { font-size: 1.05rem; line-height: 1.7; }
.letter .signoff { margin-top: var(--space-2xl); font-family: var(--font-display); font-size: 1.2rem; }
.letter .signoff .role { display: block; font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-muted); margin-top: var(--space-2xs); }

.pending-box { border: var(--rule-hair) dashed var(--color-accent); border-radius: var(--radius-card); padding: var(--space-md) var(--space-lg); margin: var(--space-lg) 0 var(--space-xl); display: flex; gap: var(--space-sm); background: var(--color-warning-bg); }
.pending-box svg { width: 20px; height: 20px; color: var(--color-accent-text); flex-shrink: 0; }
.pending-box strong { display: block; margin-bottom: var(--space-2xs); }
.pending-box p { margin: 0; font-size: var(--text-sm); color: var(--color-muted); }

/* ==========================================================================
 * Generic prose pages (Legal)
 * ========================================================================== */
.page-head { padding: var(--space-2xl) var(--page-gutter) 0; max-width: 65ch; margin-inline: auto; }
.page-head h1 { font-size: var(--text-display-s); margin-bottom: var(--space-2xs); }
.page-head .lede { color: var(--color-muted); font-size: var(--text-md); }
.legal-skeleton h2 { font-size: 1.2rem; }

.hp-field { position: absolute; left: -9999px; }

/* ==========================================================================
 * Footer — Ft7 Newsletter-first
 * ========================================================================== */
.foot-news { border-top: var(--rule-hair) solid var(--color-rule); margin-top: var(--space-3xl); }
.foot-news__inner { max-width: var(--wrap); margin-inline: auto; padding: var(--space-2xl) var(--page-gutter) var(--space-lg); }
.foot-news__form { max-width: 56ch; }
.foot-news__form label { display: block; font-family: var(--font-display); font-size: 1.3rem; margin-bottom: var(--space-sm); }
.foot-news__row { display: flex; gap: var(--space-2xs); flex-wrap: wrap; }
.foot-news__row input {
  flex: 1; min-width: 200px; min-height: 44px; padding-inline: var(--space-md);
  border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-input); background: var(--color-paper-2);
}
.foot-news__note { font-size: var(--text-xs); color: var(--color-muted); margin-top: var(--space-xs); }

.foot-links { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); border-top: var(--rule-hair) solid var(--color-rule); margin-top: var(--space-2xl); padding-top: var(--space-lg); }
.foot-h { display: block; font-family: var(--font-body); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--color-muted); margin-bottom: var(--space-sm); }
.foot-links ul { display: flex; flex-direction: column; gap: var(--space-xs); }
.foot-links a { font-size: var(--text-sm); color: var(--color-muted); }
.foot-links a:hover { color: var(--color-accent-text); }
@media (max-width: 40rem) { .foot-links { grid-template-columns: 1fr 1fr; } }
@media (max-width: 24rem) { .foot-links { grid-template-columns: 1fr; gap: var(--space-lg); } }

.foot-news__meta { font-family: var(--font-outlier); font-size: 0.72rem; color: var(--color-muted); border-top: var(--rule-hair) solid var(--color-rule); margin-top: var(--space-lg); padding-top: var(--space-md); }

/* ---- Cookie banner — UI shell, not a certified CMP (see README) ---- */
.cookie-banner {
  position: fixed; left: var(--space-md); right: var(--space-md); bottom: var(--space-md); z-index: var(--z-modal);
  max-width: 600px; margin-inline: auto; background: var(--color-paper-2); border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card); padding: var(--space-md) var(--space-lg); display: none;
}
.cookie-banner.is-visible { display: block; }
.cookie-banner p { font-size: var(--text-sm); color: var(--color-muted); margin-bottom: var(--space-sm); }
.cookie-banner .actions { display: flex; gap: var(--space-xs); flex-wrap: wrap; }

/* ---- 404 ---- */
.error-page { min-height: 55vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: var(--space-2xl) var(--page-gutter); gap: var(--space-2xs); }
.error-page .code { font-family: var(--font-display); font-size: 3.5rem; color: var(--color-accent); font-weight: 700; }

/* ==========================================================================
 * Scroll reveal — progressive enhancement only.
 * JS adds .reveal-pending right before observing an element, so content is
 * fully visible by default if JS fails or hasn't run yet (never hidden by
 * CSS alone). One-shot, IntersectionObserver-driven, capped stagger. Applies
 * to index rows, callouts, stat cards and inline section heads — quiet
 * per-viewport entrances, not a per-scroll fade-everything loop.
 * ========================================================================== */
.reveal-pending { opacity: 0; transform: translateY(10px); }
.index-row, .callout, .stat-card, .author-box, .prose h2.inline, .sources, .related, #faq {
  transition: opacity var(--dur-long) var(--ease-out), transform var(--dur-long) var(--ease-out);
}
.is-revealed { opacity: 1 !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
  .reveal-pending { opacity: 1; transform: none; }
}

/* ---- Callouts, table rows, stat cards, dropdown — small hover polish ---- */
.callout { transition: border-color var(--dur-short) var(--ease-out); }
.compare-table tbody tr { transition: background var(--dur-micro) var(--ease-out); }
.stat-card { transition: border-color var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out); }
.stat-card:hover { border-color: var(--color-accent-2); transform: translateY(-2px); }
.dropdown a { transition: background var(--dur-micro) var(--ease-out), color var(--dur-micro) var(--ease-out); }
.dropdown a:hover, .dropdown a:focus-visible { background: var(--color-paper); color: var(--color-accent-text); }
.related-list a { transition: color var(--dur-short) var(--ease-out), padding-left var(--dur-short) var(--ease-out); }
.related-list a:hover { color: var(--color-accent-text); padding-left: var(--space-xs); }

/* ---- FAQ open/close — fade + slight rise on expand (native <details>
 * can't transition display:none→block, so this rides on a JS-toggled class
 * around the [open] state instead of animating height). ---- */
.faq-item .faq-a { transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out); }
.faq-item .faq-a.faq-a-enter { opacity: 0; transform: translateY(-4px); }
.faq-item summary { transition: color var(--dur-short) var(--ease-out); }
.faq-item summary:hover { color: var(--color-accent-text); }

.mt-0 { margin-top: 0; }

/* ==========================================================================
 * Print — articles are the one thing on this site people genuinely print
 * or save as PDF (a recipe-adjacent cost breakdown, a vet-visit checklist).
 * ========================================================================== */
@media print {
  .nav-mast, .foot-news, .ad-slot, .mobile-anchor-ad, .cookie-banner,
  .reading-progress, .search-panel, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
  .prose, .article-header { max-width: 100%; }
  a[href^="http"]::after, a.text-link[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
  .callout, .compare-table-wrap { break-inside: avoid; border-color: #999; }
}

/* ==========================================================================
 * Extra-wide viewports — the wrap/max-width tokens already centre and cap
 * everything, this just keeps the bento hero from feeling thin on ultrawide
 * monitors by giving the lead tile a touch more breathing room.
 * ========================================================================== */
@media (min-width: 90rem) {
  .bento { gap: var(--space-lg); }
}
