:root {
  --bg: #f7f5f2;
  --bg-elev: #ffffff;
  --ink: #1d1c1a;
  --ink-soft: #5d5952;
  --line: #e2ddd5;
  --photo-mat: #ece7e0;
  --accent: #9a5b2e;
  --accent-ink: #ffffff;
  --good: #3f7a4d;
  --warn: #a8622a;
  --bad: #9c4040;
  --radius: 14px;
  --shadow: 0 1px 2px rgba(0,0,0,.05), 0 8px 24px rgba(0,0,0,.05);
}
:root[data-theme="dark"], :root:not([data-theme="light"]) {
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #171614;
    --bg-elev: #211f1c;
    --ink: #f0ece6;
    --ink-soft: #a8a199;
    --line: #343029;
    --photo-mat: #191816;
    --accent: #d59256;
    --accent-ink: #1d1c1a;
    --good: #6fb47f;
    --warn: #d59256;
    --bad: #d47b7b;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #171614; --bg-elev: #211f1c; --ink: #f0ece6; --ink-soft: #a8a199;
  --line: #343029; --accent: #d59256; --accent-ink: #1d1c1a;
  --photo-mat: #191816;
  --good: #6fb47f; --warn: #d59256; --bad: #d47b7b;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
  color-scheme: dark;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
h1, h2, h3 { line-height: 1.2; margin: 0 0 .4em; letter-spacing: -.015em; }
h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); }
h2 { font-size: clamp(1.3rem, 2.6vw, 1.7rem); }
.small { font-size: .85rem; }
.muted { color: var(--ink-soft); }
.lede { font-size: 1.08rem; color: var(--ink-soft); max-width: 56ch; }

.top {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1rem clamp(1rem, 4vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 5;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
}
.brand { font-weight: 650; text-decoration: none; color: var(--ink); letter-spacing: -.02em; }
.brand { display: inline-flex; align-items: center; gap: .45rem; }
.mark { color: var(--accent); flex: 0 0 auto; }

main { max-width: 960px; margin: 0 auto; padding: clamp(1.25rem, 4vw, 2.5rem) clamp(1rem, 4vw, 2.5rem) 3rem; }
.panel { margin-bottom: 2rem; }
.panel[hidden] { display: none; }

button { font: inherit; cursor: pointer; border-radius: 10px; border: 1px solid transparent; }
.primary { background: var(--accent); color: var(--accent-ink); padding: .7em 1.5em; font-weight: 600; }
.primary:hover { filter: brightness(1.06); }
.ghost { background: transparent; color: var(--ink-soft); border-color: var(--line); padding: .5em 1em; }
.ghost:hover { color: var(--ink); border-color: var(--ink-soft); }
.actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1.5rem; }

.quizhead { margin-bottom: 1.5rem; }
.q {
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.1rem; margin-bottom: .75rem; box-shadow: var(--shadow);
}
.q.off { opacity: .62; }
.q-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.q-label { font-weight: 600; }
.q-kind { font-size: .75rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); }
.q input[type="range"] { width: 100%; margin: .6rem 0 .2rem; accent-color: var(--accent); }
.ends { display: flex; justify-content: space-between; gap: 1rem; }
.ends span { font-size: .8rem; color: var(--ink-soft); }

.reshead { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.cards { list-style: none; padding: 0; margin: 1.25rem 0 0; display: grid; gap: 1rem; }
.card {
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
  display: grid; grid-template-columns: 132px 1fr; gap: 0;
  /* start, not stretch: a stretched image column is taller than it is wide on a
     narrow screen, and object-fit:cover then crops the stored square into a
     strip — which is what cut the dogs' heads off on mobile. */
  align-items: start;
}
@media (max-width: 560px) { .card { grid-template-columns: 96px 1fr; } }
/* contain, NOT cover. The stored photo keeps its native aspect ratio and the
   slot is square, so the whole dog shows and the difference letterboxes against
   the mat. Sources cluster around 1.0-1.3:1, so that is roughly 9% a side.
   cover here was what cut the heads off — see build/optimise_images.py. */
.card img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain;
  display: block; background: var(--photo-mat); }
