/* Marion County Animal Control — design system
 *
 * Inherits the mcema.us civic-document architecture: dark ink surfaces,
 * monospace eyebrow labels, a Fraunces display face, hairline rules, and
 * zero border-radius on structural chrome. Retuned for a shelter: the
 * county seal-gold stays as the institutional voice, and a warmer clay
 * accent carries the adoption/donation side so "adopt this dog" does not
 * read like a hazmat advisory.
 *
 * BRAND TOKENS ARE SAMPLED FROM THE AGENCY'S OWN ICON SET — the Adoptables,
 * Rabies, and Support-a-Shelter-Animal images on marioncountyil.gov. They
 * are the real colors, not a designer's guess, and each was checked against
 * --ink for WCAG AA before being adopted (see the notes on each token).
 *
 * Every brand color on the site resolves through the :root block below, so
 * retuning the whole estate is a few lines here, NOT a find-and-replace
 * across the pages. Keep it that way — never hardcode a brand hex below
 * this block. If the county supplies an official badge with different
 * values, change them here and the entire site follows.
 *
 * Dark-only, deliberately. mcema.us learned this the hard way: a half-
 * implemented light palette flipped the text tokens while the surfaces
 * stayed dark, making the page unreadable. Do not add a light block here
 * unless every surface below gets a light counterpart in the same commit.
 *
 * ---------------------------------------------------------------------
 * READABILITY PASS
 * ---------------------------------------------------------------------
 * The first cut of this file was legible in the abstract and tiring in
 * practice. Three things were wrong, and all three are the same mistake
 * made in different places — treating a public-information site like a
 * design portfolio.
 *
 *   1. Body text ran 15.5px in --steel-1 (#b5bec9) on #0b0d10. That is
 *      technically AA, but it is a GREY paragraph. Every sentence on this
 *      site is something a resident needs: an address, a holding period,
 *      a 24-hour reporting duty. Body copy is now 17px in a near-cream
 *      that clears AAA, and the muted tone was demoted to captions only.
 *
 *   2. Section headings were 12px uppercase mono. At that size a heading
 *      stops out-ranking the paragraph under it, so the page reads as one
 *      continuous grey slab with no way in. Headings now carry the display
 *      serif and real size, with the mono treatment kept as a KICKER above
 *      them — the label voice survives without doing a heading's job.
 *
 *   3. The ink ladder was near-neutral blue-black, so cards, tables, and
 *      the page all sat at visually the same depth and the whole thing
 *      looked flat and cheap. The surfaces are now warmed a few degrees
 *      toward the brand amber and separated by wider steps, which is why
 *      a card now reads as an object instead of a rectangle.
 *
 * Layout, class names, and DOM structure are UNCHANGED. This is a
 * material and typographic pass only — no page markup was touched.
 */

/* ============================================================
   TOKENS
   ============================================================ */
