/*
 * The One. One stylesheet, no build step — Propshaft serves this file directly.
 *
 * Tier colours mirror the emoji in config/game.yml so the on-screen pips and the
 * pasted share grid read as the same scale: white, green, blue, purple, gold.
 */

:root {
  --parchment: #f7f3ea;
  --parchment-deep: #efe7d7;
  --ink: #23201b;
  --ink-soft: #6b6456;
  --rule: #ddd3bf;
  --gold: #c08a2e;

  --tier-none: #b9b1a1;
  --tier-common: #e4ddcc;
  --tier-uncommon: #5d9b61;
  --tier-rare: #4572a7;
  --tier-very-rare: #7c5aa6;
  --tier-the-one: var(--gold);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --parchment: #1b1917;
    --parchment-deep: #242020;
    --ink: #f0e9dc;
    --ink-soft: #a89f8e;
    --rule: #3a342c;
    --tier-common: #4a443a;
  }
}

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

body {
  margin: 0;
  background: var(--parchment);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

.shell {
  max-width: 34rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- masthead ------------------------------------------------------------- */

.masthead { text-align: center; margin-bottom: 1.5rem; }

.masthead__title {
  font-family: var(--serif);
  font-size: 1.6rem;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
}

.masthead__one { color: var(--gold); font-style: italic; }

.masthead__meta {
  margin: 0.25rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-soft);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.main { flex: 1; }

.footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-align: center;
}
.footer p { margin: 0; }

/* --- the round ------------------------------------------------------------ */

.round__prompt {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.3;
  margin: 0 0 1.25rem;
}

/* Sits snug under the prompt, so the prompt gives up its bottom margin. */
.round__prompt:has(+ .round__hint) { margin-bottom: 0.35rem; }

.round__hint {
  margin: 0 0 1.25rem;
  font-size: 0.85rem;
  font-style: italic;
  color: rgba(243, 247, 240, 0.65);
}

.round__form { display: flex; gap: 0.5rem; }

.round__input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 0.85rem;
  font-size: 1rem;
  font-family: inherit;
  color: var(--ink);
  background: var(--parchment-deep);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.round__input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.round__input:disabled { opacity: 0.6; }

.round__note {
  margin: 0.85rem 0 0;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.round__note--miss strong { color: var(--ink); }
.round__note--warn { color: #b4452f; }

.round__timeout { display: none; }

/* --- buttons -------------------------------------------------------------- */

.button {
  display: inline-block;
  padding: 0.7rem 1.1rem;
  font: inherit;
  font-size: 0.95rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}

.button--primary { background: var(--ink); color: var(--parchment); }
.button--primary:hover { background: var(--ink-soft); }

.button--quiet {
  background: transparent;
  color: var(--ink-soft);
  border-color: var(--rule);
  font-size: 0.85rem;
  padding: 0.5rem 0.9rem;
}
.button--quiet:hover { color: var(--ink); }

/* button_to wraps in a form; keep them inline with their neighbours */
.button_to { display: contents; }

.link { color: var(--ink-soft); }

/* --- the reveal ----------------------------------------------------------- */

/* Centred, one line each: the rarity, what the player typed, what it earned,
   and the running total. Bigger to smaller, so it reads top to bottom. */
.reveal { text-align: center; }

.reveal__tier {
  margin: 0;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(2rem, 9vw, 3.2rem);
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  text-transform: uppercase;
}

.reveal__guess { margin: 0.9rem 0 0; font-size: 1.35rem; }

.reveal__earned {
  margin: 1rem 0 0;
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.reveal__total {
  margin: 0.6rem 0 0;
  font-size: 0.9rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.reveal--uncommon .reveal__tier { color: #8fd694; }
.reveal--rare .reveal__tier { color: #8cb8ee; }
.reveal--very_rare .reveal__tier { color: #c3a5ea; }
.reveal--the_one .reveal__tier { color: #ffd874; }

/* --- results -------------------------------------------------------------- */

.results { text-align: center; }

.results__grid {
  font-size: 1.6rem;
  letter-spacing: 0.1em;
  margin: 0 0 0.75rem;
}

.results__total {
  font-family: var(--serif);
  font-size: 2.6rem;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.results__unit {
  display: block;
  font-family: var(--sans);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-soft);
}

.results__landmark { margin: 0.75rem 0 0; color: var(--ink-soft); font-size: 0.95rem; }
.results__streak { margin: 1rem 0 0; font-size: 0.95rem; }
.results__best { color: var(--ink-soft); font-size: 0.85rem; }

.results__rows {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  text-align: left;
  border-top: 1px solid var(--rule);
}

.results__row {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}

.results__row-text { flex: 1; min-width: 0; }

.results__row-prompt {
  display: block;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.results__row-answer { display: block; font-size: 0.95rem; }

.results__row-cubits {
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.results__actions { margin-top: 2rem; }
.results__copied { margin: 0.6rem 0 0; font-size: 0.85rem; color: var(--ink-soft); }
.results__nav { margin-top: 1.5rem; font-size: 0.85rem; }

/* --- empty state ---------------------------------------------------------- */

.empty { text-align: center; padding: 3rem 0; }
.empty__title { font-family: var(--serif); font-size: 1.6rem; margin: 0 0 0.5rem; }
.empty__body { color: var(--ink-soft); margin: 0 0 1.5rem; }
.empty__hint { font-size: 0.85rem; color: var(--ink-soft); }

.empty__hint code {
  background: var(--parchment-deep);
  padding: 0.15rem 0.35rem;
  border-radius: 4px;
}

/* --- the pasture ---------------------------------------------------------- */
/*
 * A side-scroller fixed behind everything. It never scrolls with the page and
 * never re-renders — it is turbo-permanent — and the pasture controller moves
 * its layers with transforms as the sheep covers ground.
 *
 * --px is the pixel-art unit. Fixed in screen pixels rather than scaled to the
 * viewport, because a pixel that changes size between breakpoints stops reading
 * as pixel art.
 */

:root {
  --px: 5px;
  --horizon: 56%;
  /* The answer dock's height. The animals stand clear of it on every screen,
     not just during a round, so the sheep never hops as the dock comes and goes. */
  --dock-height: 6rem;
  --ground-line: max(15%, calc(var(--dock-height) + 1.25rem));
  /* Where the animals stand. The sheep is fixed here and the world moves; the
     shepherd starts just behind it and is left behind as the run begins. */
  --sheep-at: 25%;
  --shepherd-at: 14%;
}

@media (max-width: 40rem) {
  :root {
    --px: 4px;
    --horizon: 52%;
    --ground-line: max(13%, calc(var(--dock-height) + 1rem));
    --sheep-at: 40%;
    --shepherd-at: 14%;
  }
}

body { min-height: 100svh; }

.pasture {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #4f8c4c;
  pointer-events: none;
}

.pasture__sky {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--horizon);
  background: linear-gradient(to bottom, #7cc4e8 0%, #b8e0f2 60%, #dff0f7 100%);
}

.pasture__ground {
  position: absolute;
  inset: var(--horizon) 0 0 0;
  background: #4f8c4c;
}

.pasture__sun {
  position: absolute;
  top: 8%;
  right: 8%;
  width: calc(8 * var(--px));
  height: calc(8 * var(--px));
  opacity: 0.9;
}

/*
 * A scrolling layer is one tile wider than the screen, so shifting it left by
 * anything up to a whole tile never uncovers its right edge. The controller
 * takes the offset modulo the tile, so the layer is endless.
 */
.pasture__layer {
  position: absolute;
  left: 0;
  width: calc(100% + var(--tile, 0px));
  will-change: transform;
}

.pasture__layer--clouds { top: 0; height: 90px; }

/* Straddles the horizon, so the hills rise into the sky and the nearest band
   merges into the ground, which is why that band is the ground's own green. */
.pasture__layer--hills {
  top: calc(var(--horizon) - 96px);
  height: 150px;
}

.pasture__layer--tufts {
  top: calc(var(--horizon) + 2rem);
  bottom: 0;
}

/* --- the living scene ------------------------------------------------------ */
/*
 * Ambient motion that runs whether or not the sheep is moving. The camera owns
 * each layer's transform, so anything that moves on its own does it on a
 * wrapper (the cloud drift) or on elements inside a layer (the grain, the far
 * flock), never on the layer itself.
 */

/* One cloud tile (1800px) every four minutes: slow enough to notice only when
   you look up from a question. */
.pasture__drift {
  position: absolute;
  inset: 0 0 auto 0;
  height: 90px;
  animation: cloud-drift 240s linear infinite;
  will-change: transform;
}

@keyframes cloud-drift {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-1800px, 0, 0); }
}

/* The fields stand on the middle hills, their feet tucked behind the front band. */
.pasture__layer--fields {
  top: calc(var(--horizon) - 50px);
  height: 56px;
}

.pasture__ears--leaning { opacity: 0; }
.pasture__ears--still { animation: frame-a 2.8s steps(1) infinite var(--sway-delay, 0s); }
.pasture__ears--leaning { animation: frame-b 2.8s steps(1) infinite var(--sway-delay, 0s); }

/* Mostly heads up, now and then a mouthful. */
.pasture__far-sheep--down { opacity: 0; }
.pasture__far-sheep--up { animation: graze-up var(--graze-time, 6s) steps(1) infinite var(--graze-delay, 0s); }
.pasture__far-sheep--down { animation: graze-down var(--graze-time, 6s) steps(1) infinite var(--graze-delay, 0s); }

.pasture__far-shepherd { animation: shepherd-pace 16s steps(8) infinite var(--pace-delay, 0s); }

@keyframes frame-a {
  0%, 59% { opacity: 1; }
  60%, 100% { opacity: 0; }
}

@keyframes frame-b {
  0%, 59% { opacity: 0; }
  60%, 100% { opacity: 1; }
}

@keyframes graze-up {
  0%, 54% { opacity: 1; }
  55%, 100% { opacity: 0; }
}

@keyframes graze-down {
  0%, 54% { opacity: 0; }
  55%, 100% { opacity: 1; }
}

@keyframes shepherd-pace {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(10px); }
}

/* Birds fly in the band of sky above the hills and behind them. Each bird is
   placed and timed by the birds controller through custom properties. */
.pasture__birds {
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(var(--horizon) - 60px);
  overflow: hidden;
}

.pasture__bird {
  position: absolute;
  left: 0;
  top: var(--y, 20%);
  width: var(--size, 15px);
  aspect-ratio: 5 / 3;
  opacity: var(--alpha, 0.85);
  animation: bird-cross var(--duration, 14s) linear var(--delay, 0s) both;
}

.pasture__bird.is-westward { animation-direction: reverse; }

/* A gentle rise and fall on top of the crossing, so a flock doesn't fly on rails. */
.pasture__bird svg {
  display: block;
  width: 100%;
  height: 100%;
  animation: bird-glide 2.4s ease-in-out infinite alternate var(--delay, 0s);
}

.pasture__wings--down { opacity: 0; }
.pasture__wings--up { animation: frame-flap-a 0.4s steps(1) infinite; }
.pasture__wings--down { animation: frame-flap-b 0.4s steps(1) infinite; }

@keyframes bird-cross {
  from { transform: translate3d(-40px, 0, 0); }
  to { transform: translate3d(calc(100vw + 40px), 0, 0); }
}

@keyframes bird-glide {
  from { transform: translateY(-3px); }
  to { transform: translateY(3px); }
}

@keyframes frame-flap-a {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes frame-flap-b {
  0%, 49% { opacity: 0; }
  50%, 100% { opacity: 1; }
}

/* --- the flock ------------------------------------------------------------ */

.pasture__shepherd {
  position: absolute;
  left: var(--shepherd-at);
  bottom: var(--ground-line);
  width: calc(10 * var(--px));
  height: calc(16 * var(--px));
  will-change: transform;
}

.pasture__shepherd svg,
.pasture__sheep svg { display: block; width: 100%; height: 100%; }

/* The rest of the flock, milling about round the shepherd. Each layer spans
   the screen so the ewes can be placed against it; the camera owns the layer's
   transform and the flock controller owns each ewe's --wander. */
.pasture__flock {
  position: absolute;
  inset: 0;
  will-change: transform;
}

.pasture__ewe {
  position: absolute;
  left: calc(var(--sheep-at) * var(--at));
  bottom: calc(var(--ground-line) + var(--rise) * var(--px));
  width: calc(14 * var(--px));
  height: calc(11 * var(--px));
  transform: translateX(calc(var(--wander, 0) * var(--px)));
  transition: transform var(--amble, 0s) linear;
}

.pasture__ewe-sprite { display: block; width: 100%; height: 100%; overflow: visible; }
.pasture__ewe.is-facing-left .pasture__ewe-sprite { transform: scaleX(-1); }

.pasture__ewe-head--down { opacity: 0; }
.pasture__ewe[data-state="graze"] .pasture__ewe-head--up { opacity: 0; }
.pasture__ewe[data-state="graze"] .pasture__ewe-head--down {
  opacity: 1;
  animation: antic-chew 0.4s steps(1) infinite;
}

/* An amble: the same stride as the sheep's walk, a little slower. */
.pasture__ewe[data-state="walk"] { animation: ewe-bob 0.6s steps(2) infinite; }
.pasture__ewe[data-state="walk"] .pasture__legs--stride { animation: sheep-stride 0.6s steps(1) infinite; }
.pasture__ewe[data-state="walk"] .pasture__legs--gather { animation: sheep-gather 0.6s steps(1) infinite; }

/* Bobs with translate, which stacks on the transform carrying her along. */
@keyframes ewe-bob {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 calc(-0.5 * var(--px)); }
}

.pasture__sheep {
  position: absolute;
  left: var(--sheep-at);
  bottom: var(--ground-line);
  width: calc(14 * var(--px));
  height: calc(11 * var(--px));
  transform: translateX(-50%);
}

/* The two leg frames sit on top of each other; a gait animation cross-fades
   them with steps(1), which reads as a stride rather than a dissolve. */
.pasture__legs--gather { opacity: 0; }
.pasture__legs--stride { opacity: 1; }

@keyframes sheep-stride {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes sheep-gather {
  0%, 49% { opacity: 0; }
  50%, 100% { opacity: 1; }
}

@keyframes sheep-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(calc(-0.5 * var(--px))); }
}

@keyframes sheep-leap {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  35% { transform: translateX(-50%) translateY(calc(-3.5 * var(--px))); }
  70% { transform: translateX(-50%) translateY(calc(-1 * var(--px))); }
}

@keyframes sheep-graze {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(calc(0.25 * var(--px))); }
}

/* Each gait is a leg cadence plus a body motion. Faster cadence reads as a
   faster animal more than the travel time does. */
.pasture__sheep.is-grazing { animation: sheep-graze 2.6s ease-in-out infinite; }

.pasture__sheep.is-walking { animation: sheep-bob 0.5s steps(2) infinite; }
.pasture__sheep.is-walking .pasture__legs--stride { animation: sheep-stride 0.5s steps(1) infinite; }
.pasture__sheep.is-walking .pasture__legs--gather { animation: sheep-gather 0.5s steps(1) infinite; }

.pasture__sheep.is-trotting { animation: sheep-bob 0.3s steps(2) infinite; }
.pasture__sheep.is-trotting .pasture__legs--stride { animation: sheep-stride 0.3s steps(1) infinite; }
.pasture__sheep.is-trotting .pasture__legs--gather { animation: sheep-gather 0.3s steps(1) infinite; }

.pasture__sheep.is-running { animation: sheep-bob 0.18s steps(2) infinite; }
.pasture__sheep.is-running .pasture__legs--stride { animation: sheep-stride 0.18s steps(1) infinite; }
.pasture__sheep.is-running .pasture__legs--gather { animation: sheep-gather 0.18s steps(1) infinite; }

.pasture__sheep.is-leaping { animation: sheep-leap 0.62s ease-in-out infinite; }
.pasture__sheep.is-leaping .pasture__legs--stride { animation: sheep-stride 0.16s steps(1) infinite; }
.pasture__sheep.is-leaping .pasture__legs--gather { animation: sheep-gather 0.16s steps(1) infinite; }

/* --- shadow and the grass underfoot --------------------------------------- */
/*
 * Both sit outside the sheep, so the gait's bob and leap don't carry them off
 * the ground, and both read the gait from the sheep's classes with :has().
 * --stride is the leg cadence of the current gait, the same numbers the leg
 * animations above use, so the grass is pushed about in step with the hooves.
 */
.pasture:has(.pasture__sheep.is-walking) { --stride: 0.5s; }
.pasture:has(.pasture__sheep.is-trotting) { --stride: 0.3s; }
.pasture:has(.pasture__sheep.is-running) { --stride: 0.18s; }
.pasture:has(.pasture__sheep.is-leaping) { --stride: 0.16s; }

/* Centred under the body rather than the whole sprite (the head sticks out in
   front), and nudged back a touch, away from the sun. */
.pasture__shadow {
  position: absolute;
  left: var(--sheep-at);
  bottom: calc(var(--ground-line) - 1.5 * var(--px));
  width: calc(16 * var(--px));
  height: calc(3 * var(--px));
  transform: translateX(calc(-50% - 1.5 * var(--px)));
  opacity: 0.4;
}

.pasture__shadow svg {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: 50% 50%;
}

/* In the air the shadow shrinks and fades, and grows back as the sheep comes
   down, on the same beat as the leap and the pronk. */
.pasture:has(.pasture__sheep.is-leaping) .pasture__shadow svg {
  animation: shadow-leap 0.62s ease-in-out infinite;
}
.pasture:has(.pasture__sheep:is([data-antic="pronk"], [data-antic="hop"])) .pasture__shadow svg {
  animation: shadow-pronk 1.6s ease-in-out forwards;
}

@keyframes shadow-leap {
  0%, 100% { transform: scaleX(1); opacity: 1; }
  35% { transform: scaleX(0.6); opacity: 0.45; }
  70% { transform: scaleX(0.9); opacity: 0.85; }
}

@keyframes shadow-pronk {
  0%, 10%, 45%, 55%, 90%, 100% { transform: scaleX(1); opacity: 1; }
  27% { transform: scaleX(0.55); opacity: 0.4; }
  72% { transform: scaleX(0.65); opacity: 0.5; }
}

/* Laid over the hooves and centred on the sheep. Its bottom row sits just
   under the ground line so the bases of the blades are in the field. */
.pasture__ruffle {
  position: absolute;
  left: var(--sheep-at);
  bottom: calc(var(--ground-line) - var(--px));
  width: calc(20 * var(--px));
  height: calc(3 * var(--px));
  transform: translateX(-50%);
}

.pasture__ruffle svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.pasture__blades--back,
.pasture__blades--fore,
.pasture__kick { opacity: 0; }

/* On the move, the standing frame gives way to the two flattened ones, which
   swap on every stride. Inside the svg, 1px is one pixel of the sprite. */
.pasture:has(.pasture__sheep:is(.is-walking, .is-trotting, .is-running, .is-leaping)) .pasture__blades--still { opacity: 0; }
.pasture:has(.pasture__sheep:is(.is-walking, .is-trotting, .is-running, .is-leaping)) .pasture__blades--back { animation: sheep-stride var(--stride) steps(1) infinite; }
.pasture:has(.pasture__sheep:is(.is-walking, .is-trotting, .is-running, .is-leaping)) .pasture__blades--fore { animation: sheep-gather var(--stride) steps(1) infinite; }
.pasture:has(.pasture__sheep:is(.is-walking, .is-trotting, .is-running, .is-leaping)) .pasture__kick { opacity: 1; }

.pasture__kick-bit {
  opacity: 0;
  animation: grass-kick calc(var(--stride, 0.5s) * 2) steps(1) infinite paused;
}
.pasture__kick-bit:nth-child(2) { animation-delay: calc(var(--stride, 0.5s) * -0.5); }
.pasture__kick-bit:nth-child(3) { animation-delay: calc(var(--stride, 0.5s) * -1); }
.pasture__kick-bit:nth-child(4) { animation-delay: calc(var(--stride, 0.5s) * -1.5); }

.pasture:has(.pasture__sheep:is(.is-walking, .is-trotting, .is-running, .is-leaping)) .pasture__kick-bit {
  animation-play-state: running;
}

/* Flicked up and back off a hoof, then dropped behind the sheep. Backwards,
   because the field is running past it from right to left. */
@keyframes grass-kick {
  0%, 24% { transform: translate(0, 0); opacity: 1; }
  25%, 49% { transform: translate(-1px, -2px); opacity: 1; }
  50%, 74% { transform: translate(-3px, -3px); opacity: 1; }
  75%, 99% { transform: translate(-4px, -1px); opacity: 0.6; }
  100% { transform: translate(-5px, 0); opacity: 0; }
}

/* --- antics: what the sheep gets up to while the player thinks ------------ */
/*
 * The pasture controller sets data-antic on the sheep for a few seconds at a
 * time during a question. The gait animation keeps running on the outer box
 * (it owns the translateX that centres the sheep), so antics move the svg
 * inside it, or the parts drawn in the svg. Inside the svg, 1px is one pixel
 * of the sprite; on the svg itself it is a screen pixel, so those use --px.
 */
.pasture__sheep svg {
  overflow: visible;
  transform-origin: 50% 50%;
}

.pasture__antic { display: none; }
.pasture__sheep[data-antic] svg,
.pasture__sheep[data-antic] svg g { transform-box: fill-box; }

/* Graze: head down, and the tuft in front of it goes in three bites. */
.pasture__sheep[data-antic="graze"] .pasture__body--up { display: none; }
.pasture__sheep[data-antic="graze"] .pasture__body--down,
.pasture__sheep[data-antic="graze"] .pasture__tuft { display: inline; }
.pasture__sheep[data-antic="graze"] .pasture__tuft {
  transform-origin: 50% 100%;
  animation: antic-tuft 3.2s steps(1) forwards;
}
.pasture__sheep[data-antic="graze"] .pasture__body--down {
  animation: antic-chew 0.4s steps(1) infinite;
}

@keyframes antic-tuft {
  0%, 30% { transform: scaleY(1); }
  31%, 55% { transform: scaleY(0.67); }
  56%, 80% { transform: scaleY(0.34); }
  81%, 100% { transform: scaleY(0); }
}

@keyframes antic-chew {
  0%, 49% { transform: translateY(0); }
  50%, 100% { transform: translateY(0.25px); }
}

/* Glance back at the shepherd, then carry on. */
.pasture__sheep[data-antic="glance"] svg { animation: antic-glance 2.4s steps(1) forwards; }

@keyframes antic-glance {
  0%, 15% { transform: scaleX(1); }
  16%, 80% { transform: scaleX(-1); }
  81%, 100% { transform: scaleX(1); }
}

/* Baa: a bubble pops up over the head, and the head gives a little toss. */
.pasture__sheep[data-antic="bleat"] .pasture__bubble {
  display: inline;
  animation: antic-bubble 2s steps(1) forwards;
}
.pasture__sheep[data-antic="bleat"] svg { animation: antic-toss 2s steps(1) forwards; }

@keyframes antic-bubble {
  0%, 9% { opacity: 0; }
  10%, 85% { opacity: 1; }
  86%, 100% { opacity: 0; }
}

@keyframes antic-toss {
  0%, 9% { transform: translateY(0); }
  10%, 19% { transform: translateY(calc(-0.5 * var(--px))); }
  20%, 100% { transform: translateY(0); }
}

/* A wool shake, nose to tail, like coming out of the rain. */
.pasture__sheep[data-antic="shake"] svg { animation: antic-shake 1.2s steps(1) forwards; }

@keyframes antic-shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70% { transform: translateX(calc(-0.5 * var(--px))) rotate(-3deg); }
  20%, 40%, 60%, 80% { transform: translateX(calc(0.5 * var(--px))) rotate(3deg); }
  90% { transform: translateX(0); }
}

/* Pronk: two springy hops straight up, legs tucked, the way lambs do. */
.pasture__sheep:is([data-antic="pronk"], [data-antic="hop"]) svg { animation: antic-pronk 1.6s ease-in-out forwards; }
.pasture__sheep:is([data-antic="pronk"], [data-antic="hop"]) .pasture__legs--stride { animation: antic-legs-tuck-a 1.6s steps(1) forwards; }
.pasture__sheep:is([data-antic="pronk"], [data-antic="hop"]) .pasture__legs--gather { animation: antic-legs-tuck-b 1.6s steps(1) forwards; }

@keyframes antic-pronk {
  0%, 10%, 45%, 55%, 90%, 100% { transform: translateY(0); }
  27% { transform: translateY(calc(-4 * var(--px))); }
  72% { transform: translateY(calc(-3 * var(--px))); }
}

@keyframes antic-legs-tuck-a {
  0%, 11%, 44%, 56%, 89%, 100% { opacity: 1; }
  12%, 43%, 57%, 88% { opacity: 0; }
}

@keyframes antic-legs-tuck-b {
  0%, 11%, 44%, 56%, 89%, 100% { opacity: 0; }
  12%, 43%, 57%, 88% { opacity: 1; }
}

/* Roll: over onto its back, a good wriggle with the legs kicking at the sky,
   and on round the rest of the way back to its feet. Stepped so it turns like
   a sprite, not a vector. */
.pasture__sheep[data-antic="roll"] svg { animation: antic-roll 3.6s steps(1) forwards; }
.pasture__sheep[data-antic="roll"] .pasture__legs--stride { animation: sheep-stride 0.24s steps(1) infinite; }
.pasture__sheep[data-antic="roll"] .pasture__legs--gather { animation: sheep-gather 0.24s steps(1) infinite; }

@keyframes antic-roll {
  0%, 7% { transform: rotate(0deg); }
  8%, 13% { transform: translateY(calc(-0.5 * var(--px))) rotate(-45deg); }
  14%, 19% { transform: translateY(calc(-1 * var(--px))) rotate(-90deg); }
  20%, 25% { transform: translateY(calc(-0.5 * var(--px))) rotate(-135deg); }
  26%, 35% { transform: rotate(-180deg); }
  36%, 43% { transform: rotate(-172deg); }
  44%, 51% { transform: rotate(-188deg); }
  52%, 59% { transform: rotate(-172deg); }
  60%, 69% { transform: rotate(-180deg); }
  70%, 75% { transform: translateY(calc(-0.5 * var(--px))) rotate(-225deg); }
  76%, 81% { transform: translateY(calc(-1 * var(--px))) rotate(-270deg); }
  82%, 87% { transform: translateY(calc(-0.5 * var(--px))) rotate(-315deg); }
  88%, 100% { transform: rotate(-360deg); }
}

/* Nap: lies down, legs folded away, eyes shut, z's drifting up. */
.pasture__sheep[data-antic="nap"] .pasture__legs { visibility: hidden; }
.pasture__sheep[data-antic="nap"] .pasture__body--up { transform: translateY(3px); }
.pasture__sheep[data-antic="nap"] .pasture__eyelid,
.pasture__sheep[data-antic="nap"] .pasture__zzz { display: inline; }
.pasture__sheep[data-antic="nap"] .pasture__zzz { transform: translateY(3px); }
.pasture__sheep[data-antic="nap"] .pasture__z { opacity: 0; animation: antic-z 2s steps(4) infinite; }
.pasture__sheep[data-antic="nap"] .pasture__z--2 { animation-delay: 1s; }

@keyframes antic-z {
  0% { opacity: 0; transform: translate(0, 0); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translate(1px, -3px); }
}

/* --- pokes: what the sun and the sheep do when they're clicked ------------- */
/*
 * The pasture lets clicks fall through it everywhere except these, and the
 * stage above it lets them through everywhere except its cards, so the scene
 * can be clicked anywhere a card isn't. touch-action keeps a tap a tap on a
 * phone, with no double-tap zoom in the way.
 */
.stage { pointer-events: none; }
.stage > * { pointer-events: auto; }

.pasture__sun,
.pasture__sheep,
.pasture__ewe {
  pointer-events: auto;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* The sun dances: a hop and a sway from side to side, with a grin and its
   rays flashing on and off. Stepped, like everything else up there. */
.pasture__sun { overflow: visible; transform-origin: 50% 50%; }
.pasture__sun-face,
.pasture__sun-rays { display: none; }
.pasture__sun[data-dancing] { animation: sun-dance 2s steps(1) forwards; }
.pasture__sun[data-dancing] .pasture__sun-face { display: inline; }
.pasture__sun[data-dancing] .pasture__sun-rays { display: inline; animation: sun-rays 0.5s steps(1) infinite; }

@keyframes sun-dance {
  0%, 100% { transform: none; }
  8% { transform: translateY(calc(-1 * var(--px))) rotate(-15deg); }
  16% { transform: rotate(0deg); }
  24% { transform: translateY(calc(-1 * var(--px))) rotate(15deg); }
  32% { transform: rotate(0deg); }
  40% { transform: translateX(calc(-1 * var(--px))) rotate(-15deg); }
  48% { transform: translateX(calc(1 * var(--px))) rotate(15deg); }
  56% { transform: translateX(calc(-1 * var(--px))) rotate(-15deg); }
  64% { transform: translateX(calc(1 * var(--px))) rotate(15deg); }
  72% { transform: translateY(calc(-2 * var(--px))); }
  80% { transform: translateY(calc(-2 * var(--px))) rotate(45deg); }
  88% { transform: translateY(calc(-1 * var(--px))) rotate(90deg); }
  96% { transform: none; }
}

@keyframes sun-rays {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Belly up: over onto its back with its legs kicking at the sky, a wriggle
   while it waits for a rub, and back up onto its feet. Hop is the pronk. */
.pasture__sheep[data-antic="belly"] svg { animation: antic-belly 3.4s steps(1) forwards; }
.pasture__sheep[data-antic="belly"] .pasture__legs--stride { animation: sheep-stride 0.3s steps(1) infinite; }
.pasture__sheep[data-antic="belly"] .pasture__legs--gather { animation: sheep-gather 0.3s steps(1) infinite; }

@keyframes antic-belly {
  0%, 5% { transform: rotate(0deg); }
  6%, 11% { transform: translateY(calc(-0.5 * var(--px))) rotate(-90deg); }
  12%, 24% { transform: rotate(-180deg); }
  25%, 34% { transform: rotate(-172deg); }
  35%, 44% { transform: rotate(-188deg); }
  45%, 54% { transform: rotate(-172deg); }
  55%, 64% { transform: rotate(-188deg); }
  65%, 82% { transform: rotate(-180deg); }
  83%, 90% { transform: translateY(calc(-0.5 * var(--px))) rotate(-90deg); }
  91%, 100% { transform: rotate(0deg); }
}

/* The flock pokes. The ewe's own transform carries her wander and her sprite's
   carries which way she faces, so these use translate and rotate, which stack
   on top of both. */
.pasture__ewe[data-poke="hop"] .pasture__ewe-sprite { animation: ewe-hop 1.6s ease-in-out forwards; }
.pasture__ewe[data-poke="hop"] .pasture__legs--stride { animation: antic-legs-tuck-a 1.6s steps(1) forwards; }
.pasture__ewe[data-poke="hop"] .pasture__legs--gather { animation: antic-legs-tuck-b 1.6s steps(1) forwards; }

.pasture__ewe[data-poke="belly"] .pasture__ewe-sprite { transform-origin: 50% 50%; animation: ewe-belly 3.4s steps(1) forwards; }
.pasture__ewe[data-poke="belly"] .pasture__legs--stride { animation: sheep-stride 0.3s steps(1) infinite; }
.pasture__ewe[data-poke="belly"] .pasture__legs--gather { animation: sheep-gather 0.3s steps(1) infinite; }

@keyframes ewe-hop {
  0%, 10%, 45%, 55%, 90%, 100% { translate: 0 0; }
  27% { translate: 0 calc(-4 * var(--px)); }
  72% { translate: 0 calc(-3 * var(--px)); }
}

@keyframes ewe-belly {
  0%, 5% { rotate: 0deg; translate: 0 0; }
  6%, 11% { rotate: -90deg; translate: 0 calc(-0.5 * var(--px)); }
  12%, 24% { rotate: -180deg; translate: 0 0; }
  25%, 34% { rotate: -172deg; }
  35%, 44% { rotate: -188deg; }
  45%, 54% { rotate: -172deg; }
  55%, 64% { rotate: -188deg; }
  65%, 82% { rotate: -180deg; translate: 0 0; }
  83%, 90% { rotate: -90deg; translate: 0 calc(-0.5 * var(--px)); }
  91%, 100% { rotate: 0deg; translate: 0 0; }
}

/* A heart floats up off whichever sheep was poked: once for a hop, twice
   while one lies there waiting for its belly rub. */
.pasture__heart {
  position: absolute;
  width: calc(3 * var(--px));
  height: calc(3 * var(--px));
  opacity: 0;
  pointer-events: none;
}
.pasture__heart svg { display: block; width: 100%; height: 100%; }

.pasture > .pasture__heart {
  left: calc(var(--sheep-at) + 2 * var(--px));
  bottom: calc(var(--ground-line) + 11 * var(--px));
}
.pasture__ewe .pasture__heart {
  left: calc(50% - 1.5 * var(--px));
  bottom: 100%;
}

.pasture:has(.pasture__sheep[data-antic="hop"]) > .pasture__heart,
.pasture__ewe[data-poke="hop"] .pasture__heart { animation: heart-float 1.6s steps(8) forwards; }
.pasture:has(.pasture__sheep[data-antic="belly"]) > .pasture__heart,
.pasture__ewe[data-poke="belly"] .pasture__heart { animation: heart-float 1.7s steps(8) 2; }

@keyframes heart-float {
  0% { opacity: 0; transform: translateY(0); }
  15% { opacity: 1; }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translateY(calc(-3 * var(--px))); }
}

@keyframes heart-still {
  0%, 10% { opacity: 0; }
  11%, 85% { opacity: 1; }
  86%, 100% { opacity: 0; }
}

/* Scanlines. Decorative only. */
.pasture__scanlines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,0.10) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
  opacity: 0.5;
}

@media (prefers-contrast: more) { .pasture__scanlines { display: none; } }

/* Reduced motion: the camera jumps to the new distance instead of scrolling
   (handled in the controller), and the bobbing, the leap and the leg cycle stop. */
@media (prefers-reduced-motion: reduce) {
  .pasture__sheep,
  .pasture__sheep .pasture__legs { animation: none !important; }
  .pasture__legs--gather { opacity: 0; }

  /* No antics either; the controller never starts them, and this is the
     backstop if the setting changes mid-question. */
  .pasture__sheep svg,
  .pasture__sheep svg g { animation: none !important; transform: none !important; }
  .pasture__sheep .pasture__antic { display: none !important; }
  .pasture__sheep .pasture__body--up { display: inline !important; }
  .pasture__sheep .pasture__legs { visibility: visible !important; }

  /* The scene holds still: no drift, no sway, no grazing. The birds controller
     doesn't release any birds either. */
  .pasture__drift,
  .pasture__ears > g,
  .pasture__far-sheep > g,
  .pasture__far-shepherd { animation: none !important; }
  .pasture__ears--leaning,
  .pasture__far-sheep--down { opacity: 0; }

  /* The flock stays as drawn: no wandering, no chewing, no stride. */
  .pasture__ewe,
  .pasture__ewe g,
  .pasture__ewe-sprite { animation: none !important; transition: none !important; }

  /* A poke still gets an answer, just not a moving one: the sun puts on its
     grin and rays, and a heart shows over the sheep for a moment. */
  .pasture__sun { animation: none !important; }
  .pasture__sun-rays { animation: none !important; }
  .pasture__heart { animation-name: heart-still !important; }

  /* The shadow stays put and the grass stands still, whatever the gait. */
  .pasture__shadow svg,
  .pasture__blades,
  .pasture__kick-bit { animation: none !important; transform: none !important; }
  .pasture__blades--still { opacity: 1 !important; }
  .pasture__blades--back,
  .pasture__blades--fore,
  .pasture__kick { opacity: 0 !important; }
}

/* --- the stage: cards that sit on the pasture ----------------------------- */

.stage {
  position: relative;
  z-index: 1;
  display: block;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  /* Clear of the ground line, so a card never covers the sheep. */
  padding-bottom: calc(var(--ground-line) + 10rem);
}

.card {
  width: 100%;
  max-width: 32rem;
  text-align: center;
  animation: card-enter 320ms ease-out both;
}

.card--title { max-width: 36rem; }

@keyframes card-enter {
  from { opacity: 0; transform: translateY(0.75rem); }
  to { opacity: 1; transform: none; }
}

/* Pressing Start fades the title out while the pasture stays put. */
.card.is-leaving {
  animation: card-leave 260ms ease-in both;
  pointer-events: none;
}

@keyframes card-leave {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-0.5rem); }
}

@media (prefers-reduced-motion: reduce) {
  .card, .card.is-leaving { animation: none; }
  .card.is-leaving { opacity: 0; }
}

/* Anything a player has to read sits on its own plate: the pasture behind it
   is light sky in one place and dark grass in another, so the text cannot rely
   on the background for contrast. */
.card--round,
.card--reveal,
.card--results,
.card--credits,
.card--empty {
  padding: 1.5rem 1.4rem 1.75rem;
  text-align: left;
  background: rgba(22, 38, 26, 0.86);
  border: 2px solid rgba(247, 243, 234, 0.22);
  box-shadow: 0 8px 0 rgba(16, 30, 20, 0.35);
  color: #f3f7f0;
  backdrop-filter: blur(2px);
}

.card--results { text-align: center; }

.card--round .round__prompt,
.card--reveal .reveal__guess,
.card--empty .empty__title { color: #ffffff; }

.dock .round__input {
  background: rgba(10, 20, 12, 0.5);
  border-color: rgba(247, 243, 234, 0.3);
  color: #f7f3ea;
}

.dock .round__input::placeholder { color: rgba(243, 247, 240, 0.45); }

.dock .button--primary,
.card--results .button--primary {
  background: #f7f3ea;
  color: #1d3322;
}

.card--round .button--quiet {
  color: rgba(243, 247, 240, 0.75);
  border-color: rgba(247, 243, 234, 0.3);
}

.card--reveal .reveal__total,
.card--results .results__landmark { color: rgba(243, 247, 240, 0.8); }

.card--results .results__rows { border-color: rgba(247, 243, 234, 0.2); }
.card--results .results__row { border-color: rgba(247, 243, 234, 0.14); }
.card--results .results__row-prompt,
.card--results .results__row-cubits,
.card--results .results__unit,
.card--results .results__best { color: rgba(243, 247, 240, 0.7); }

.card--empty .empty__body,
.card--empty .empty__hint { color: rgba(243, 247, 240, 0.78); }
.card--empty .empty__hint code { background: rgba(10, 20, 12, 0.5); }

/* --- title card ----------------------------------------------------------- */

.card__wordmark-wrap { margin: 0; }

.wordmark {
  display: block;
  width: min(78vw, 32rem);
  margin: 0 auto;
  height: auto;
  /* CRT misregistration in screen pixels, so it stays a fringe at every size,
     plus a hard drop shadow — never a blur, which would soften pixel edges. */
  filter:
    drop-shadow(-2px 0 0 #ff5d73)
    drop-shadow(2px 0 0 #4fd8e8)
    drop-shadow(0 4px 0 rgba(20, 40, 25, 0.45));
}

.card__tagline {
  margin: 0.9rem 0 0;
  font-size: clamp(0.75rem, 2.6vw, 1rem);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  color: #eaf7ef;
  text-shadow: 0 2px 0 rgba(20, 40, 25, 0.5);
}

.card__rules {
  margin: 0.5rem auto 0;
  max-width: 26rem;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(0.68rem, 2.1vw, 0.85rem);
  letter-spacing: 0.08em;
  line-height: 1.7;
  color: #eef8f2;
  text-shadow: 0 1px 0 rgba(20, 40, 25, 0.7);
}

.card__rules span { white-space: nowrap; }

.start-button {
  margin-top: 1.8rem;
  display: inline-block;
  min-width: min(74vw, 22rem);
  padding: 1rem 2.5rem;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(1rem, 3.4vw, 1.4rem);
  font-weight: 700;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  text-decoration: none;
  color: #f7f3ea;
  background: #26402c;
  /* Blocky and offset — a rounded corner would be the one non-pixel edge. */
  border: 3px solid #f7f3ea;
  border-radius: 0;
  box-shadow: 0 5px 0 rgba(20, 40, 25, 0.55);
  cursor: pointer;
  transition: transform 90ms steps(2), box-shadow 90ms steps(2), background-color 90ms;
}

.start-button:hover { background: #32543a; }

.start-button:active {
  transform: translateY(4px);
  box-shadow: 0 1px 0 rgba(20, 40, 25, 0.55);
}

.start-button:focus-visible { outline: 3px solid #ffe08a; outline-offset: 3px; }

.card__meta {
  margin: 1.6rem 0 0;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: #f3faf5;
}

@media (prefers-reduced-motion: reduce) { .start-button { transition: none; } }

/* Sits over sky on a short screen and hillside on a tall one, so it carries its
   own plate rather than trusting whatever is behind it. Block, not inline-block:
   the Start button above it is an inline-block, and two of those share a line. */
.card__meta {
  display: block;
  width: fit-content;
  margin-inline: auto;
  padding: 0.3rem 0.75rem;
  background: rgba(20, 40, 25, 0.45);
}

/* --- round and reveal on the pasture: a card, and a dock below ---------- */

/* During a round the card rides at the top of the screen instead of the
   middle, leaving the sky and the sheep in view between question and answer.
   The reveal stays centred. */
.stage:has(.round) {
  align-items: flex-start;
  padding-bottom: calc(var(--dock-height) + 2rem);
}

.play-screen { width: 100%; max-width: 32rem; }

.dock {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 2;
  min-height: var(--dock-height);
  display: flex;
  align-items: center;
  padding: 0.9rem 1rem calc(0.9rem + env(safe-area-inset-bottom));
  background: rgba(16, 30, 20, 0.92);
  border-top: 2px solid rgba(247, 243, 234, 0.22);
  color: #f3f7f0;
}

.dock__inner {
  width: 100%;
  max-width: 40rem;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.round__answer { flex: 1; min-width: 0; }

/* Between prompts the dock holds one wide button where the answer bar was. */
.dock__button { flex: 1; padding-block: 0.85rem; }

/* A ring that empties clockwise, with the seconds in the middle. */
.round__clock {
  flex: none;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(closest-side, rgb(16, 30, 20) 78%, transparent 80%),
    conic-gradient(#f7f3ea var(--remaining, 100%), rgba(247, 243, 234, 0.18) 0);
}

.round__clock-count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 1.05rem;
  color: #f7f3ea;
}

.round__clock-bar {
  margin-top: 0.5rem;
  height: 0.3rem;
  border-radius: 999px;
  background: rgba(247, 243, 234, 0.18);
  position: relative;
  overflow: hidden;
}

.round__clock-bar::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--draining, 100%);
  background: #f7f3ea;
  transition: width 1s linear, background-color 0.3s ease;
}

.round.is-urgent .round__clock-bar::after { background: #e0664c; }
.round.is-urgent .round__clock {
  background:
    radial-gradient(closest-side, rgb(16, 30, 20) 78%, transparent 80%),
    conic-gradient(#e0664c var(--remaining, 100%), rgba(247, 243, 234, 0.18) 0);
}
.round.is-urgent .round__clock-count { color: #ffb4a3; }

@media (prefers-reduced-motion: reduce) {
  .round__clock-bar::after { width: var(--remaining, 100%); transition: none; }
}

/* --- results: flock curve, field log, rubric, logbook ----------------------- */

/* Brighter cousins of the tier colours, for marks drawn on the dark plate. */
.card--results {
  max-width: 36rem;
  --plate-none: #b9b1a1;
  --plate-common: #f3eedf;
  --plate-uncommon: #8fd18f;
  --plate-rare: #86b6ee;
  --plate-very-rare: #bfa2ea;
  --plate-the-one: #f2c55c;
  --plate-soft: rgba(243, 247, 240, 0.7);
  --plate-faint: rgba(243, 247, 240, 0.25);
}

.card--results .tier--none { --tier-mark: var(--plate-none); }
.card--results .tier--common { --tier-mark: var(--plate-common); }
.card--results .tier--uncommon { --tier-mark: var(--plate-uncommon); }
.card--results .tier--rare { --tier-mark: var(--plate-rare); }
.card--results .tier--very_rare { --tier-mark: var(--plate-very-rare); }
.card--results .tier--the_one { --tier-mark: var(--plate-the-one); }

.results__section { margin-top: 2rem; text-align: left; }

.results__heading {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0 0 0.75rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #f3f7f0;
}

.results__heading span { color: var(--plate-soft); font-weight: 400; }

.results__heading::after {
  content: "";
  flex: 1;
  border-top: 1px dashed var(--plate-faint);
  transform: translateY(-0.2em);
}

.flock__chart,
.field__chart { display: block; width: 100%; height: auto; overflow: visible; }

.flock__area { fill: rgba(143, 209, 143, 0.18); }
.flock__line { fill: none; stroke: var(--plate-uncommon); stroke-width: 2; stroke-linejoin: round; }
.flock__axis { stroke: var(--plate-faint); }
.flock__tick { fill: var(--plate-soft); font-size: 9px; font-variant-numeric: tabular-nums; }
.flock__you-stem { stroke: var(--plate-the-one); stroke-width: 2; }
.flock__you-dot { fill: var(--plate-the-one); }
.flock__you-label { fill: var(--plate-the-one); font-size: 9px; font-weight: 700; letter-spacing: 0.12em; }

.flock__verdict { margin: 0.6rem 0 0; font-size: 0.95rem; }
.flock__verdict strong { color: var(--plate-the-one); }
.flock__verdict span { color: var(--plate-soft); font-size: 0.85rem; }

.field__guide { stroke: var(--plate-faint); stroke-dasharray: 3 4; }
.field__guide-label { fill: var(--plate-soft); font-size: 8px; font-variant-numeric: tabular-nums; }
.field__ground { stroke: rgba(143, 209, 143, 0.6); stroke-width: 2; }
.field__stem { stroke: var(--tier-mark); stroke-width: 2; opacity: 0.7; }
.field__pip { fill: var(--tier-mark); stroke: rgba(16, 30, 20, 0.8); stroke-width: 1.5; }
.field__miss { fill: none; stroke: var(--plate-faint); stroke-width: 1.5; stroke-dasharray: 2 2; }
.field__index { fill: var(--plate-soft); font-size: 9px; }

.rubric { list-style: none; margin: 0; padding: 0; }

.rubric__row {
  display: grid;
  grid-template-columns: 1.6rem 4.6rem 1fr;
  gap: 0.5rem;
  align-items: baseline;
  padding: 0.55rem 0;
  border-top: 1px solid rgba(247, 243, 234, 0.12);
  font-size: 0.88rem;
  color: var(--plate-soft);
}

.rubric__row:first-child { border-top: 0; }
.rubric__range { color: var(--tier-mark); font-variant-numeric: tabular-nums; }
.rubric__text strong { color: var(--tier-mark); font-weight: 600; }
.rubric__row.is-earned { color: #ffffff; }
.rubric__row:not(.is-earned) { opacity: 0.6; }

.results__recap .results__rows { margin-top: 0; }
.results__row-verse {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.82rem;
  font-style: italic;
  line-height: 1.4;
  color: var(--plate-soft);
  quotes: "\201C" "\201D";
}
.results__row-verse mark {
  font-style: normal;
  font-weight: 600;
  color: inherit;
  background: rgba(240, 200, 90, 0.32);
  border-radius: 3px;
  padding: 0 0.15em;
}
.results__row-same { display: block; margin-top: 0.15rem; font-size: 0.8rem; color: var(--plate-soft); }
.results__row-same strong { color: var(--plate-uncommon); font-variant-numeric: tabular-nums; }

/* "Should this have counted?" under a guess that did not score. */
.results__report { display: block; margin-top: 0.15rem; font-size: 0.8rem; color: var(--plate-soft); }
.results__report-form { display: inline; }
.results__report-button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.logbook {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  margin: 0;
}

.logbook__stat dt {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--plate-soft);
}

.logbook__stat dd {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.4rem;
  font-variant-numeric: tabular-nums;
}

/* --- did you mean --------------------------------------------------------- */

/* Floats just above the dock, centred over the answer box. The dock is fixed,
   so it is the positioning parent; the panel never pushes the input around.
   Stepped corners instead of a radius, to match the pixel pasture. */
.round__suggestion {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.75rem);
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100vw - 2rem);
  padding: 0.85rem 1.6rem 0.9rem;
  text-align: center;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  background: rgb(16, 30, 20);
  box-shadow:
    inset 0 0 0 2px rgba(247, 243, 234, 0.22),
    0 6px 0 rgba(16, 30, 20, 0.45);
  clip-path: polygon(
    0 8px, 4px 8px, 4px 4px, 8px 4px, 8px 0,
    calc(100% - 8px) 0, calc(100% - 8px) 4px, calc(100% - 4px) 4px, calc(100% - 4px) 8px, 100% 8px,
    100% calc(100% - 8px), calc(100% - 4px) calc(100% - 8px), calc(100% - 4px) calc(100% - 4px),
    calc(100% - 8px) calc(100% - 4px), calc(100% - 8px) 100%,
    8px 100%, 8px calc(100% - 4px), 4px calc(100% - 4px), 4px calc(100% - 8px), 0 calc(100% - 8px)
  );
  animation: suggestion-in 160ms steps(3);
}

.round__suggestion-pair {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.2rem 0.75rem;
  font-size: clamp(1rem, 4vw, 1.35rem);
  font-weight: 700;
  letter-spacing: 0.06em;
}

.round__suggestion-typed { color: rgba(243, 247, 240, 0.55); }
.round__suggestion-arrow { color: #f3f7f0; }
.round__suggestion-name { color: #ffe08a; text-shadow: 0 2px 0 rgba(0, 0, 0, 0.35); }

.round__suggestion-hint {
  margin: 0.55rem 0 0;
  font-size: clamp(0.66rem, 2.4vw, 0.8rem);
  letter-spacing: 0.16em;
  color: rgba(243, 247, 240, 0.7);
}

@keyframes suggestion-in {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) { .round__suggestion { animation: none; } }

/* --- ad rails ------------------------------------------------------------- */
/*
 * A 160x600 banner either side of the field, each in its own gutter. On wide
 * screens the pasture, the cards and the dock all draw between the gutters, so
 * a banner never covers the sheep or the flock; the art itself is unchanged,
 * the field is just a little narrower. Below that width there are no rails and
 * no gutters. Ad-free players get neither (the rails are not rendered at all).
 */

.ad-rail { display: none; }

@media (min-width: 80rem) {
  body:has(> .ad-rail) {
    --rail-gutter: calc(160px + 2rem);
    background: #16261a;
  }

  body:has(> .ad-rail) .pasture { inset: 0 var(--rail-gutter); }
  body:has(> .ad-rail) .stage { margin-inline: var(--rail-gutter); }
  body:has(> .ad-rail) .dock { inset-inline: var(--rail-gutter); }
  body:has(> .ad-rail) .sound-toggle { left: calc(var(--rail-gutter) + 0.75rem); }

  .ad-rail {
    position: fixed;
    top: max(1rem, calc(50% - 300px));
    z-index: 1;
    display: block;
    width: 160px;
    height: 600px;
  }

  .ad-rail--left { left: 1rem; }
  .ad-rail--right { right: 1rem; }
}

.ad-rail__slot { display: block; width: 160px; height: 600px; }

.ad-rail__slot--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: rgba(247, 243, 234, 0.75);
  background: rgba(16, 30, 20, 0.35);
  border: 2px dashed rgba(247, 243, 234, 0.45);
}

/* --- sound toggle --------------------------------------------------------- */

.sound-toggle {
  position: fixed;
  top: calc(0.75rem + env(safe-area-inset-top));
  left: 0.75rem;
  z-index: 3;
  padding: 8px;
  line-height: 0;
  background: #26402c;
  border: 2px solid #f7f3ea;
  border-radius: 0;
  cursor: pointer;
}

.sound-toggle svg { width: 27px; height: 21px; }
.sound-toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.sound-toggle[aria-pressed="true"] .sound-toggle__off,
.sound-toggle[aria-pressed="false"] .sound-toggle__on { display: none; }

/* --- credits -------------------------------------------------------------- */

.credits__title { margin: 0 0 0.5rem; font-size: 1.5rem; color: #ffffff; }
.credits__heading {
  margin: 1.2rem 0 0.4rem;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(243, 247, 240, 0.75);
}
.credits__list { margin: 0; padding-left: 1.1rem; font-size: 0.92rem; }
.credits__list li + li { margin-top: 0.4rem; }
.card--credits a { color: #f6d58e; }
.credits__back { margin: 1.5rem 0 0; }

.credits-link {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(243, 250, 245, 0.85);
  text-shadow: 0 1px 0 rgba(20, 40, 25, 0.7);
}
.credits-link:hover { color: #ffffff; }
.card__credits { margin: 1rem 0 0; }
.card__credits .credits-link + .credits-link { margin-left: 1.25rem; }
