/* Reset, document defaults and the shared button system. */

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

/* 100%, not a fixed 16px: the type scale in tokens.css is expressed in rem, so
   pinning the root here would silently override a reader's own font-size
   setting. Identical to 16px at default settings. */
/* scroll-padding-top because the header sticks on every page: without it an
   anchor lands with its target tucked under the header. --nav-h is the header's
   own height, so the two cannot drift apart. */
html { font-size: 100%; scroll-behavior: smooth; scroll-padding-top: var(--nav-h); }

/* overflow-x:hidden is a backstop, not a fix. It was doing the work of a
   responsive layout here: six rows overflowed on a phone and were silently
   clipped, which is why the "View all stories" link was unreachable. Every one
   of those is fixed, and tools/probe.sh asserts it stays that way at twelve
   widths in both languages. Remove this line to see real overflow while
   working; put it back before shipping. */
body { font-family: var(--font-main); color: var(--black); background: var(--white); overflow-x: hidden; }

/* Case IDs (MH-20260519-0041), emails and URLs have no break opportunity and
   punch out of narrow columns. CJK breaks anywhere by default and is unaffected. */
body { overflow-wrap: break-word; }

a { text-decoration: none; color: inherit; }

/* Visible to assistive technology only. The nav's drawer toggle is drawn as
   three bars, so its accessible name has to come from real text — and that text
   has to be translatable, which rules out aria-label (i18n writes textContent,
   not attributes). */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Keyboard focus was invisible site-wide: every interactive element styled
   :hover and nothing styled :focus. */
:focus-visible { outline: 2px solid var(--black); outline-offset: 2px; border-radius: 4px; }

/* ── BUTTONS ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-family: var(--font-main);
  font-weight: 500;
  cursor: pointer;
  transition: opacity .15s;
  border: none;
}

/* Compact solid button — the nav CTA on lost-found.html, the only page using it.
   index.html carried a larger 16px/12px-24px variant of this rule, but never
   applied the class; these are the values actually in use. */
.btn-black {
  background: var(--black);
  color: var(--white);
  padding: 4px 10px;
  font-size: var(--step--1);
}

/* .btn-black-lg and .btn-gray are the same treatment under two names; both are
   in use across the site, so both selectors stay. */
.btn-black-lg, .btn-gray {
  background: var(--light-gray);
  color: var(--black);
  padding: 10px 20px;
  font-size: var(--step-0);
  font-family: var(--font-soft);
  font-weight: 700;
}

/* ── MEDIA FRAME ──
   The one correct pattern on the site (still-waiting's .pet-card-img), lifted
   so the pages stop reinventing it. A box that reserves its space before the
   asset loads, fills without distorting, and is capped against the viewport so
   it cannot take over a phone screen. */
.media-frame { position: relative; overflow: hidden; }
.media-frame > img,
.media-frame > video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── TOUCH ──
   Keyed on a coarse pointer OR a narrow viewport rather than the pointer alone:
   a 400px-wide window is a phone layout whatever is driving it, and headless
   Chrome always reports a fine pointer, so pointer-only rules are untestable. */
@media (pointer: coarse), (max-width: 1023px) {
  .btn { min-height: var(--tap); }
  .btn-black { padding: 8px 16px; }
}

/* Hover effects are latched by a tap on a touch screen — the element keeps its
   hover paint until something else is touched. Guard every one of them. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { opacity: .8; }
}

/* ── SHARED KEYFRAMES ──
   Keyframe names are global to a document. dot-pulse and pin-pulse were once
   both called "pulse" on two different elements, in two style blocks, on two
   pages — the later definition silently won and drove the wrong element. Keep
   them distinctly named, and defined once.

   slideUp lives here because index.html references it on its rescue modal but
   loads neither of the two page files that used to define it, so the animation
   silently did nothing there. */
@keyframes dot-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .3; }
}
@keyframes pin-pulse {
  0%   { transform: scale(1); opacity: 0.4; }
  100% { transform: scale(3); opacity: 0; }
}
@keyframes slideUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* ── REDUCED MOTION ──
   Two infinite loops run on every visit (the badge dot, and one halo per map
   pin), plus a 10s interval mutating marker styles forever. Honour the setting. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── SHORT LANDSCAPE ──
   A rotated phone is ~844px wide and ~390px tall: wide enough to miss every
   phone width query, short enough that hero padding and media caps have to
   come down or the first screen holds nothing but a header. */
@media (max-height: 520px) and (orientation: landscape) {
  :root {
    --media-h-hero: clamp(160px, 60svh, 260px);
    --media-h-map:  clamp(180px, 60svh, 300px);
    --gap-sec: clamp(28px, 4vw, 44px);
  }
}