:root {
  /* Surfaces — ink ladder.
     Warmed off pure blue-black (hue pulled toward the brand amber) and
     given wider steps between rungs. Flat neutral greys are what made
     the first pass look cheap: with only 5 points of luminance between
     the page and a card, the card never reads as a physical object. */
  --ink:        #0c0d0f;
  --ink-1:      #14161a;
  --ink-2:      #1c1f25;
  --ink-3:      #262a31;
  --rule:       #343a44;
  --rule-soft:  #23272e;

  /* Text.
     --cream is body copy and must stay near-white: 16.9:1 on --ink.
     --cream-2 is the warm variant for display type.
     --steel-1 was doing paragraph duty and was too dim for it; it is now
     a SECONDARY tone (12.2:1) for card body and table cells.
     --steel is captions and timestamps ONLY — never a full sentence. */
  --cream:      #f4efe6;
  --cream-2:    #ece0c9;
  --steel-1:    #cdd5de;
  --steel:      #96a1af;

  /* Institutional voice — sampled from the agency's own Adoptables icon.
     #cc8430 is their literal brand amber, not an approximation. 6.40:1 on
     --ink, so it clears WCAG AA for body text, not just large text.
     --gold-bright (9.94:1) carries every link and hover state, because
     the base gold on a tinted card surface is closer to the floor. */
  --gold:       #cc8430;
  --gold-bright:#f0ac52;
  --gold-pale:  #f7d5a5;   /* headings and kickers that must not shout */

  /* Action voice. MCAC's palette is effectively single-hue warm amber:
     their Adoptables (#cc8430) and Support-a-Shelter (#cc8448) icons are
     nearly the same color, so mapping them to two "different" brand
     colors would collapse into one and destroy the institutional/action
     distinction the layout depends on.

     Instead the second voice is separated by DEPTH, not hue — #c06c00 is
     the deeper, fully-saturated orange from their own Rabies icon. Still
     genuinely their brand, but reads unmistakably as "this is a button".
     4.99:1 against --ink, and 4.99:1 for --ink text sitting on the fill. */
  --clay:       #c06c00;
  --clay-bright:#e08a1a;
  --clay-deep:  #60483c;   /* their brown, from the Adoptables illustration */

  /* Status */
  --ok:         #7ade97;
  --info:       #7ab8e4;
  --warn:       #f6a800;
  --urgent:     #e0605a;   /* lifted from #b73a32 — the old red failed AA */

  /* Tints */
  --tint-gold:  rgba(204, 132, 48, 0.085);
  --tint-clay:  rgba(192, 108, 0, 0.095);
  --tint-ok:    rgba(122, 222, 151, 0.07);
  --tint-urgent:rgba(224, 96, 90, 0.085);

  /* Type */
  --font-display: 'Fraunces', 'Source Serif Pro', Georgia, serif;
  --font-sans:    'IBM Plex Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  --font-stamp:   'Special Elite', 'Courier New', monospace;

  /* Layout */
  --pad: clamp(20px, 4vw, 56px);
  --nav-h: 68px;
  --measure: 64ch;   /* tightened from 68ch — shorter lines are easier to track */

  /* Motion.
     A spring curve, not a CSS default. Heavy at the start, long settle,
     so anything a person can push on behaves like it has mass. */
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit:   cubic-bezier(0.4, 0, 0.2, 1);

  /* Depth. --lip is the hairline catching light on a top edge, --trough
     the shadow a recessed panel casts on itself. Near-invisible alone;
     together they are what makes a flat panel read as machined. */
  --lip:    inset 0 1px 0 rgba(244, 239, 230, 0.06);
  --trough: inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  --lift-1: 0 1px 2px rgba(0,0,0,0.32), 0 10px 26px -14px rgba(0,0,0,0.6);
  --lift-2: 0 2px 5px rgba(0,0,0,0.36), 0 26px 54px -22px rgba(0,0,0,0.78);

  color-scheme: dark;
}

/* The toggle is not wired; if a stray data-theme lands, hold the dark palette. */
[data-theme="light"] { color-scheme: dark; }

/* ============================================================
   RESET + BASE
   ============================================================ */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