/* overflow-wrap:anywhere is the backstop for large text. The image column is a
   fixed 96px, so at 320px with 200% text the body gets 88px while the word
   "Sheepdog" alone needs 169px — and because .card is overflow:hidden the
   surplus was clipped invisibly instead of scrolling. This only engages when a
   word genuinely cannot fit, so nothing changes at ordinary sizes. */
.card-body { padding: .9rem 1.1rem 1rem; min-width: 0; overflow-wrap: anywhere; }
/* wrap + min-width:0, or the name and the score fight over one line: at 200%
   text "American Hairless Terrier" plus "74%" is wider than a phone card, and
   because .card is overflow:hidden the score was silently clipped off the edge
   rather than pushing a scrollbar. Same failure the trait pills had. */
.card-top { display: flex; justify-content: space-between; align-items: baseline;
  gap: .35rem .75rem; flex-wrap: wrap; }
.card h3 { margin: 0; font-size: 1.12rem; min-width: 0; }
.score { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--accent); white-space: nowrap; }
.rank { color: var(--ink-soft); font-weight: 500; font-variant-numeric: tabular-nums; }
/* The breed name is the way through to the breed page. Underline only on hover:
   195 permanently underlined headings turned the results list into a wall of rules. */
.card h3 .name { color: inherit; text-decoration: none; }
.card h3 .name:hover, .card h3 .name:focus-visible { text-decoration: underline; }
.facts { margin: .35rem 0 .55rem; font-size: .84rem; color: var(--ink-soft); }
.why { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0; padding: 0; list-style: none; }
/* No nowrap. A miss chip reads "Openness to strangers: 5 (you wanted at most 2)",
   which is far wider than a 96px-image card leaves on a phone — the pill ran
   straight out past the card edge and the text was cut off. Let it wrap inside
   its own pill; max-width stops a single long word doing the same thing. */
.why li {
  font-size: .78rem; padding: .2em .6em; border-radius: 999px;
  border: 1px solid var(--line); max-width: 100%; overflow-wrap: anywhere;
}
.why .hit { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, var(--line)); }
.why .miss { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, var(--line)); }
.credit { margin: .6rem 0 0; font-size: .72rem; color: var(--ink-soft); }
.credit a { color: inherit; }

footer { border-top: 1px solid var(--line); padding: 1rem clamp(1rem, 4vw, 2.5rem) 1.5rem;
  max-width: 960px; margin: 0 auto; }
/* Source/licence boilerplate is reference material, not reading matter — it is
   set smaller than the memorial line below it, which keeps its own size. */
footer p.small { margin: .15rem 0; line-height: 1.35; font-size: .66rem; }