body {
  font-family: var(--font-sans);
  font-feature-settings: "kern", "liga", "calt";
  /* 17px, not 15.5px. This site's whole job is being read — often on a
     phone, often by someone stressed about a missing animal. */
  font-size: 17px;
  line-height: 1.72;
  background: var(--ink);
  color: var(--cream);
  overflow-x: hidden;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
::selection { background: var(--gold); color: var(--ink); }

/* Film grain. Fixed and pointer-events-none, on its own layer, NEVER
   attached to a scrolling container — a noise texture that scrolls
   repaints the entire composite layer every frame. Inlined as a data:
   URI, which the img-src 'self' data: policy in _headers permits. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 9999;
  pointer-events: none;
  opacity: 0.03;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
.skip-link {
  position: absolute; left: 8px; top: 8px; z-index: 100000;
  padding: 10px 16px;
  background: var(--gold); color: var(--ink);
  font-family: var(--font-mono); font-size: 13px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  transform: translateY(-200%); transition: transform 0.18s ease;
}
.skip-link:focus, .skip-link:focus-visible {
  transform: translateY(0);
  outline: 3px solid var(--gold-bright); outline-offset: 2px;
}
:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 3px; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ============================================================
   CLASSIFICATION BAR — the civic "this is an official page" signal
   ============================================================ */
.classif {
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border-bottom: 1px solid rgba(204, 132, 48, 0.45);
  font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--gold-pale);
  text-align: center;
  padding: 8px 12px;
}
.classif b { color: var(--cream); padding: 0 10px; letter-spacing: 0.35em; font-weight: 600; }

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: sticky; top: 0; z-index: 900;
  background: rgba(12,13,15,0.86);
  /* backdrop-filter stays confined to this sticky bar. Applied to any
     scrolling region it forces a continuous GPU repaint of everything
     behind it, which is the most common cause of jank on a blurred site. */
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--rule);
  box-shadow: 0 1px 0 rgba(244,239,230,0.03), 0 12px 34px -20px rgba(0,0,0,0.95);
}
.nav-inner {
  max-width: 1240px; margin: 0 auto;
  padding: 0 var(--pad);
  min-height: var(--nav-h);
  /* 18px, not 28px. With nine items plus the badge, the wider gap pushed the
     DONATE button onto a second row at 1440px — the nav read as broken rather
     than as full. The nav is the densest row on the site; it gets the tightest
     spacing, and everything else keeps the generous scale. */
  display: flex; align-items: center; gap: 18px;
}
.brand { display: flex; align-items: center; gap: 13px; text-decoration: none; margin-right: auto; }
/* The badge SVG paints with currentColor, so the brand color is set HERE and
   never as an inline style attribute. `style-src 'self'` in _headers blocks
   inline style ATTRIBUTES, not just <style> blocks — an inline color here
   would be silently dropped in production and the mark would render in body
   cream with no console error anyone would notice. */
/* Holds the county's official badge (a raster PNG with transparency), not the
   old currentColor SVG — so no color token applies to it any more. Do not add
   a filter to tint it: it is an official seal and recoloring it misrepresents
   the agency's mark. */
.brand-mark {
  /* 46px, not the 40px the old line-art mark used. A detailed seal needs more
     room than a two-path glyph before it stops reading as a smudge. */
  width: 46px; height: 46px; flex: none;
  display: block;
  transition: transform 0.6s var(--ease-spring);
}
.brand-mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
.brand:hover .brand-mark { transform: scale(1.05); }
.brand-text { display: flex; flex-direction: column; line-height: 1.18; }
.brand-name {
  font-family: var(--font-display); font-weight: 800;
  font-size: 16px; letter-spacing: -0.012em; color: var(--cream);
}
.brand-sub {
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--gold);
}
.nav-links { display: flex; align-items: center; gap: 3px; flex-wrap: wrap; }
.nav-links a {
  position: relative;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--steel-1); text-decoration: none;
  padding: 9px 9px; border: 1px solid transparent;
  transition: color 0.28s var(--ease-spring), border-color 0.28s var(--ease-spring);
}
.nav-links a:hover { color: var(--gold-bright); border-color: var(--rule); }
.nav-links a[aria-current="page"] { color: var(--gold); border-color: var(--gold); }
.nav-links a.cta {
  color: var(--ink); background: var(--clay);
  border-color: var(--clay); font-weight: 700;
  box-shadow: var(--lip), var(--lift-1);
}
.nav-links a.cta:hover { background: var(--clay-bright); border-color: var(--clay-bright); color: var(--ink); }

.nav-toggle {
  display: none;
  background: var(--ink-1); border: 1px solid var(--rule); color: var(--cream);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; padding: 9px 14px; cursor: pointer;
  box-shadow: var(--lip);
  transition: border-color 0.28s var(--ease-exit), color 0.28s var(--ease-exit);
}
.nav-toggle:hover { border-color: var(--gold); color: var(--gold-bright); }
@media (max-width: 900px) {
  .nav-toggle { display: block; }
  .nav-links {
    display: none; width: 100%;
    flex-direction: column; align-items: stretch;
    padding: 10px 0 18px; gap: 0;
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 14px 4px; border: 0; border-bottom: 1px solid var(--rule-soft); font-size: 12px; }
  .nav-links a.cta { margin-top: 12px; text-align: center; border: 1px solid var(--clay); justify-content: center; }
  .nav-inner { flex-wrap: wrap; padding-top: 12px; padding-bottom: 0; }

  /* Menu items cascade in rather than arriving as a block. Delays are
     declared per position; a seventh link inherits the last delay, which
     is the correct degradation rather than an unbounded stagger. */
  .nav-links.open a { animation: mac-cascade 0.5s var(--ease-spring) both; }
  .nav-links.open a:nth-child(1) { animation-delay: 0.02s; }
  .nav-links.open a:nth-child(2) { animation-delay: 0.05s; }
  .nav-links.open a:nth-child(3) { animation-delay: 0.08s; }
  .nav-links.open a:nth-child(4) { animation-delay: 0.11s; }
  .nav-links.open a:nth-child(5) { animation-delay: 0.14s; }
  .nav-links.open a:nth-child(6) { animation-delay: 0.17s; }
  .nav-links.open a:nth-child(n+7) { animation-delay: 0.20s; }
}
@keyframes mac-cascade {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   PAGE SHELL
   ============================================================ */
/* Whitespace at roughly 1.5x the first pass. Cramped spacing is the other
   half of why the original read as a template — a document earns its
   seriousness by letting sections stand apart. */
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 var(--pad) clamp(96px, 10vw, 150px); }
.narrow { max-width: 860px; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  padding: clamp(64px, 8.5vw, 132px) 0 clamp(32px, 4vw, 56px);
  overflow: hidden;
}
/* A soft amber bloom behind the hero. This is the one place the page is
   allowed atmosphere; it lifts the top of the document off flat black
   without touching contrast anywhere text actually sits. */
.hero::before {
  content: "";
  position: absolute; top: -40%; left: -10%;
  width: 70%; height: 150%;
  background: radial-gradient(closest-side, rgba(204,132,48,0.10), transparent 70%);
  pointer-events: none;
}
/* The watermark is now the real badge. It is silver and black rather than the
   old amber line art, which reads much darker against the ink surface — at the
   previous 0.05 it disappeared completely. Raised to 0.09, which is visible as
   texture without ever competing with the headline sitting on top of it. */
.hero-watermark {
  position: absolute; top: 50%; right: -4%;
  transform: translateY(-50%);
  width: min(460px, 46vw);
  opacity: 0.09;
  pointer-events: none; user-select: none;
}
.hero-watermark img { width: 100%; height: auto; display: block; }

/* Spacing utilities, so pages never need an inline style attribute. */
.mt-1 { margin-top: 26px; }
.mt-2 { margin-top: 32px; }
.text-gold { color: var(--gold); }
.text-clay { color: var(--clay-bright); }
.hero-inner { position: relative; z-index: 1; max-width: 880px; }

.eyebrow {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 18px;
  display: flex; align-items: center; gap: 13px;
}
.eyebrow::before {
  content: ""; display: inline-block;
  width: 34px; height: 1px; background: var(--gold); flex: none;
  transform-origin: left center;
  transition: transform 0.7s var(--ease-spring);
}
.eyebrow.clay { color: var(--clay-bright); }
.eyebrow.clay::before { background: var(--clay-bright); }

h1, .h1 {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(38px, 6vw, 68px);
  line-height: 1.03; letter-spacing: -0.025em;
  color: var(--cream); margin: 0 0 22px;
}
h1 em, .h1 em {
  font-family: var(--font-display); font-style: italic;
  font-weight: 500; color: var(--gold-bright);
}
.lede {
  /* The lede is the sentence that decides whether the rest gets read.
     Near-cream, not grey, and set a full step above body. */
  font-size: clamp(18px, 1.9vw, 21px);
  line-height: 1.62; color: var(--cream);
  max-width: var(--measure); margin: 0 0 30px;
  font-weight: 350;
}
.lede strong { color: var(--cream); font-weight: 600; }
.lede a { color: var(--gold-bright); border-bottom: 1px solid rgba(240,172,82,0.4); text-decoration: none; }
.lede a:hover { color: var(--gold-pale); border-bottom-color: currentColor; }