table.credits { width: 100%; border-collapse: collapse; font-size: .85rem; }
table.credits th, table.credits td { text-align: left; padding: .45rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.tablewrap { overflow-x: auto; }

/* ---- theme toggle icon ------------------------------------------------- */
.iconbtn {
  background: transparent; border: 1px solid var(--line); color: var(--ink-soft);
  width: 38px; height: 38px; display: grid; place-items: center; padding: 0;
}
.iconbtn:hover { color: var(--ink); border-color: var(--ink-soft); }
.iconbtn svg { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.iconbtn svg .fill { fill: currentColor; stroke: none; }
/* One icon shows at a time: auto by default, sun/moon once a theme is pinned. */
.iconbtn .i-sun, .iconbtn .i-moon { display: none; }
:root[data-theme="light"] .iconbtn .i-auto, :root[data-theme="dark"] .iconbtn .i-auto { display: none; }
:root[data-theme="light"] .iconbtn .i-sun { display: inline; }
:root[data-theme="dark"] .iconbtn .i-moon { display: inline; }

/* ---- hero photography --------------------------------------------------- */
/* Copy first, dog second in source order, so the CTA is never pushed below the
   fold on a phone. On a wide screen they sit side by side. */
.intro-grid { display: grid; gap: clamp(1.25rem, 4vw, 2.5rem); align-items: center; }
@media (min-width: 760px) { .intro-grid { grid-template-columns: 1fr 1fr; } }
.intro-copy > .primary { margin-top: .6rem; }
.intro-copy > .small { margin-bottom: 0; }

.hero { margin: 0; }
.hero[hidden] { display: none; }
.hero img {
  width: 100%; height: auto; display: block; border-radius: var(--radius);
  box-shadow: var(--shadow); background: var(--line);
  aspect-ratio: 4 / 3; object-fit: cover;
}
.hero .credit { margin: .4rem 0 0; text-align: right; }

/* The stepper is the wayfinding now, so the quiz header earns much less room
   than the intro does — smaller heading, smaller portrait, one line of copy. */
.quizhead { display: flex; align-items: center; gap: clamp(.9rem, 3vw, 1.5rem); margin-bottom: 1.1rem; }
.quizhead h2 { font-size: clamp(1.15rem, 2.2vw, 1.4rem); }
.quizhead > div { flex: 1; min-width: 0; }
.quizhead h2, .quizhead p { margin-top: 0; }
.portrait { margin: 0; flex: 0 0 auto; width: clamp(64px, 11vw, 92px); }
.portrait[hidden] { display: none; }
.portrait img {
  width: 100%; height: auto; display: block; border-radius: 50%;
  border: 3px solid var(--bg-elev); box-shadow: var(--shadow); background: var(--line);
  aspect-ratio: 1; object-fit: cover;
}
/* No negative margin here: it let the caption escape the viewport by 2px at
   380px wide. Let it wrap instead — two short lines are fine under a circle. */
.portrait .credit { margin: .45rem 0 0; text-align: center; line-height: 1.3; font-size: .68rem;
  overflow-wrap: anywhere; }
.portrait .credit a { text-decoration-thickness: from-font; }

/* ---- slider value readout ---------------------------------------------- */
.readout {
  display: flex; align-items: baseline; gap: .5rem; justify-content: center;
  margin: .1rem 0 .35rem; min-height: 1.5rem;
}
.readout .pill {
  font-size: .82rem; font-weight: 600; padding: .2em .8em; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.q.off .readout .pill { background: transparent; color: var(--ink-soft); border-color: var(--line); }



/* ---- questionnaire steps ------------------------------------------------ */
.steps { display: flex; gap: .4rem; margin: 0 0 .9rem; flex-wrap: wrap; }
.steps button {
  flex: 1 1 0; min-width: 110px; text-align: left; padding: .5rem .75rem .55rem;
  background: transparent; border: 1px solid var(--line); color: var(--ink-soft);
  border-radius: 10px; line-height: 1.25;
}
.steps button:hover { border-color: var(--ink-soft); color: var(--ink); }
.steps button[aria-current="true"] {
  border-color: var(--accent); color: var(--ink);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.steps .n { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; opacity: .75; }
.steps .t { font-weight: 600; font-size: .9rem; }
.steps .set { display: block; font-variant-numeric: tabular-nums; font-size: .72rem; color: var(--accent); }
.steps .set.blank { visibility: hidden; }
.stepblurb { margin: 0 0 1rem; }
.actions .spacer { flex: 1; }

/* Two columns on a wide screen. The cards were full-width with a long empty
   middle, which is what made five questions feel like a scroll. */
/* min() guard: a bare minmax(430px,...) forces a 430px track on a 380px phone
   and pushes the page sideways. */
#questions { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(430px, 100%), 1fr)); gap: .6rem; }
#questions > .q { margin-bottom: 0; }

/* ---- compact question card ---------------------------------------------- */
.q { padding: .7rem .9rem .75rem; margin-bottom: .6rem; }
.q-top { align-items: center; gap: .75rem; flex-wrap: nowrap; }
.q-label { font-size: .95rem; flex: 1; min-width: 0; }
.q-kind { display: none; }
/* Undo for a single question. Shown only once an answer exists, on EVERY card —
   the old checkbox appeared on target questions only and read as arbitrary. */
.clearq {
  flex: 0 0 auto; font-size: .74rem; padding: .2em .6em; border-radius: 999px;
  background: transparent; border: 1px solid var(--line); color: var(--ink-soft);
  white-space: nowrap;
}
.clearq:hover { color: var(--ink); border-color: var(--ink-soft); }
.clearq.blank { visibility: hidden; }
/* Readout sits UNDER the slider, not beside it: side by side, the pill ate more
   width than the control it described and truncated its own text. */
.sliderrow { display: flex; flex-direction: column; gap: .3rem; margin: .5rem 0 .1rem; }
.sliderrow input[type="range"] { width: 100%; margin: 0; }
.sliderrow .readout { margin: 0; min-height: 0; justify-content: center; }
/* Hidden with visibility, not display: the pill keeps its box, so a card is
   exactly the same height before and after it gets an answer. */
.readout .pill.blank { visibility: hidden; }
.q .ends { margin-top: .1rem; }
.q .ends span { font-size: .74rem; }

.q.off .readout .pill { background: transparent; color: var(--ink-soft); border-color: var(--line); }

@media (max-width: 620px) { .q-top { flex-wrap: wrap; } }


/* ---- slider ------------------------------------------------------------- */
/* Fully custom-styled rather than using accent-color. A native range always
   paints left-of-thumb differently from right, so even an all-grey accent still
   read as "half full" while the question said Not scored. Here an unscored
   slider gets ONE flat track and a hollow thumb: it claims nothing. The filled
   portion is a gradient driven by --pct, set from paint() in app.js. */
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 20px; background: transparent; cursor: pointer;
}
input[type="range"]:disabled { cursor: default; }

input[type="range"]::-webkit-slider-runnable-track {
  height: 5px; border-radius: 999px;
  background: linear-gradient(to right,
    var(--accent) calc(var(--pct, 0) * 1%), var(--line) calc(var(--pct, 0) * 1%));
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 17px; height: 17px; margin-top: -6px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg-elev);
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
input[type="range"]::-moz-range-track { height: 5px; border-radius: 999px; background: var(--line); }
input[type="range"]::-moz-range-progress { height: 5px; border-radius: 999px; background: var(--accent); }
input[type="range"]::-moz-range-thumb {
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg-elev);
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
input[type="range"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Bigger hit area for fingers. The track is drawn 5px regardless, so this only
   grows the target, it does not change how the slider looks. */
@media (pointer: coarse) { input[type="range"] { height: 32px; } }

/* Unscored: one flat track, hollow thumb. */
.q.off input[type="range"]::-webkit-slider-runnable-track { background: var(--line); }
.q.off input[type="range"]::-webkit-slider-thumb {
  background: var(--bg-elev); border-color: var(--line); box-shadow: none;
}
.q.off input[type="range"]::-moz-range-track { background: var(--line); }
.q.off input[type="range"]::-moz-range-progress { background: var(--line); }
.q.off input[type="range"]::-moz-range-thumb {
  background: var(--bg-elev); border-color: var(--line); box-shadow: none;
}

/* ---- memorial ----------------------------------------------------------- */
.memorial {
  margin: .9rem 0 0; padding-top: .8rem; border-top: 1px solid var(--line);
  font-size: .82rem; color: var(--ink-soft); text-align: center; font-style: italic;
}
.memorial .heart { font-style: normal; }

/* ---- results filter ----------------------------------------------------- */
.reshead-actions { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; }
.switch {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  font-size: .85rem; color: var(--ink-soft); white-space: nowrap;
}
.switch input { accent-color: var(--accent); margin: 0; }
.switch:hover { color: var(--ink); }
.footnote { font-size: .74rem; margin: .1rem 0 0; max-width: 62ch; }
.empty {
  margin: 1.25rem 0 0; padding: 1.1rem; border: 1px dashed var(--line);
  border-radius: var(--radius); color: var(--ink-soft); text-align: center;
}

/* The credits page is the only place photographers are named now, so its link
   is set apart from the surrounding boilerplate rather than buried in it. */
.creditlink { font-weight: 600; text-decoration-thickness: 2px; text-underline-offset: 2px; }


/* ---- donation prompt (home only) ---------------------------------------- */
.give {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  flex-wrap: wrap; margin: 0 0 2rem;
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.1rem 1.3rem; box-shadow: var(--shadow);
}
.give[hidden] { display: none; }
.give > div { flex: 1 1 22rem; min-width: 0; }
.give h2 { font-size: 1.05rem; margin-bottom: .35rem; }
.give p { margin: 0 0 .3rem; color: var(--ink-soft); font-size: .9rem; }
.give p.small { font-size: .72rem; margin-bottom: 0; }
/* .primary's radius lives on the `button` element selector, and this is an <a>. */
.give-btn { flex: 0 0 auto; text-decoration: none; display: inline-block; border-radius: 10px; }
.give-btn:hover { filter: brightness(1.06); }

/* ---- per-breed pages ---------------------------------------------------- */
.breedpage { max-width: 900px; }
.crumbs { font-size: .78rem; color: var(--ink-soft); margin: 0 0 1.2rem; }
.crumbs a { color: var(--ink-soft); }
.crumbs a:hover { color: var(--accent); }
.breedhead { display: grid; gap: clamp(1rem, 3vw, 2rem); align-items: start; margin-bottom: 2rem; }
@media (min-width: 640px) { .breedhead { grid-template-columns: 240px 1fr; } }
.breedhead img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain;
  border-radius: var(--radius); box-shadow: var(--shadow); background: var(--photo-mat); }
.breedhead h1 { font-size: clamp(1.6rem, 4vw, 2.2rem); margin-bottom: .3rem; }
.breedhead .facts { color: var(--ink-soft); font-size: .88rem; margin: 0 0 .7rem; }
.cta { display: inline-block; text-decoration: none; border-radius: 10px; margin-top: .4rem; }
.cta:hover { filter: brightness(1.06); }

.bars { list-style: none; padding: 0; margin: 0 0 .5rem; display: grid; gap: .4rem; }
.bars li { display: grid; grid-template-columns: 11rem 1fr 1.5rem; align-items: center; gap: .7rem; }
@media (max-width: 560px) { .bars li { grid-template-columns: 8.5rem 1fr 1.5rem; font-size: .85rem; } }
.bars .bl { color: var(--ink-soft); font-size: .85rem; }
.bars .bt { background: var(--line); height: 8px; border-radius: 999px; overflow: hidden; }
.bars .bf { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.bars .bv { font-variant-numeric: tabular-nums; font-size: .82rem; color: var(--ink-soft); text-align: right; }

blockquote.wp { margin: 0 0 1.5rem; padding: .9rem 1.1rem; background: var(--bg-elev);
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--radius); font-size: .92rem; }
blockquote.wp cite { display: block; margin-top: .5rem; font-size: .74rem;
  color: var(--ink-soft); font-style: normal; }

.simgrid { list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .9rem; }
.simgrid a { display: block; text-decoration: none; color: var(--ink); }
.simgrid img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain;
  border-radius: 10px; background: var(--photo-mat); }
.simgrid span { display: block; font-size: .8rem; margin-top: .35rem; line-height: 1.3; }
.simgrid a:hover span { color: var(--accent); }
.fit { display: grid; gap: 1rem; margin: 1.5rem 0; }
@media (min-width: 560px) { .fit { grid-template-columns: 1fr 1fr; } }
.fit > div { background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .9rem 1.1rem; }
.fit h3 { font-size: .92rem; margin: 0 0 .4rem; }
.fit ul { margin: 0; padding-left: 1.1rem; font-size: .88rem; color: var(--ink-soft); }
.fit li { margin: .2rem 0; }
.card .summary { margin: 0 0 .5rem; font-size: .88rem; color: var(--ink); }