/* Meta strip — the hairline fact rail under a hero */
.meta-strip {
  display: flex; flex-wrap: wrap; gap: 10px 34px;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: 17px 0; margin: 36px 0 0;
  font-family: var(--font-mono); font-size: 12px;
  letter-spacing: 0.04em; color: var(--cream);
}
.meta-strip strong {
  color: var(--gold); padding-right: 8px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.16em; font-size: 10.5px;
}

/* ============================================================
   HEADINGS + SECTIONS
   ============================================================ */
section { padding: clamp(58px, 7vw, 104px) 0 0; }

/* h2 was 12px uppercase mono — the same visual weight as the paragraph
   beneath it, which is why the page had no scannable structure. The mono
   label voice is preserved as a KICKER rendered in ::before, and the
   heading itself is now real display type at a real size. */
h2 {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(24px, 3vw, 33px);
  line-height: 1.15; letter-spacing: -0.018em;
  color: var(--cream);
  display: block;
  margin: 0 0 26px; padding: 0 0 16px;
  border-bottom: 1px solid var(--rule);
}
/* The old marker was a single mono glyph sitting inline with a mono
   heading. Now that h2 is display serif, that glyph rendered as an
   orphaned square floating above the words -- it read as a rendering
   fault, not as a label. A short gold rule does the same job (announce
   a section) with no stray character. */
h2::before {
  content: "";
  display: block;
  width: 42px; height: 2px;
  background: var(--gold);
  margin: 0 0 16px;
}
h3 {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(21px, 2.5vw, 28px); line-height: 1.22;
  letter-spacing: -0.012em; color: var(--cream); margin: 0 0 12px;
}
h4 {
  font-family: var(--font-sans); font-weight: 600;
  font-size: 17px; color: var(--cream); margin: 0 0 8px;
  letter-spacing: -0.005em;
}
p { max-width: var(--measure); color: var(--cream); margin: 0 0 20px; }
p strong { color: #fff; font-weight: 600; }
a { color: var(--gold-bright); }
a:hover { color: var(--gold-pale); }
/* Body links get an underline, not just a color shift. Color alone as a
   link affordance fails WCAG 1.4.1 for anyone who cannot separate amber
   from cream, and this site is read by people over 65 every day. */
p a, li a, dd a, td a {
  text-decoration: underline;
  text-decoration-color: rgba(240,172,82,0.42);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
p a:hover, li a:hover, dd a:hover, td a:hover { text-decoration-color: currentColor; }
ul, ol { color: var(--cream); max-width: var(--measure); padding-left: 20px; }
li { margin: 0 0 10px; }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 15px 24px; text-decoration: none;
  border: 1px solid var(--rule); color: var(--cream);
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  box-shadow: var(--lip), var(--lift-1);
  /* Press is short, release is long. That asymmetry is what reads as
     physical rather than as a color swap. Transform and opacity only —
     nothing here triggers layout. */
  transition:
    transform 0.5s var(--ease-spring),
    box-shadow 0.5s var(--ease-spring),
    background 0.22s var(--ease-exit),
    border-color 0.22s var(--ease-exit),
    color 0.22s var(--ease-exit);
  cursor: pointer;
}
.btn:hover {
  border-color: var(--gold); color: var(--gold-bright);
  transform: translateY(-2px); box-shadow: var(--lip), var(--lift-2);
}
.btn:active { transform: translateY(0) scale(0.985); transition-duration: 0.09s; }
.btn-primary {
  background: linear-gradient(180deg, var(--clay-bright), var(--clay));
  border-color: var(--clay); color: var(--ink);
}
.btn-primary:hover { background: var(--clay-bright); border-color: var(--clay-bright); color: var(--ink); }
.btn-gold {
  background: linear-gradient(180deg, var(--gold-bright), var(--gold));
  border-color: var(--gold); color: var(--ink);
}
.btn-gold:hover { background: var(--gold-bright); border-color: var(--gold-bright); color: var(--ink); }
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; margin: 6px 0 0; }

/* A trailing arrow lives in its own enclosure flush with the button's
   right padding, never naked beside the label. Optional: add
   <span class="btn-ico" aria-hidden="true">&rsaquo;</span> as the last
   child. Decorative only — the label already carries the meaning. */
.btn-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 23px; height: 23px; flex: none;
  margin: -7px -11px -7px 3px;
  font-size: 13px; line-height: 1;
  background: rgba(244, 239, 230, 0.08);
  box-shadow: inset 0 0 0 1px rgba(244, 239, 230, 0.11);
  transition: transform 0.5s var(--ease-spring), background 0.22s var(--ease-exit);
}
.btn-primary .btn-ico, .btn-gold .btn-ico {
  background: rgba(12, 13, 15, 0.15);
  box-shadow: inset 0 0 0 1px rgba(12, 13, 15, 0.2);
}
.btn:hover .btn-ico { transform: translate(3px, -1px) scale(1.06); }

/* ============================================================
   CARDS + GRIDS
   ============================================================ */
.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

/* Every panel gets the same two-part treatment: a lit lip on the top edge
   and a trough at the bottom, so it sits IN the page instead of on it.
   With zero border-radius this is the flat-design equivalent of a
   machined tray — depth without borrowing the rounded-glass idiom, which
   would be wrong for a county agency publishing a fee schedule. */
.card {
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--rule);
  padding: 28px 26px;
  position: relative;
  box-shadow: var(--lip), var(--trough), var(--lift-1);
  transition:
    transform 0.55s var(--ease-spring),
    box-shadow 0.55s var(--ease-spring),
    border-color 0.3s var(--ease-exit);
}
.card::before, .stat::before, .animal::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg,
    transparent, rgba(244,239,230,0.12) 18%, rgba(244,239,230,0.12) 82%, transparent);
  pointer-events: none;
}
a.card { text-decoration: none; display: block; }
a.card:hover {
  border-color: var(--gold);
  transform: translateY(-5px);
  box-shadow: var(--lip), var(--trough), var(--lift-2);
}
a.card:active { transform: translateY(-1px); }
.card .card-label {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 12px;
}
.card p { font-size: 15.5px; color: var(--steel-1); margin-bottom: 0; }
.card p + p { margin-top: 14px; }
/* Card headings do NOT inherit the section h3 scale. At clamp(21px,28px)
   a two-word title like "Tags & registration" breaks mid-phrase inside a
   four-up grid column, which is what made that card row look unfinished. */
.card h3, .animal .animal-name { font-size: clamp(19px, 1.5vw, 22px); line-height: 1.25; }
.card h3, .card h4 { color: var(--cream); }
.card.clay { border-left: 2px solid var(--clay); }
.card.clay .card-label { color: var(--clay-bright); }
.card.urgent { border-left: 2px solid var(--urgent); background: linear-gradient(180deg, var(--tint-urgent), var(--ink-1)); }
.card.urgent .card-label { color: var(--urgent); }

/* Stat tiles */
.stat {
  position: relative;
  border: 1px solid var(--rule);
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  padding: 26px 24px;
  box-shadow: var(--lip), var(--trough), var(--lift-1);
}
.stat-num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(34px, 4.4vw, 48px); line-height: 1;
  color: var(--gold-bright); letter-spacing: -0.025em;
}
.stat-label {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--steel-1); margin-top: 11px;
}

/* ============================================================
   TABLES — fee schedules, vaccination clinics
   ============================================================ */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--rule);
  background: var(--ink-1);
  box-shadow: var(--lip), var(--trough), var(--lift-1);
}
table { width: 100%; border-collapse: collapse; min-width: 460px; }
caption {
  text-align: left; padding: 18px 22px 0;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--steel-1);
}
th {
  text-align: left; padding: 15px 22px;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); background: var(--ink-2);
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
td {
  padding: 15px 22px; font-size: 15.5px; color: var(--cream);
  border-bottom: 1px solid var(--rule-soft); vertical-align: top;
}
/* Zebra striping. On a fee schedule read on a phone, alternating rows are
   what stops the eye sliding onto the wrong amount. */
tbody tr:nth-child(even) td { background: rgba(244,239,230,0.018); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--ink-2); }
td.amount {
  font-family: var(--font-mono); font-size: 15px; font-weight: 600;
  color: var(--gold-pale); white-space: nowrap; text-align: right;
}
th.amount { text-align: right; }

/* ============================================================
   CALLOUTS
   ============================================================ */
.callout {
  border-left: 3px solid var(--gold);
  background: linear-gradient(90deg, var(--tint-gold), transparent 85%);
  padding: 22px 26px; margin: 30px 0;
  box-shadow: var(--lip);
}
.callout.clay { border-left-color: var(--clay-bright); background: linear-gradient(90deg, var(--tint-clay), transparent 85%); }
.callout.urgent { border-left-color: var(--urgent); background: linear-gradient(90deg, var(--tint-urgent), transparent 85%); }
.callout .callout-label {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 9px;
}
.callout.clay .callout-label { color: var(--clay-bright); }
.callout.urgent .callout-label { color: var(--urgent); }
.callout p { color: var(--cream); }
.callout p:last-child { margin-bottom: 0; }

/* ============================================================
   ANIMAL CARDS — the adoption grid
   ============================================================ */
.animal {
  position: relative;
  background: linear-gradient(180deg, var(--ink-2), var(--ink-1));
  border: 1px solid var(--rule);
  display: flex; flex-direction: column;
  box-shadow: var(--lip), var(--trough), var(--lift-1);
  transition:
    transform 0.55s var(--ease-spring),
    box-shadow 0.55s var(--ease-spring),
    border-color 0.3s var(--ease-exit);
}
.animal:hover {
  border-color: var(--clay-bright);
  transform: translateY(-5px);
  box-shadow: var(--lip), var(--trough), var(--lift-2);
}
.animal-photo {
  aspect-ratio: 4 / 3; background: var(--ink-3);
  display: flex; align-items: center; justify-content: center;
  color: var(--steel); font-family: var(--font-mono);
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  overflow: hidden;
}
.animal-photo img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.9s var(--ease-spring);
}
.animal:hover .animal-photo img { transform: scale(1.045); }
.animal-body { padding: 20px 20px 22px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.animal-name {
  font-family: var(--font-display); font-weight: 700;
  font-size: 23px; color: var(--cream); line-height: 1.15;
}
.animal-meta {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--steel-1);
}
.animal-note { font-size: 15px; color: var(--steel-1); margin: 10px 0 0; }
.animal-body .btn { margin-top: auto; align-self: flex-start; }

.tag {
  display: inline-block;
  font-family: var(--font-mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 5px 10px; border: 1px solid var(--rule); color: var(--steel-1);
  background: rgba(244,239,230,0.03);
}
.tag.ok { border-color: var(--ok); color: var(--ok); }
.tag.clay { border-color: var(--clay-bright); color: var(--clay-bright); }
.tag.info { border-color: var(--info); color: var(--info); }
.tag-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 12px 0 0; }

/* ============================================================
   DEFINITION LISTS — hours, contact blocks
   ============================================================ */
.deflist { display: grid; gap: 0; border-top: 1px solid var(--rule); }
.deflist > div {
  display: flex; flex-wrap: wrap; gap: 4px 26px;
  padding: 15px 0; border-bottom: 1px solid var(--rule-soft);
  transition: background 0.3s var(--ease-exit);
}
.deflist > div:hover { background: rgba(244,239,230,0.02); }
.deflist dt {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); min-width: 160px;
}
.deflist dd { margin: 0; color: var(--cream); font-size: 15.5px; }

/* ============================================================
   STEPS — "what to do if you lost a pet"
   ============================================================ */
.steps { counter-reset: step; display: grid; gap: 2px; }
.step {
  counter-increment: step;
  display: flex; gap: 20px;
  padding: 24px 0; border-bottom: 1px solid var(--rule-soft);
}
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono); font-size: 15px; font-weight: 700;
  letter-spacing: 0.04em; color: var(--gold);
  flex: none; padding-top: 2px; min-width: 30px;
}
.step p:last-child { margin-bottom: 0; }

/* ============================================================
   FOOTER
   ============================================================ */
footer.bulletin {
  border-top: 1px solid var(--gold);
  background: linear-gradient(180deg, var(--ink-1), var(--ink));
  padding: clamp(48px, 6vw, 76px) var(--pad) 0;
}
.footer-inner {
  max-width: 1240px; margin: 0 auto;
  display: grid; gap: 38px;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  padding-bottom: 40px;
}
.footer-col h5 {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 16px;
}
.footer-col a, .footer-col p {
  display: block; color: var(--steel-1); text-decoration: none;
  font-size: 15px; margin: 0 0 10px; max-width: none;
  transition: color 0.25s var(--ease-exit);
}
.footer-col a:hover { color: var(--gold-bright); }
.footer-bottom {
  max-width: 1240px; margin: 0 auto;
  border-top: 1px solid var(--rule);
  padding: 22px 0 38px;
  display: flex; flex-wrap: wrap; gap: 8px 24px;
  justify-content: space-between;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.06em; color: var(--steel);
}
.footer-bottom a { color: var(--steel); text-decoration: none; }
.footer-bottom a:hover { color: var(--gold); }

/* Design attribution. Deliberately the quietest thing in the footer: it is a
   credit on a county public-information site, not a promotion. It sits last
   and reads dimmer than the county's own line, so a resident scanning the
   footer for the county never lands on the vendor first. */
.footer-bottom .credit { color: var(--steel); opacity: 0.72; margin-left: auto; }
.footer-bottom .credit a { text-decoration: underline; text-decoration-color: rgba(150,161,175,0.4); text-underline-offset: 2px; }
.footer-bottom .credit:hover { opacity: 1; }
@media (max-width: 700px) {
  /* At phone width space-between strands it awkwardly; let it fall in line. */
  .footer-bottom .credit { margin-left: 0; }
}

/* ============================================================
   SCROLL REVEAL
   ============================================================
   GATED ON .js-motion, which mac.js puts on <html> at parse time. Without
   JS the selector never matches and every element renders at rest.

   That ordering is the whole point. If the hidden state were the default
   and JS did the revealing, one script failure would blank the page for a
   resident looking up a phone number. IntersectionObserver only — a
   scroll listener fires hundreds of times a second and reads layout on
   every one of them. */
.js-motion .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.9s var(--ease-spring),
    transform 0.9s var(--ease-spring);
  will-change: transform, opacity;
}
.js-motion .reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;   /* released once settled; a permanent hint costs memory */
}
.js-motion .reveal[data-i="1"] { transition-delay: 0.06s; }
.js-motion .reveal[data-i="2"] { transition-delay: 0.12s; }
.js-motion .reveal[data-i="3"] { transition-delay: 0.18s; }
.js-motion .reveal[data-i="4"] { transition-delay: 0.24s; }
.js-motion .reveal[data-i="5"] { transition-delay: 0.30s; }

@media (prefers-reduced-motion: reduce) {
  .js-motion .reveal { opacity: 1 !important; transform: none !important; }
  .nav-links.open a { animation: none !important; }
  .btn:hover, a.card:hover, .animal:hover { transform: none !important; }
}

/* ============================================================
   PRINT — a fee schedule that survives a county printer
   ============================================================ */
@media print {
  .classif, .nav, footer.bulletin, .hero-watermark, .hero::before,
  .btn-row, .skip-link, body::after { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .card, .stat, .table-scroll, table, .animal, .callout {
    border-color: #999; background: #fff; box-shadow: none !important;
  }
  .card::before, .stat::before, .animal::before { display: none; }
  tbody tr:nth-child(even) td { background: #fff; }
  h1, h2, h3, h4, .animal-name, td, p, .lede, li, dd { color: #000; }
  h2::before, th, .eyebrow, .card-label { color: #444; }
  a { color: #000; text-decoration: underline; }
  .wrap { padding: 0; max-width: none; }
  .js-motion .reveal { opacity: 1 !important; transform: none !important; }
}
