/* ---------- base ---------- */

* {
  box-sizing: border-box;
}

:root {
  /* Width of a scale-1 (front, newest) horse. Keyed off viewport height so the
     whole paddock shrinks to fit shorter screens rather than growing so tall it
     hides the buttons and donate text below it. Capped so it never gets huge. */
  --horse-unit: clamp(104px, 19vh, 196px);
}

body {
  margin: 0;
  font-family: "Avenir Next", "Segoe UI", system-ui, sans-serif;
  background: #faf6ee;
  color: #3d3428;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* A tap-happy game: rapid clicks were selecting popup/toast text (issue
     #37). Nothing here is prose worth selecting, so switch selection off
     globally and opt the few genuinely copyable things back in below. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* The bits a player genuinely copies or types into stay selectable: form
   fields, and the save code they carry to another device. */
input,
textarea,
#sc-code-value {
  user-select: text;
  -webkit-user-select: text;
}

/* ---------- top bar / HUD ---------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  max-width: 960px;
  width: 100%;
  margin: 0 auto;
  /* Lift the HUD above the paddock (which makes its own stacking context via
     translateZ) so the supporters "+N" pop, which drifts down out of the chip,
     lands in front of the paddock sky rather than behind it. */
  position: relative;
  z-index: 30;
}

.title-block h1 {
  margin: 0;
  font-size: 1.6rem;
  letter-spacing: 0.01em;
}

.tagline {
  margin: 0.1rem 0 0;
  font-size: 0.85rem;
  color: #8a7d68;
}

.hud {
  position: relative; /* anchors the .lang-menu dropdown below */
  display: flex;
  align-items: center;
  gap: 0.6rem;
  /* Wrap to a second line rather than running off the side on narrow screens
     (a full HUD is two chips plus four buttons). */
  flex-wrap: wrap;
  justify-content: flex-end;
}

.chip[hidden] {
  display: none;
}

.chip {
  position: relative; /* anchors the floating "+N" supporter pop */
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  font-size: 0.95rem;
}

.chip-icon {
  color: #b0823f;
  font-weight: 700;
}

.chip-value {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.chip-label {
  font-size: 0.75rem;
  color: #8a7d68;
}

/* Icon-only, like the other HUD buttons (residents/collection/sound) -- the
   full "Tack room" name would crowd the HUD, so it shows only once the shop
   is open (the modal's own title). The emoji still carries an accessible name
   via aria-label/title. */
.shop-btn {
  position: relative;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  color: #6b5c44;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 999px;
  width: 2.3rem;
  height: 2.3rem;
  cursor: pointer;
}

.shop-btn:hover {
  border-color: #d8c39a;
}

.shop-btn[hidden] {
  display: none;
}

.shop-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #6f8f4f;
  border: 1.5px solid #fffdf7;
}

.shop-badge[hidden] {
  display: none;
}

.album-btn {
  position: relative;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  color: #6b5c44;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 999px;
  width: 2.3rem;
  height: 2.3rem;
  cursor: pointer;
}

.album-btn:hover {
  border-color: #d8c39a;
}

.album-btn[hidden] {
  display: none;
}

/* Unread count bubble on the album button. */
.album-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #d9534f;
  color: #fff;
  font-size: 0.65rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
}

.album-badge[hidden] {
  display: none;
}

.sound-btn {
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  color: #6b5c44;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 999px;
  width: 2.3rem;
  height: 2.3rem;
  cursor: pointer;
}

.sound-btn:hover {
  border-color: #d8c39a;
}

/* Language menu (js/translate.js): a small dropdown under the 🌐 button,
   styled like the shop/album popovers rather than Google's own widget UI. */
.lang-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 6px 18px rgba(60, 45, 20, 0.12);
  min-width: 160px;
}
.lang-menu[hidden] {
  display: none;
}
.lang-menu button {
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
  color: #6b5c44;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
}
.lang-menu button:hover {
  background: #f3ead2;
}
.lang-menu button.is-active {
  font-weight: 700;
  color: #3d3428;
}

/* Google's Website Translator widget does real work (translating, and
   re-scanning the page as new toasts/dialogs appear) but its own banner/
   dropdown UI is never shown -- the .lang-menu above is the only control a
   player sees. */
/* Google obfuscates the banner iframe's own class name (it changes between
   widget versions), but always tags it -- and its other utility iframes --
   with "skiptranslate", so that's the stable hook to hide it by. */
#google_translate_element,
iframe.skiptranslate {
  display: none !important;
}
body {
  top: 0 !important; /* the widget sometimes nudges <body> down for its banner; undo it */
  position: static !important;
}

main {
  flex: 1;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 0 1.5rem 0.6rem;
  /* Centre the paddock + buttons in the leftover height so they drop down to
     use the gap that would otherwise sit above the footer. */
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The horizon is fixed in px (not %) so hooves land on grass no matter how
   tall the herd makes the paddock grow. */
.paddock {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid #e0d6bf;
  /* Reserved from the very first horse so the scene never visibly grows OR
     shrinks (issue #113). Sized to the tallest layout — a full-scale front-row
     horse (~3.12 horse-units of content) — so a shorter front row (e.g. when
     the newest arrival is a small foal) leaves a little extra sky rather than
     resizing the whole paddock. Derived from --horse-unit so it scales with the
     scene on shorter screens. */
  min-height: calc(var(--horse-unit) * 3.18);
  /* Split into separate layers instead of one gradient with stops 2px apart --
     Safari's rasterizer has known edge cases with near-zero-distance colour
     stops inside a single gradient, especially under border-radius clipping,
     causing an intermittent blank paint on reload. Three simple flat/2-colour
     layers avoid the tight-stop pattern entirely. */
  /* Horizon (grass line) scales with --horse-unit so the fence and the back
     horses standing on the grass stay in step as the scene shrinks. */
  background:
    linear-gradient(#a9c37f, #93b36c) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#e8f2e0, #e8f2e0) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #d9ecf8;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

/* The magical paddock — the free home of the gift horses (unicorn, rainbow,
   golden pegasus). Same scene layers as .paddock, recoloured to a soft dusk:
   violet sky, cooler enchanted grass. Toggled by render.js per view. */
.paddock.magic-paddock {
  border-color: #cbbcec;
  background:
    linear-gradient(#93b98c, #6fa07c) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#f0e7fb, #f0e7fb) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #e2d5f6;
}

/* Its fence turns magical too: lilac wood, golden rails. Same layered-gradient
   structure and metrics as .fence (including the proportional post spacing),
   colours swapped. */
.magic-paddock .fence {
  background:
    repeating-linear-gradient(90deg,
      #c3aae2 0 1.2037%,
      transparent 1.2037% 14.4444%),
    linear-gradient(#e0be74, #e0be74) 0 calc(var(--horse-unit) * 0.073) / 100% calc(var(--horse-unit) * 0.041) no-repeat,
    linear-gradient(#e0be74, #e0be74) 0 calc(var(--horse-unit) * 0.218) / 100% calc(var(--horse-unit) * 0.041) no-repeat;
}

/* Sparkles: two hand-scattered layers of tiny white/gold glints twinkling out
   of phase. They sit above the grass and ground props (z1) but behind the
   horse rows (z3), so the dust drifts through the scene without covering
   anyone's face. */
.paddock.magic-paddock::before,
.paddock.magic-paddock::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
}

.paddock.magic-paddock::before {
  background-image:
    radial-gradient(circle, rgba(255,255,255,.95) 0 1px, rgba(255,255,255,.4) 2px, transparent 4px),
    radial-gradient(circle, rgba(255,244,189,.95) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.9) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,244,189,.9) 0 1px, rgba(255,244,189,.35) 2px, transparent 4px),
    radial-gradient(circle, rgba(255,255,255,.9) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.85) 0 1px, transparent 3px);
  background-size: 12px 12px, 7px 7px, 6px 6px, 10px 10px, 7px 7px, 5px 5px;
  background-position: 9% 14%, 24% 7%, 41% 20%, 63% 9%, 81% 17%, 93% 32%;
  animation: magic-twinkle 2.6s ease-in-out infinite;
}

.paddock.magic-paddock::after {
  background-image:
    radial-gradient(circle, rgba(255,244,189,.95) 0 1px, rgba(255,244,189,.4) 2px, transparent 4px),
    radial-gradient(circle, rgba(255,255,255,.9) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.95) 0 1px, rgba(255,255,255,.35) 2px, transparent 4px),
    radial-gradient(circle, rgba(255,244,189,.9) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.85) 0 1px, transparent 3px),
    radial-gradient(circle, rgba(255,255,255,.9) 0 1px, transparent 3px);
  background-size: 11px 11px, 6px 6px, 12px 12px, 7px 7px, 5px 5px, 6px 6px;
  background-position: 16% 26%, 33% 12%, 52% 24%, 72% 30%, 87% 8%, 47% 55%;
  animation: magic-twinkle 3.4s ease-in-out 1.1s infinite;
}

@keyframes magic-twinkle {
  0%, 100% { opacity: .25; }
  50%      { opacity: 1; }
}

/* The sanctuary barn (issue #136) — the ladder's last and grandest purchase
   gets its own indoor scene rather than a fourth field: a golden wood-plank
   wall, a woven-hay floor, and a wide window looking out onto the green in
   place of sky, grass and a farm fence. A plain, undivided wall reads calmer
   than a row of stall doors -- this is a resting place, not a working
   paddock. Same 3-layer structure as the base .paddock (floor / trim line /
   wall), colours and materials swapped. */
.paddock.sanctuary-paddock {
  border-color: #a9762f;
  background:
    /* piles of straw scattered on the floor -- small wisps, unlit by anything
       fancier than a couple of overlapping ellipses per pile */
    radial-gradient(ellipse 16px 6px at 10% 91%, #f0d78c, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    radial-gradient(ellipse 11px 4px at 13% 93%, #e6c877, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    radial-gradient(ellipse 14px 5px at 34% 96%, #f0d78c, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    radial-gradient(ellipse 18px 6px at 63% 92%, #f0d78c, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    radial-gradient(ellipse 12px 4px at 66% 95%, #e6c877, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    radial-gradient(ellipse 15px 5px at 88% 94%, #f0d78c, transparent 72%) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    /* woven-hay floor: two faint crosshatch passes over the gold base */
    repeating-linear-gradient(35deg, rgba(139,98,42,.16) 0 2px, transparent 2px 9px) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    repeating-linear-gradient(-35deg, rgba(139,98,42,.16) 0 2px, transparent 2px 9px) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    linear-gradient(#d1a352, #b9862f) 0 calc(var(--horse-unit) * 1.10) / 100% 100% no-repeat,
    linear-gradient(#5a3d22, #5a3d22) 0 calc(var(--horse-unit) * 1.091) / 100% 3px no-repeat,
    /* wall: horizontal wood-plank courses, up to the (now taller) floor line */
    repeating-linear-gradient(180deg, rgba(90,61,34,.14) 0 2px, transparent 2px calc(var(--horse-unit) * 0.09)) 0 0 / 100% calc(var(--horse-unit) * 1.10) no-repeat,
    #e0b56a;
}

/* Its "fence" becomes a fixed stable facade: a plain plank wall with one wide
   window looking out onto the green paddock beyond, centred, with squarish
   panes rather than the tall narrow ones a straight width doubling would give.
   A fixed composition rather than an indefinitely-repeating tile. Stretched
   to fill the fence's width and height exactly (background-size 100% 100%),
   so the window holds its size and position at any paddock width rather than
   tiling. Sized to about a third of the whole scene (see the .fence override
   below), tall enough to read as a real building behind the horses rather
   than a low rail. */
.sanctuary-paddock .fence {
  top: calc(var(--horse-unit) * 0.04);
  height: calc(var(--horse-unit) * 1.06);
  /* The barn's fixed furniture (hay barrow and bales, issue #136) rides on
     this element too, listed before the facade so it paints in front of the
     wall. The fence's bottom edge IS the floor line (top 0.04 + height 1.06
     = the 1.10-horse-unit horizon), and the furniture is anchored bottom 0
     and sized in horse-units -- so it stands on the floor at every viewport,
     where the old width-scaled decor-SVG placement drifted up the wall on
     narrow (mobile) screens. */
  background:
    url("../assets/decor/barn-hay-barrow.png") left 7% bottom 0
      / auto calc(var(--horse-unit) * 0.38) no-repeat,
    url("../assets/decor/barn-hay-bales.png") right 5% bottom 0
      / auto calc(var(--horse-unit) * 0.52) no-repeat,
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27800%27%20height%3D%27300%27%3E%3Crect%20x%3D%27270%27%20y%3D%2718%27%20width%3D%27260%27%20height%3D%27282%27%20fill%3D%27%236b4a2f%27%2F%3E%3Crect%20x%3D%27286%27%20y%3D%2734%27%20width%3D%27228%27%20height%3D%27110%27%20fill%3D%27%23bcdff0%27%2F%3E%3Crect%20x%3D%27286%27%20y%3D%27164%27%20width%3D%27228%27%20height%3D%2790%27%20fill%3D%27%238bb35f%27%2F%3E%3Ccircle%20cx%3D%27400%27%20cy%3D%27205%27%20r%3D%2716%27%20fill%3D%27%236f9a54%27%2F%3E%3Crect%20x%3D%27397%27%20y%3D%27221%27%20width%3D%276%27%20height%3D%2720%27%20fill%3D%27%237a5a36%27%2F%3E%3Ccircle%20cx%3D%27440%27%20cy%3D%27210%27%20r%3D%2711%27%20fill%3D%27%237fae63%27%2F%3E%3Ccircle%20cx%3D%27368%27%20cy%3D%27212%27%20r%3D%279%27%20fill%3D%27%237fae63%27%2F%3E%3Crect%20x%3D%27286%27%20y%3D%27160%27%20width%3D%27228%27%20height%3D%274%27%20fill%3D%27%23e8f2e0%27%2F%3E%3Cline%20x1%3D%27400%27%20y1%3D%2734%27%20x2%3D%27400%27%20y2%3D%27254%27%20stroke%3D%27%236b4a2f%27%20stroke-width%3D%275%27%2F%3E%3Cline%20x1%3D%27286%27%20y1%3D%27144%27%20x2%3D%27514%27%20y2%3D%27144%27%20stroke%3D%27%236b4a2f%27%20stroke-width%3D%275%27%2F%3E%3Crect%20x%3D%27276%27%20y%3D%27254%27%20width%3D%27248%27%20height%3D%2710%27%20fill%3D%27%238a6238%27%2F%3E%3C%2Fsvg%3E")
      0 0 / 100% 100% no-repeat;
  opacity: 1;
}

/* Hanging lanterns -- small dark grey shapes with a warm pulsing glow beneath
   each, two either side of the window and evenly spread across the scene --
   plus a few wisps of hay dust catching the light. The barn's answer to
   weather, since none reaches indoors. Same layering as the magical sparkle
   (z2, behind the horses), stilled under reduced motion below. */
.paddock.sanctuary-paddock::before,
.paddock.sanctuary-paddock::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
}
.paddock.sanctuary-paddock::before {
  --lantern: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2728%27%20height%3D%2730%27%3E%3Cline%20x1%3D%2714%27%20y1%3D%270%27%20x2%3D%2714%27%20y2%3D%2712%27%20stroke%3D%27%233a3a3a%27%20stroke-width%3D%272%27%2F%3E%3Cpath%20d%3D%27M4%2012%20h20%20l-3%2014%20a7%207%200%200%201%20-14%200%20Z%27%20fill%3D%27%234a4a4a%27%2F%3E%3Cellipse%20cx%3D%2714%27%20cy%3D%2726%27%20rx%3D%275%27%20ry%3D%272.4%27%20fill%3D%27%23ffe6ab%27%2F%3E%3C%2Fsvg%3E");
  background:
    var(--lantern) 10% 0 / 28px 30px no-repeat,
    var(--lantern) 30% 0 / 28px 30px no-repeat,
    var(--lantern) 70% 0 / 28px 30px no-repeat,
    var(--lantern) 90% 0 / 28px 30px no-repeat,
    radial-gradient(38% 55% at 10% 8%, rgba(255, 214, 140, .55), transparent 72%),
    radial-gradient(38% 55% at 30% 8%, rgba(255, 214, 140, .55), transparent 72%),
    radial-gradient(38% 55% at 70% 8%, rgba(255, 214, 140, .55), transparent 72%),
    radial-gradient(38% 55% at 90% 8%, rgba(255, 214, 140, .55), transparent 72%);
  animation: barn-glow 4.5s ease-in-out infinite;
}
.paddock.sanctuary-paddock::after {
  background-image:
    radial-gradient(circle, rgba(227, 165, 66, .5) 0 2px, transparent 4px),
    radial-gradient(circle, rgba(227, 165, 66, .4) 0 1.5px, transparent 3px),
    radial-gradient(circle, rgba(227, 165, 66, .45) 0 2px, transparent 4px),
    radial-gradient(circle, rgba(227, 165, 66, .4) 0 1.5px, transparent 3px);
  background-size: 6px 6px, 4px 4px, 5px 5px, 4px 4px;
  background-position: 20% 22%, 38% 30%, 62% 20%, 78% 34%;
  animation: season-petal-drift 7s ease-in-out infinite;
}
@keyframes barn-glow {
  0%, 100% { opacity: .6; }
  50%      { opacity: 1; }
}

/* Built-in scenery for the named buildable paddocks (Meadow, Campo). Little
   flowers and butterflies painted right into the grass in CSS — like the decor
   items, but free and permanent, so each paddock lives up to its name. Tiny
   inline SVGs kept as reusable vars; they sit above the grass/props (z2) but
   behind the horse rows (z3), and never take pointer events. */
.paddock {
  --flower-pink:   url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='14'%20height='14'%3E%3Cg%20fill='%23E895B3'%3E%3Ccircle%20cx='7'%20cy='3'%20r='2.4'/%3E%3Ccircle%20cx='11'%20cy='6'%20r='2.4'/%3E%3Ccircle%20cx='9.4'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='4.6'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='3'%20cy='6'%20r='2.4'/%3E%3C/g%3E%3Ccircle%20cx='7'%20cy='7'%20r='2.3'%20fill='%23F7CD3A'/%3E%3C/svg%3E");
  --flower-white:  url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='14'%20height='14'%3E%3Cg%20fill='%23FBF7EE'%3E%3Ccircle%20cx='7'%20cy='3'%20r='2.4'/%3E%3Ccircle%20cx='11'%20cy='6'%20r='2.4'/%3E%3Ccircle%20cx='9.4'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='4.6'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='3'%20cy='6'%20r='2.4'/%3E%3C/g%3E%3Ccircle%20cx='7'%20cy='7'%20r='2.3'%20fill='%23F7CD3A'/%3E%3C/svg%3E");
  --flower-purple: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='14'%20height='14'%3E%3Cg%20fill='%23A971D6'%3E%3Ccircle%20cx='7'%20cy='3'%20r='2.4'/%3E%3Ccircle%20cx='11'%20cy='6'%20r='2.4'/%3E%3Ccircle%20cx='9.4'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='4.6'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='3'%20cy='6'%20r='2.4'/%3E%3C/g%3E%3Ccircle%20cx='7'%20cy='7'%20r='2.3'%20fill='%23F7CD3A'/%3E%3C/svg%3E");
  --flower-yellow: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='14'%20height='14'%3E%3Cg%20fill='%23F7CD3A'%3E%3Ccircle%20cx='7'%20cy='3'%20r='2.4'/%3E%3Ccircle%20cx='11'%20cy='6'%20r='2.4'/%3E%3Ccircle%20cx='9.4'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='4.6'%20cy='10.5'%20r='2.4'/%3E%3Ccircle%20cx='3'%20cy='6'%20r='2.4'/%3E%3C/g%3E%3Ccircle%20cx='7'%20cy='7'%20r='2.3'%20fill='%23E0A81E'/%3E%3C/svg%3E");
  --flower-poppy:  url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='13'%20height='13'%3E%3Cg%20fill='%23E24B4A'%3E%3Ccircle%20cx='6.5'%20cy='2.8'%20r='2.4'/%3E%3Ccircle%20cx='10.2'%20cy='5.6'%20r='2.4'/%3E%3Ccircle%20cx='8.8'%20cy='9.8'%20r='2.4'/%3E%3Ccircle%20cx='4.2'%20cy='9.8'%20r='2.4'/%3E%3Ccircle%20cx='2.8'%20cy='5.6'%20r='2.4'/%3E%3C/g%3E%3Ccircle%20cx='6.5'%20cy='6.4'%20r='1.9'%20fill='%234A1B0C'/%3E%3C/svg%3E");
  --butterfly-violet: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='14'%3E%3Cg%20fill='%23A971D6'%3E%3Cellipse%20cx='4.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='11.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='5'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3Cellipse%20cx='11'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3C/g%3E%3Crect%20x='7.5'%20y='2'%20width='1'%20height='10'%20rx='0.5'%20fill='%233d3428'/%3E%3C/svg%3E");
  --butterfly-pink: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='14'%3E%3Cg%20fill='%23D4537E'%3E%3Cellipse%20cx='4.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='11.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='5'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3Cellipse%20cx='11'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3C/g%3E%3Crect%20x='7.5'%20y='2'%20width='1'%20height='10'%20rx='0.5'%20fill='%233d3428'/%3E%3C/svg%3E");
  --butterfly-amber: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='14'%3E%3Cg%20fill='%23EF9F27'%3E%3Cellipse%20cx='4.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='11.5'%20cy='4.8'%20rx='3.6'%20ry='3.1'/%3E%3Cellipse%20cx='5'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3Cellipse%20cx='11'%20cy='9.6'%20rx='2.9'%20ry='3'/%3E%3C/g%3E%3Crect%20x='7.5'%20y='2'%20width='1'%20height='10'%20rx='0.5'%20fill='%234a2b0c'/%3E%3C/svg%3E");
}

/* Meadow paddock: a fresh, lush green with a light scatter of wildflowers and
   a couple of fluttering butterflies. */
.paddock.meadow-paddock {
  background:
    linear-gradient(#a4c775, #8bb35f) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#eef5e6, #eef5e6) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #d9ecf8;
}

.paddock.meadow-paddock::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    var(--flower-pink), var(--flower-white), var(--flower-yellow),
    var(--flower-purple), var(--flower-pink), var(--flower-white),
    var(--flower-yellow), var(--flower-purple);
  background-size:
    13px 13px, 11px 11px, 12px 12px, 12px 12px, 10px 10px, 13px 13px, 9px 9px, 10px 10px;
  background-position:
    7% 74%, 19% 90%, 31% 68%, 44% 88%, 57% 73%, 69% 92%, 82% 70%, 92% 86%;
}

.paddock.meadow-paddock::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image: var(--butterfly-violet), var(--butterfly-pink);
  background-size: 16px 14px, 14px 12px;
  background-position: 26% 56%, 73% 50%;
  animation: paddock-flutter 5s ease-in-out infinite;
}

/* Campo paddock: the sun-baked Andalusian countryside — warmer, golden grass
   dotted with red poppies and a few dry wildflowers. */
.paddock.campo-paddock {
  background:
    linear-gradient(#bcc079, #a3a95e) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#f3f0dd, #f3f0dd) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #dbeaf3;
}

.paddock.campo-paddock::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    var(--flower-poppy), var(--flower-yellow), var(--flower-poppy),
    var(--flower-white), var(--flower-poppy), var(--flower-yellow),
    var(--flower-poppy);
  background-size:
    12px 12px, 10px 10px, 11px 11px, 9px 9px, 13px 13px, 9px 9px, 10px 10px;
  background-position:
    9% 76%, 22% 91%, 35% 71%, 49% 89%, 63% 74%, 78% 92%, 90% 78%;
}

.paddock.campo-paddock::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image: var(--butterfly-amber);
  background-size: 15px 13px;
  background-position: 66% 54%;
  animation: paddock-flutter 6s ease-in-out infinite;
}

/* A gentle bob for the built-in butterflies. Kept tiny so it reads as a
   flutter, not a distraction, and stilled for reduced-motion below. */
@keyframes paddock-flutter {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}

/* ---- Seasons (issue #48) ------------------------------------------------- *
 * A game-time year (seasons.js) washes a seasonal weather layer over any real
 * paddock, stacking on the Meadow/Campo scatter. The tint rides on the
 * .paddock-weather overlay (behind the horses) so it never replaces a paddock's
 * own grass; the scatter (petals/glints/leaves/snow) is painted in CSS off two
 * pseudo-element layers, kept sparse and to the upper scene so no horse's face
 * is covered. Tiny inline SVGs, like the flowers above. */
.paddock {
  --petal-pink:  url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='11'%3E%3Cellipse%20cx='5'%20cy='5.5'%20rx='2.2'%20ry='3.8'%20fill='%23F0A8C4'%20transform='rotate(35%205%205.5)'/%3E%3C/svg%3E");
  --petal-white: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='11'%3E%3Cellipse%20cx='5'%20cy='5.5'%20rx='2'%20ry='3.5'%20fill='%23FBEFF3'%20transform='rotate(-22%205%205.5)'/%3E%3C/svg%3E");
  /* Real little maple leaves in three autumn colours (issue #48), kept very
     small so they read as leaves rather than blobs. Each colour comes in three
     baked-in rotations so the scatter points every which way (CSS can't rotate
     individual background layers). They replace the earlier inline-SVG
     silhouettes for the falling scatter and the settled leaves. */
  --leaf-o1: url('../assets/decor/leaf-orange-1.png');
  --leaf-o2: url('../assets/decor/leaf-orange-2.png');
  --leaf-o3: url('../assets/decor/leaf-orange-3.png');
  --leaf-r1: url('../assets/decor/leaf-red-1.png');
  --leaf-r2: url('../assets/decor/leaf-red-2.png');
  --leaf-r3: url('../assets/decor/leaf-red-3.png');
  --leaf-y1: url('../assets/decor/leaf-yellow-1.png');
  --leaf-y2: url('../assets/decor/leaf-yellow-2.png');
  --leaf-y3: url('../assets/decor/leaf-yellow-3.png');
  /* Rain: longer, slanted, clearly falling streaks. */
  --raindrop:    url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='7'%20height='18'%3E%3Cline%20x1='5'%20y1='1'%20x2='1.5'%20y2='16'%20stroke='%237BA0C8'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-opacity='0.85'/%3E%3C/svg%3E");
  /* A shallow puddle catching the grey sky, so winter reads as wet. */
  --puddle:      url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='42'%20height='15'%3E%3Cellipse%20cx='21'%20cy='9'%20rx='20'%20ry='5'%20fill='%239DB7D6'%20fill-opacity='0.55'/%3E%3Cellipse%20cx='19'%20cy='7.5'%20rx='12'%20ry='2.6'%20fill='%23CBDCEE'%20fill-opacity='0.6'/%3E%3C/svg%3E");
}

/* Seasonal grass: every real paddock lives the Mediterranean year together —
   parched golden through the dry summer, greening again for the wet autumn and
   winter. Spring is deliberately absent: it's the standard state, so Home,
   Meadow and Campo each show their own base grass then (the built-in flower
   scatter still tells them apart in the other seasons too). Applied to all
   non-magical paddocks; these rules follow Meadow/Campo in the source so they
   win at equal specificity. The magical paddock never gets a season class, so
   it stays magical year-round. Same layered structure as the base .paddock
   (grass / horizon line / sky), colours swapped. */
.paddock.season-summer:not(.magic-paddock) {
  background:
    linear-gradient(#ddc978, #c3ab5a) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#f6f0d3, #f6f0d3) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #dcebef;
}
.paddock.season-autumn:not(.magic-paddock) {
  background:
    linear-gradient(#aabf65, #8ba851) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#eef4da, #eef4da) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #d9ecf8;
}
.paddock.season-winter:not(.magic-paddock) {
  background:
    linear-gradient(#83ac65, #6d9853) 0 calc(var(--horse-unit) * 0.545) / 100% 100% no-repeat,
    linear-gradient(#e4efda, #e4efda) 0 calc(var(--horse-unit) * 0.536) / 100% 2px no-repeat,
    #cfdae1;
}

/* Base overlay: full scene, behind the horses (z2), inert. Present on every
   non-magical paddock; the season class supplies the tint and scatter. */
.paddock-weather {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.paddock-weather::before,
.paddock-weather::after {
  content: '';
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  opacity: .8;
}

/* Spring — blossom drifting on the breeze, over a soft rose-green wash. */
.paddock.season-spring .paddock-weather {
  background: radial-gradient(130% 90% at 50% 0%, rgba(240,168,196,.14), transparent 62%);
}
.paddock.season-spring .paddock-weather::before {
  background-image:
    var(--petal-pink), var(--petal-white), var(--petal-pink), var(--petal-white),
    var(--petal-pink), var(--petal-white), var(--petal-pink), var(--petal-white),
    var(--petal-pink), var(--petal-white),
    var(--petal-pink), var(--petal-white);
  background-size:
    10px 11px, 9px 10px, 8px 9px, 10px 11px,
    9px 10px, 8px 9px, 10px 11px, 9px 10px,
    8px 9px, 10px 11px,
    9px 10px, 8px 9px;
  background-position:
    6% 10%, 18% 22%, 30% 8%, 42% 26%,
    54% 14%, 66% 24%, 78% 10%, 90% 20%,
    15% 38%, 75% 34%,
    5% 70%, 93% 66%;
  animation: season-petal-drift 6s ease-in-out infinite;
}
.paddock.season-spring .paddock-weather::after {
  background-image:
    var(--petal-white), var(--petal-pink), var(--petal-white), var(--petal-pink),
    var(--petal-white), var(--petal-pink), var(--petal-white), var(--petal-pink),
    var(--petal-white), var(--petal-pink);
  background-size:
    9px 10px, 8px 9px, 9px 10px, 8px 9px,
    10px 11px, 9px 10px, 8px 9px, 10px 11px,
    9px 10px, 8px 9px;
  background-position:
    12% 34%, 24% 42%, 36% 30%, 48% 44%,
    60% 32%, 72% 40%, 84% 28%, 95% 40%,
    9% 80%, 89% 78%;
  animation: season-petal-drift-alt 7.5s ease-in-out .8s infinite;
}

/* Summer — warm sun-glints twinkling in a golden haze. */
.paddock.season-summer .paddock-weather {
  background: radial-gradient(130% 90% at 50% 0%, rgba(255,214,120,.16), transparent 60%);
}
.paddock.season-summer .paddock-weather::before {
  background-image:
    radial-gradient(circle, rgba(255,244,196,.95) 0 1.4px, transparent 3px),
    radial-gradient(circle, rgba(255,236,170,.9) 0 1.2px, transparent 3px),
    radial-gradient(circle, rgba(255,248,214,.95) 0 1.4px, transparent 3px),
    radial-gradient(circle, rgba(255,236,170,.9) 0 1.2px, transparent 3px);
  background-size: 9px 9px, 7px 7px, 8px 8px, 6px 6px;
  background-position: 14% 15%, 37% 24%, 61% 13%, 86% 22%;
  animation: season-shimmer 3s ease-in-out infinite;
}
.paddock.season-summer .paddock-weather::after {
  background-image:
    radial-gradient(circle, rgba(255,248,214,.9) 0 1.3px, transparent 3px),
    radial-gradient(circle, rgba(255,236,170,.85) 0 1.1px, transparent 3px),
    radial-gradient(circle, rgba(255,244,196,.9) 0 1.3px, transparent 3px);
  background-size: 8px 8px, 6px 6px, 7px 7px;
  background-position: 25% 33%, 68% 38%, 92% 30%;
  animation: season-shimmer 3.8s ease-in-out 1.1s infinite;
}

/* Autumn — orange, red and yellow leaves turning down over an amber wash, with
   four proper piles of fallen leaves raked up along the bottom of the grass
   (each pile built from three overlapping leaves so it reads as a heap, not a
   single stray leaf) -- painted on the base layer, so both pseudo-layers stay
   free for falling leaves. */
.paddock.season-autumn .paddock-weather {
  background:
    radial-gradient(130% 90% at 50% 0%, rgba(214,140,60,.15), transparent 62%),
    var(--leaf-o1), var(--leaf-r2), var(--leaf-y3),
    var(--leaf-r1), var(--leaf-y2), var(--leaf-o3),
    var(--leaf-y1), var(--leaf-o2), var(--leaf-r3),
    var(--leaf-o1), var(--leaf-r1), var(--leaf-y1);
  background-repeat: no-repeat;
  background-size:
    auto, 20px 20px, 23px 23px, 17px 17px,
    21px 21px, 24px 24px, 18px 18px,
    19px 19px, 22px 22px, 16px 16px,
    20px 20px, 23px 23px, 17px 17px;
  background-position:
    0 0, 9% 98%, 14% 100%, 12% 97%,
    28% 99%, 34% 100%, 31% 97%,
    59% 99%, 65% 100%, 62% 97%,
    83% 98%, 89% 100%, 86% 97%;
}
.paddock.season-autumn .paddock-weather::before {
  background-image: var(--leaf-o1), var(--leaf-r2), var(--leaf-y1), var(--leaf-o3), var(--leaf-r1), var(--leaf-y2), var(--leaf-o2), var(--leaf-r3);
  background-size: 20px 20px, 19px 19px, 18px 18px, 21px 21px, 19px 19px, 18px 18px, 20px 20px, 19px 19px;
  background-position: 8% 12%, 22% 20%, 34% 8%, 47% 26%, 60% 13%, 72% 23%, 85% 10%, 95% 29%;
  animation: season-drift 6.5s ease-in-out infinite;
}
.paddock.season-autumn .paddock-weather::after {
  background-image: var(--leaf-r3), var(--leaf-y2), var(--leaf-o1), var(--leaf-y3), var(--leaf-r1), var(--leaf-o2);
  background-size: 18px 18px, 19px 19px, 18px 18px, 19px 19px, 18px 18px, 19px 19px;
  background-position: 14% 34%, 29% 44%, 44% 40%, 58% 46%, 78% 44%, 90% 36%;
  animation: season-drift 8s ease-in-out .9s infinite;
}

/* Winter — a mild, wet Andalusian winter: a cool grey-blue wash (no snow at
   this elevation, the pasture stays green) with puddles pooled along the
   bottom. The rain streaks read poorly against the grass, so it's the puddles
   that carry the "wet" — one broad and wide, a couple smaller. */
.paddock.season-winter .paddock-weather {
  background:
    radial-gradient(130% 95% at 50% 0%, rgba(150,178,208,.22), transparent 64%),
    var(--puddle), var(--puddle), var(--puddle);
  background-repeat: no-repeat;
  background-size: auto, 78px 22px, 34px 13px, 40px 15px;
  background-position: 0 0, 22% 98%, 60% 99%, 87% 96%;
}

/* Nothing blooms in winter: the Meadow's wildflowers and butterflies and the
   Campo's poppies (their built-in ::before/::after scatter) are hidden while
   the season is winter. Higher specificity than the base scatter, so it wins. */
.paddock.season-winter.meadow-paddock::before,
.paddock.season-winter.meadow-paddock::after,
.paddock.season-winter.campo-paddock::before,
.paddock.season-winter.campo-paddock::after {
  display: none;
}

/* A slow vertical drift for the falling scatter, and a soft twinkle for the
   summer glints. Both tiny, and stilled for reduced-motion below. */
@keyframes season-drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(7px); }
}
/* Spring's blossom drifts on an actual breeze rather than just bobbing
   straight down: a touch of sideways sway alongside the fall. The two petal
   layers (::before/::after) use opposite sway directions, on top of their
   already-different durations/delays, so the whole scatter reads as loosely
   floating rather than one rigid block moving in lockstep. */
@keyframes season-petal-drift {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(4px, 9px); }
}
@keyframes season-petal-drift-alt {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(-5px, 7px); }
}
@keyframes season-shimmer {
  0%, 100% { opacity: .35; }
  50%      { opacity: .9; }
}

/* Respect a reduced-motion preference: still the ambient paddock animations
   (the butterfly flutter, the magical sparkle, the seasonal weather) without
   hiding anything. */
@media (prefers-reduced-motion: reduce) {
  .paddock.meadow-paddock::after,
  .paddock.campo-paddock::after,
  .paddock.magic-paddock::before,
  .paddock.magic-paddock::after,
  .paddock.sanctuary-paddock::before,
  .paddock.sanctuary-paddock::after,
  .paddock-weather::before,
  .paddock-weather::after {
    animation: none;
  }
}

/* fence: posts + two rails, drawn with layered gradients so it tiles at any
   width. Vertical metrics scale with --horse-unit (ratios from the original
   60/78/16/48px design at a 220px unit) so it shrinks with the horses. Post
   spacing is a fraction of the fence's own (=paddock's) width rather than a
   fixed pixel repeat, so it always lands on the same 130-of-900 cadence the
   fence-line decor (bunting/garland, render.js) draws its posts-to-posts
   swags in -- a fixed-px repeat drifts in and out of sync with that as the
   paddock resizes, which is what made bunting look strung in the wrong
   places (issue #123 follow-up). 14.4444% = 130/900, 1.2037% keeps the post
   the same fraction of its cell as the original 10px-of-120px design. */
.fence {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--horse-unit) * 0.273);
  height: calc(var(--horse-unit) * 0.355);
  background:
    /* posts */
    repeating-linear-gradient(90deg,
      #c7a97e 0 1.2037%,
      transparent 1.2037% 14.4444%),
    /* upper rail */
    linear-gradient(#bd9d70, #bd9d70) 0 calc(var(--horse-unit) * 0.073) / 100% calc(var(--horse-unit) * 0.041) no-repeat,
    /* lower rail */
    linear-gradient(#bd9d70, #bd9d70) 0 calc(var(--horse-unit) * 0.218) / 100% calc(var(--horse-unit) * 0.041) no-repeat;
  opacity: 0.9;
}

/* Paddock decor overlay: purchased scene items, drawn behind the horses
   (DOM order, not z-index -- same trick as .fence). Scales uniformly with
   the paddock's width so hand-placed item coordinates never distort. */
.paddock-decor {
  position: absolute;
  left: 0;
  top: calc(var(--horse-unit) * 0.19);
  width: 100%;
  height: auto;
}

.horses {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: calc(var(--horse-unit) * 2.55);
  /* top padding (responsive, like the fence) drops the back row onto the grass
     just below the fence rather than up on the rails. Kept in sync with
     .paddock-decor's own top offset just above, and tuned so the back row's
     shorter-postured coats (donkeys, several rare coats -- their source art
     carries more transparent headroom above the head than the common horses)
     still reach roughly neck-height with the fence (issue #123), rather than
     only the tallest-postured coats getting there. */
  padding: calc(var(--horse-unit) * 0.19) 1.25rem 1rem;
}

/* Stacking inside the paddock: ground props sit lowest, and the horse rows sit
   in front of everything. */
.ground-decor {
  position: relative;
  z-index: 1;
}

.horses-back,
.horses-front {
  position: relative;
  z-index: 3;
}

/* Reserve the back row's height even while it's empty, so the front horses
   keep a fixed position: the first horse to reach the back row must never
   shove the whole paddock downward. Sized to one back-row card (scale 0.48). */
.horses-back {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  min-height: calc(var(--horse-unit) * 0.56);
}

.horses-front {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 12px;
}

/* Ground props (trough, buckets, bales, balls) sit in the gap between the two
   rows. Height keys off --horse-unit (not the paddock width) so the band stays
   compact and shrinks with the rest of the scene on short screens. */
.ground-decor {
  width: 100%;
  height: calc(var(--horse-unit) * 0.62);
  margin: 2px 0;
}

.ground-decor svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* background horses: keep their cards quiet — just name and bar */
.horse.is-back .horse-sponsor,
.horse.is-back .horse-condition {
  display: none;
}

/* ---------- horse card ---------- */

.horse {
  position: relative;
  width: min(260px, 70vw);
  text-align: center;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* Safari treats the image/SVG as draggable/selectable even with the parent's
   user-select:none -- cover them directly. */
.horse-img,
.horse-costume {
  -webkit-user-select: none;
  -webkit-user-drag: none;
  user-select: none;
}

.horse:focus-visible {
  outline: 3px solid #b0823f;
  outline-offset: 4px;
  border-radius: 12px;
}

/* Invisible spacer card that keeps an empty paddock at full height (#44). */
.horse.horse-ghost {
  visibility: hidden;
  pointer-events: none;
}

.horse.just-cared .horse-img,
.horse.just-cared .horse-costume {
  animation: care-bounce 0.25s ease;
}

@keyframes care-bounce {
  40% { transform: scale(1.04) translateY(-3px); }
}

.care-pop {
  position: absolute;
  transform: translate(-50%, -100%) rotate(var(--tilt, 0deg));
  background: #fffdf7;
  border: 1.5px solid #e6dcc6;
  border-radius: 999px;
  padding: 0.2rem 0.65rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: #5c5344;
  white-space: nowrap;
  pointer-events: none;
  animation: care-pop-float 1.4s ease-out forwards;
}

/* pastel variants, picked at random per click */
.care-pop.c0 { background: #ffe8cc; border-color: #f4c98a; color: #8a5a1f; }
.care-pop.c1 { background: #e4f2d4; border-color: #b7d89a; color: #4e6e2f; }
.care-pop.c2 { background: #fde2e4; border-color: #f5b8bd; color: #96434d; }
.care-pop.c3 { background: #e0eef9; border-color: #a9cbe8; color: #33617f; }
.care-pop.c4 { background: #f3e8ff; border-color: #d3b8f0; color: #6b4694; }

@keyframes care-pop-float {
  0%   { opacity: 0; translate: 0 6px; }
  12%  { opacity: 1; }
  65%  { opacity: 1; }
  100% { opacity: 0; translate: 0 -36px; }
}

/* Crit: a care click that lands especially well. Larger and gold, with a pop of
   scale and a higher float so it clearly outshines an everyday care pop. */
.care-pop.crit {
  background: linear-gradient(#fff4cc, #ffe39a);
  border-color: #eab945;
  color: #8a5a1f;
  font-size: 1.02rem;
  padding: 0.28rem 0.8rem;
  box-shadow: 0 2px 10px rgba(224, 168, 30, 0.35);
  animation: care-pop-crit 1.5s ease-out forwards;
}

/* Spontaneous tip: money-coloured (matches the share money-pop) so it reads as
   cash even mid-paddock, and shares the crit's livelier float. */
.care-pop.tip {
  background: #e4f2d4;
  border-color: #b7d89a;
  color: #4e6e2f;
  font-weight: 700;
  animation: care-pop-crit 1.5s ease-out forwards;
}

@keyframes care-pop-crit {
  0%   { opacity: 0; translate: 0 8px; scale: 0.7; }
  13%  { opacity: 1; scale: 1.12; }
  24%  { scale: 1; }
  65%  { opacity: 1; }
  100% { opacity: 0; translate: 0 -50px; }
}

/* Little-needs thought bubble: floats above the horse, gently bobbing, showing
   what it fancies. Purely an indicator (pointer-events off) so a tap goes
   straight to the horse card and tends the want. */
.want-bubble {
  position: absolute;
  top: -6px;
  left: 50%;
  background: #fffdf7;
  border: 1.5px solid #e6dcc6;
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
  font-size: 1.15rem;
  line-height: 1;
  box-shadow: 0 2px 8px rgba(61, 52, 40, 0.18);
  pointer-events: none;
  z-index: 5;
  animation: want-bob 1.8s ease-in-out infinite;
}

@keyframes want-bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, -4px); }
}

/* Camera flash on tending a "take a photo" want. */
.photo-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  border-radius: 12px;
  pointer-events: none;
  opacity: 0;
  z-index: 6;
  animation: photo-flash 0.5s ease-out forwards;
}

@keyframes photo-flash {
  0%   { opacity: 0; }
  12%  { opacity: 0.85; }
  100% { opacity: 0; }
}

/* The horse figure: image + costume overlay share one box (500x480 art
   canvas), with a soft ground shadow behind. Jitter/facing transforms are
   applied to .horse-figure so image and costume move together. */
.horse-figure {
  position: relative;
  /* Slightly narrower than the card so the enlarged name/status text can grow
     into the freed height without making the card -- and paddock -- any taller. */
  width: 84%;
  margin: 0 auto;
  aspect-ratio: 500 / 480;
}

.horse-img,
.horse-costume {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Rare and unicorn coats get a soft, gently pulsing shimmer behind them (the
   ::before paints before the image, so it sits behind the horse) to mark them
   as special without touching the art itself. */
.horse.is-shiny .horse-figure::before {
  content: '';
  position: absolute;
  inset: -12% -6% -4%;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 45%,
    rgba(255, 241, 176, 0.6), rgba(255, 241, 176, 0) 62%);
  animation: shiny-pulse 2.8s ease-in-out infinite;
  pointer-events: none;
}

@keyframes shiny-pulse {
  0%, 100% { opacity: 0.4; transform: scale(0.96); }
  50%      { opacity: 0.85; transform: scale(1.05); }
}

.horse-costume {
  pointer-events: none;
}

/* Soft oval shadow under the hooves (art baseline ~8px from the bottom). */
.horse-shadow {
  position: absolute;
  left: 50%;
  bottom: 1.6%;
  transform: translateX(-50%);
  width: 60%;
  height: 4%;
  background: rgba(55, 75, 30, 0.16);
  border-radius: 50%;
}

/* Card text and bar use em so they scale with the card's font-size,
   which renderPaddock sets per depth rank. Names are bigger now that the
   personality trait line is gone. */
/* Every text line below the horse has a FIXED height (not min-height), so no
   status change, sponsor reveal, or line-metric quirk can ever change the
   card's height -- and therefore the paddock's. */
.horse-name {
  margin: 0.35em 0 0.25em;
  font-weight: 700;
  font-size: 1.35em;
  line-height: 1.2;
  height: 1.2em;
  white-space: nowrap; /* a name never wraps to a second line */
}

.horse-condition {
  font-size: 0.95em;
  color: #5c5344;
  margin: 0 0 0.45em;
  line-height: 1.2;
  /* Exactly two lines, text centred within them: a status that wraps ("just
     arrived, needs a lot of care") takes the same space as a short one
     ("in rough shape"). Fixed height (not min-height) so even browsers that
     round line boxes up can't grow the card. */
  height: 2.4em;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* The sponsor line always occupies exactly one line of space; the "shown"
   class only flips visibility. Fixed height + nowrap keep card height
   constant, so a sponsorship reveal (or a long sponsor name) never makes
   the paddock jump. */
.horse-sponsor {
  font-size: 0.88em;
  color: #a3763a;
  margin: -0.25em 0 0.45em;
  line-height: 1.3;
  height: 1.3em;
  white-space: nowrap;
  visibility: hidden;
}

.horse-sponsor.shown {
  visibility: visible;
}

.wellbeing {
  height: 0.62em;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
  overflow: hidden;
}

.wellbeing-fill {
  height: 100%;
  border-radius: 999px;
  transition: width 0.3s ease, background-color 0.3s ease;
}

/* ---------- paddock navigation ---------- */

.paddock-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 20;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid #e6dcc6;
  background: #fffdf7;
  color: #6b5c44;
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 3px 8px rgba(61, 52, 40, 0.18);
  transition: transform 0.12s ease;
}

.paddock-nav:hover {
  transform: translateY(-50%) scale(1.08);
}

.paddock-nav[hidden] {
  display: none;
}

.nav-older { left: 12px; }
.nav-newer { right: 12px; }

/* A little signpost rather than a floating UI chip -- same flat solid-fill
   language as the horses and buttons (no gradients, strokes or shadows). */
/* Season badge (issue #96): a small ambient pill, top-left, opposite the
   wooden paddock sign, so the current game season reads at a glance. */
.season-badge {
  position: absolute;
  top: 14px;
  left: 18px;
  z-index: 15;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  background: rgba(255, 253, 247, 0.92);
  border: 1px solid rgba(61, 52, 40, 0.1);
  border-radius: 999px;
  padding: 0.22rem 0.62rem;
  font-size: 0.72rem;
  font-weight: 700;
  color: #5c5344;
  box-shadow: 0 1px 3px rgba(61, 52, 40, 0.12);
  pointer-events: none;
}
.season-badge[hidden] {
  display: none;
}
.season-badge span {
  font-size: 0.95rem;
  line-height: 1;
}

.paddock-label {
  position: absolute;
  top: 14px;
  right: 18px;
  z-index: 15;
  transform: rotate(-2deg);
  background: #b0823f;
  border-radius: 5px;
  padding: 0.3rem 0.8rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fffdf7;
}

.paddock-label::before,
.paddock-label::after {
  content: '';
  position: absolute;
  top: 5px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #8a6530;
}

.paddock-label::before { left: 7px; }
.paddock-label::after { right: 7px; }

.paddock-label[hidden] {
  display: none;
}

/* ---------- action bar ---------- */

.actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 0.9rem;
}

.actions[hidden] {
  display: none;
}

.action-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  font: inherit;
  font-weight: 700;
  color: #fffdf7;
  background: #b0823f;
  border: none;
  border-radius: 14px;
  padding: 0.6rem 1.5rem;
  cursor: pointer;
  box-shadow: 0 3px 8px rgba(61, 52, 40, 0.18);
  transition: transform 0.12s ease, background 0.2s ease;
}

.action-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  background: #9a7135;
}

.action-btn:disabled {
  background: #cfc4ae;
  color: #857c6b;
  cursor: default;
  box-shadow: none;
}

.action-cost {
  font-size: 0.8rem;
  font-weight: 600;
  opacity: 0.9;
}

.action-btn.share {
  position: relative;
  background: #6f8f4f;
}

.action-btn.share:hover {
  background: #5f7d42;
}

/* Just shared: the button rests while the meter starts refilling. Stays green
   (a cooldown, not "can't afford") — only dimmed, so it reads as catching
   its breath rather than broken. */
.action-btn.share:disabled {
  background: #93a87c;
  color: #f1f5e8;
  box-shadow: 0 3px 8px rgba(61, 52, 40, 0.12);
}

/* The charge line: fills over SHARE_CHARGE_TIME; payout scales with it. */
.share-meter {
  width: 100%;
  height: 5px;
  margin-top: 0.25rem;
  border-radius: 3px;
  background: rgba(255, 253, 247, 0.35);
  overflow: hidden;
}

.share-meter-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: #fffdf7;
  transition: width 1s linear; /* smooths the once-a-second tick updates */
}

/* Fully charged: the line turns golden and the button glows an invitation. */
.action-btn.share.ready .share-meter-fill {
  background: #f7cd3a;
}

.action-btn.share.ready {
  animation: share-ready-pulse 1.6s ease-in-out infinite;
}

@keyframes share-ready-pulse {
  0%, 100% { box-shadow: 0 3px 8px rgba(61, 52, 40, 0.18); }
  50% { box-shadow: 0 3px 16px rgba(247, 205, 58, 0.6); }
}

.money-pop {
  position: absolute;
  top: 0;
  transform: translate(-50%, -100%) rotate(var(--tilt, 0deg));
  background: #e4f2d4;
  border: 1.5px solid #b7d89a;
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  font-size: 0.85rem;
  font-weight: 700;
  color: #4e6e2f;
  white-space: nowrap;
  pointer-events: none;
  animation: care-pop-float 0.9s ease-out forwards;
}

/* Floating "+N 💛" for the supporters chip: warm and quiet, matching the HUD.
   The chip sits at the very top of the screen, so this drifts *downward* below
   it (a float up would sail straight off the top edge), and lingers longer so
   it's actually readable. */
.supporter-pop {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translate(-50%, 0) rotate(var(--tilt, 0deg));
  margin-top: 2px;
  background: #fffdf7;
  border: 1.5px solid #e6dcc6;
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: #b0823f;
  white-space: nowrap;
  pointer-events: none;
  animation: supporter-pop-float 1.9s ease-out forwards;
}

@keyframes supporter-pop-float {
  0%   { opacity: 0; translate: 0 0; }
  12%  { opacity: 1; }
  65%  { opacity: 1; }
  100% { opacity: 0; translate: 0 26px; }
}

/* ---------- donate banner ---------- */

/* Same flat language as the chips: cream fill, thin border, no shadow.
   Appears rarely (first sponsorship, or returning after a long break). */
.donate-banner {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 0.9rem;
  padding: 0.7rem 1rem;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 14px;
  animation: donate-in 0.4s ease;
}

.donate-banner[hidden] {
  display: none;
}

@keyframes donate-in {
  from { opacity: 0; translate: 0 6px; }
}

.donate-text {
  margin: 0;
  flex: 1;
  font-size: 0.85rem;
  color: #5c5344;
}

/* The "Tell a friend" pill sits beside Donate: same soft outline as its modal
   twin (.share-btn-modal), kept from shrinking in the banner row. */
.share-btn-donate {
  flex-shrink: 0;
}

.donate-link {
  flex-shrink: 0;
  background: #6f8f4f;
  color: #fffdf7;
  font-weight: 700;
  font-size: 0.85rem;
  text-decoration: none;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  white-space: nowrap;
}

.donate-link:hover {
  background: #5f7d42;
}

.donate-dismiss {
  flex-shrink: 0;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  color: #8a7d68;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.3rem;
}

.donate-dismiss:hover {
  color: #3d3428;
}

@media (max-width: 560px) {
  /* Stack on narrow screens: button above the text (rather than squeezed
     to its right), dismiss tucked into the corner. */
  .donate-banner {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.6rem;
    position: relative;
  }
  .donate-link { order: 1; }
  .share-btn-donate { order: 2; }
  .donate-text { order: 3; }
  .donate-dismiss {
    position: absolute;
    top: 0.25rem;
    right: 0.4rem;
    padding: 0.2rem;
  }
}

/* ---------- shop modal ---------- */

.shop-overlay {
  position: fixed;
  inset: 0;
  background: rgba(61, 52, 40, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 100;
}

.shop-overlay[hidden] {
  display: none;
}

.shop-modal {
  background: #faf6ee;
  border: 1px solid #e6dcc6;
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(61, 52, 40, 0.2);
  padding: 1.25rem 1.5rem 1.5rem;
  width: 100%;
  max-width: 480px;
  max-height: 85vh;
  overflow-y: auto;
}

/* Tabbed popups keep a steady size whatever tab is showing (issues #94, #89):
   the header, intro and tabs stay pinned and only the active panel scrolls, so
   flicking between tabs never resizes the box (the tack room's Wardrobe / Decor
   / Expansions, and the book's Collection / Badges / Stats / Top rescuers /
   Postcards, whose panels otherwise range from tall grids to a short board). */
#shop-modal,
#collection-modal {
  display: flex;
  flex-direction: column;
  height: min(85vh, 560px);
  overflow: hidden;
}

#shop-modal .shop-header,
#shop-modal > .shop-intro,
#shop-modal > .modal-tabs,
#collection-modal .shop-header,
#collection-modal > .modal-tabs {
  flex-shrink: 0;
}

#shop-modal .modal-panel,
#collection-modal .modal-panel {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.shop-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}

.shop-header h2 {
  margin: 0;
  font-size: 1.3rem;
}

/* Right-hand cluster in a modal header: the "Tell a friend" share button sits
   beside the close ×. */
.header-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

/* Quiet share affordance: reads as an invitation, not a call to action, so it
   never competes with the game's own green "Share an update" fundraiser. */
.share-btn-modal {
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: #6f8f4f;
  background: none;
  border: 1px solid #cfdcb9;
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}

.share-btn-modal:hover {
  background: #eef3e2;
  border-color: #6f8f4f;
}

.share-icon {
  font-size: 0.85em;
}

/* Desktop fallback menu (mobile uses the native share sheet instead). Floats
   at the document level, positioned in JS under the button that opened it. */
.share-menu {
  position: absolute;
  z-index: 200;
  min-width: 9rem;
  background: #fffdf7;
  border: 1px solid #e6ddca;
  border-radius: 0.7rem;
  box-shadow: 0 6px 20px rgba(61, 52, 40, 0.18);
  padding: 0.3rem;
  display: flex;
  flex-direction: column;
}

.share-menu-item {
  font: inherit;
  font-size: 0.85rem;
  color: #3d3428;
  text-align: left;
  text-decoration: none;
  background: none;
  border: none;
  border-radius: 0.45rem;
  padding: 0.5rem 0.6rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.share-menu-item:hover {
  background: #f0ece0;
}

.shop-close {
  font: inherit;
  font-size: 1.3rem;
  line-height: 1;
  color: #8a7d68;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.3rem;
}

.shop-close:hover {
  color: #3d3428;
}

.shop-intro {
  font-size: 0.85rem;
  color: #5c5344;
  margin: 0 0 1rem;
}

/* Section head: title on the left, the section's one target selector on the
   right (e.g. "Wardrobe        Dressing [ Biscuit ▾ ]"). */
.shop-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 1.1rem 0 0.5rem;
}

.shop-section-head h3 {
  font-size: 0.9rem;
  color: #8a7d68;
  margin: 0;
}

/* "Build a new paddock": a full-width call to action under the decor head, so a
   paddock can be built (even empty) whenever one is unlocked. */
.shop-build-paddock:empty {
  display: none;
}

.shop-build-paddock {
  margin: 0 0 0.6rem;
  padding: 0.6rem 0.75rem;
  background: #f4f8ec;
  border: 1px solid #dbe6c6;
  border-radius: 12px;
  text-align: center;
}

.build-paddock-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.85rem;
  color: #fffdf7;
  background: #6f8f4f;
  border: none;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  cursor: pointer;
  white-space: nowrap;
}

.build-paddock-btn:hover:not(:disabled) {
  background: #5f7d42;
}

.build-paddock-btn:disabled {
  background: #dcd3bf;
  color: #a89b83;
  cursor: default;
}

.build-paddock-note {
  margin: 0.4rem 0 0;
  font-size: 0.75rem;
  color: #8a7d68;
}

.shop-target-inner {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.shop-target-label {
  font-size: 0.78rem;
  color: #8a7d68;
}

.shop-target-select {
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: #3d3428;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 8px;
  padding: 0.25rem 0.5rem;
  max-width: 11rem;
}

.shop-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

.shop-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 12px;
  padding: 0.5rem 0.7rem;
}

.shop-item.owned {
  background: #f2ede0;
  border-color: #ddd0b0;
}

.shop-item-icon {
  font-size: 1.2rem;
}

.shop-item-name {
  flex: 1;
  font-size: 0.85rem;
  font-weight: 600;
  color: #3d3428;
}

/* Holds the row's control(s) — a price/Place button, or a "Worn"/"In paddock"
   label with its Remove button. Kept together so they wrap as a unit. */
.shop-item-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
}

/* A placed/worn row carries a wide label+Remove pair. In the half-width either/or
   columns that can't fit on one line, so let the controls drop below the name
   rather than spill over the OR. Buy rows aren't .owned, so they stay one line. */
.shop-item.owned {
  flex-wrap: wrap;
  row-gap: 0.3rem;
}

.shop-item-owned {
  font-size: 0.75rem;
  font-weight: 700;
  color: #6f8f4f;
}

.shop-buy-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.8rem;
  color: #fffdf7;
  background: #b0823f;
  border: none;
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
}

.shop-buy-btn:hover:not(:disabled) {
  background: #9a7135;
}

.shop-buy-btn:disabled {
  background: #dcd3bf;
  color: #a89b83;
  cursor: default;
}

/* ---- "grow the rescue" facility ladder (issue #48) ---- */
.shop-subintro {
  margin: 0 0 0.7rem;
  font-size: 0.82rem;
  color: #8a7d68;
  line-height: 1.4;
}

.facility-grid {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.facility-card {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: #fffdf7;
  border: 1.5px solid #ece3cf;
  border-radius: 12px;
  padding: 0.6rem 0.75rem;
}

.facility-icon {
  font-size: 1.7rem;
  line-height: 1;
  flex: none;
}

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

.facility-name {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 700;
  color: #3d3428;
}

.facility-blurb {
  margin: 0.1rem 0 0;
  font-size: 0.75rem;
  color: #8a7d68;
  line-height: 1.35;
}

.facility-control {
  flex: none;
}

.facility-buy-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.8rem;
  color: #fffdf7;
  background: #6f8f4f;
  border: none;
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
  cursor: pointer;
  white-space: nowrap;
}

.facility-buy-btn:hover:not(:disabled) {
  background: #5f7d42;
}

.facility-buy-btn:disabled {
  background: #dcd3bf;
  color: #a89b83;
  cursor: default;
}

.facility-built {
  font-size: 0.8rem;
  font-weight: 700;
  color: #6f8f4f;
  white-space: nowrap;
}

.facility-locked {
  font-size: 0.78rem;
  font-weight: 600;
  color: #b3a488;
  white-space: nowrap;
}

/* Built: settled and quiet. Next: the one to save for, gently highlighted.
   Locked: dimmed, out of reach until the rung below is built. */
.facility-card.built {
  background: #f4efe2;
  border-color: #e2d9c4;
}

.facility-card.next {
  border-color: #cdb98c;
  box-shadow: 0 0 0 2px #f0e6cd;
}

.facility-card.locked {
  opacity: 0.6;
}

/* Place: bring an owned item out of the stores. Free, so it reads friendlier
   (green) than the coin-cost buy button. */
.shop-place-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.8rem;
  color: #fffdf7;
  background: #6f8f4f;
  border: none;
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
}

.shop-place-btn:hover {
  background: #607d43;
}

/* Remove: send a placed item back to the stores. A quiet, secondary control
   sitting after the "Worn"/"In paddock" label. */
.shop-remove-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.72rem;
  color: #9a7135;
  background: none;
  border: 1px solid #ddd0b0;
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  margin-left: 0.4rem;
  cursor: pointer;
  white-space: nowrap;
}

.shop-remove-btn:hover {
  background: #efe7d5;
}

/* Decor item that can't be placed: the target paddock is at its decoration
   limit. Muted, like the owned state, but not celebratory. */
.shop-item-note {
  font-size: 0.72rem;
  font-weight: 600;
  color: #a89b83;
  text-align: right;
  line-height: 1.2;
}

/* An either/or pair spans the full grid width with an OR between the two
   choices, so it reads as a single "pick one" row. */
.shop-pair {
  grid-column: 1 / -1;
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
}

.shop-pair > .shop-item {
  flex: 1;
  min-width: 0;
}

.shop-pair-or {
  align-self: center;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: #b3a488;
}

@media (max-width: 480px) {
  .shop-grid {
    grid-template-columns: 1fr;
  }
  /* Drop the HUD onto its own full-width line under the title and let its chips
     and buttons wrap, so nothing runs off the side of a phone screen. */
  .hud {
    flex: 1 0 100%;
    justify-content: flex-start;
  }
}

/* ---------- postcard album ---------- */

.album-overlay {
  position: fixed;
  inset: 0;
  background: rgba(61, 52, 40, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 100;
}

.album-overlay[hidden] {
  display: none;
}

.album-modal {
  background: #faf6ee;
  border: 1px solid #e6dcc6;
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(61, 52, 40, 0.2);
  padding: 1.25rem 1.5rem 1.5rem;
  width: 100%;
  max-width: 560px;
  max-height: 85vh;
  overflow-y: auto;
}

.album-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
}

.album-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: #8a7d68;
  font-size: 0.9rem;
  padding: 1.5rem 0.5rem;
}

/* A polaroid: portrait in a soft frame, name + note + date below. */
.postcard {
  margin: 0;
  background: #fffdf7;
  border: 1px solid #ece3cf;
  border-radius: 10px;
  box-shadow: 0 3px 10px rgba(61, 52, 40, 0.12);
  padding: 0.5rem 0.5rem 0.7rem;
  display: flex;
  flex-direction: column;
}

.postcard-photo {
  background: linear-gradient(#eaf3dd, #dcecc9);
  border-radius: 6px;
  padding: 0.4rem;
  aspect-ratio: 5 / 4;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

.postcard-photo .horse-figure {
  width: 80%;
  margin: 0 auto;
}

.postcard-caption {
  padding: 0.5rem 0.35rem 0;
  text-align: center;
}

.postcard-name {
  margin: 0 0 0.25rem;
  font-weight: 800;
  font-size: 1rem;
  color: #3d3428;
}

.postcard-msg {
  margin: 0 0 0.4rem;
  font-size: 0.8rem;
  line-height: 1.35;
  color: #5c5344;
}

.postcard-date {
  margin: 0;
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  color: #a99f89;
}

@media (max-width: 480px) {
  .album-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- residents (the horses at the rescue) — issue #89 ---------- */

/* A touch wider than the other modals so the compact cards fit three across. */
#residents-modal {
  max-width: 620px;
}

.residents-grid {
  display: grid;
  /* Fit as many ~160px cards as the width allows: three across on desktop,
     reflowing to two then one on smaller screens. */
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.7rem;
}

/* Section heading (e.g. magical friends), spanning the whole grid row. */
.residents-group {
  grid-column: 1 / -1;
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
  font-weight: 700;
  color: #8a7d68;
}
.residents-group:first-child {
  margin-top: 0;
}

#residents-grid .album-empty {
  grid-column: 1 / -1;
}

/* "Keep forever" control (issue #83): make a horse a permanent resident. */
.resident-keep {
  margin-top: 0.4rem;
  text-align: center;
}
.resident-keep-btn {
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  color: #6f8f4f;
  background: none;
  border: 1px solid #cfdcb9;
  border-radius: 999px;
  padding: 0.22rem 0.55rem;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
.resident-keep-btn:hover:not(:disabled) {
  background: #eef3e2;
  border-color: #6f8f4f;
}
.resident-keep-btn:disabled {
  color: #a89b83;
  border-color: #e6dcc6;
  cursor: default;
}
/* Once kept, the button reads as a badge and toggles back off on click. */
.resident-keep-btn.is-kept {
  color: #8a6d3b;
  background: #f6efe0;
  border-color: #e4d3ad;
}
.resident-card.is-kept {
  border-color: #e4d3ad;
  box-shadow: 0 3px 10px rgba(138, 109, 59, 0.16);
}
.resident-keep-note {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.66rem;
  color: #a89b83;
}

.resident-card {
  margin: 0;
  background: #fffdf7;
  border: 1px solid #ece3cf;
  border-radius: 10px;
  box-shadow: 0 3px 10px rgba(61, 52, 40, 0.12);
  padding: 0.4rem 0.4rem 0.55rem;
  display: flex;
  flex-direction: column;
}

.resident-photo {
  background: linear-gradient(#eaf3dd, #dcecc9);
  border-radius: 6px;
  padding: 0.35rem;
  aspect-ratio: 5 / 4;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

.resident-info {
  padding: 0.45rem 0.25rem 0;
}

.resident-name {
  margin: 0 0 0.35rem;
  font-weight: 800;
  font-size: 0.92rem;
  text-align: center;
  color: #3d3428;
}

.resident-facts {
  margin: 0;
  font-size: 0.72rem;
}

.resident-facts > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.18rem 0;
  border-top: 1px dashed #ece3cf;
}

.resident-facts dt {
  color: #8a7d68;
  font-weight: 600;
  flex-shrink: 0;
}

.resident-facts dd {
  margin: 0;
  color: #5c5344;
  text-align: right;
}

/* ---------- collection book ---------- */

/* ---------- modal tabs (Collection / Stats) ---------- */

.modal-tabs {
  display: flex;
  gap: 0.4rem;
  margin: 0.2rem 0 0.9rem;
  border-bottom: 1.5px solid #ece3cf;
  overflow-x: auto;           /* the five tabs scroll sideways on a narrow phone */
  scrollbar-width: thin;
}

.modal-tab {
  font: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  color: #8a7d68;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1.5px;
  padding: 0.4rem 0.6rem;
  cursor: pointer;
  white-space: nowrap;        /* a tab label never wraps mid-scroll */
  flex: 0 0 auto;
}

.modal-tab:hover {
  color: #5c5344;
}

.modal-tab.is-active {
  color: #6f8f4f;
  border-bottom-color: #6f8f4f;
}

/* Unread-postcards count on the 💌 tab. */
.tab-badge {
  display: inline-block;
  min-width: 15px;
  height: 15px;
  padding: 0 4px;
  margin-left: 3px;
  border-radius: 999px;
  background: #d9534f;
  color: #fff;
  font-size: 0.6rem;
  font-weight: 800;
  line-height: 15px;
  text-align: center;
  vertical-align: middle;
}

/* ---------- stats tab ---------- */

.stats-list {
  display: flex;
  flex-direction: column;
}

.stat-group {
  margin: 1rem 0 0.35rem;
  font-size: 0.8rem;
  color: #8a7d68;
}

.stat-group:first-child {
  margin-top: 0.2rem;
}

.stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.2rem;
  border-bottom: 1px solid #f0e9d9;
}

.stat-label {
  font-size: 0.9rem;
  color: #5c5344;
}

.stat-value {
  font-size: 0.95rem;
  font-weight: 700;
  color: #3d3428;
  white-space: nowrap;
}

.collection-grid {
  display: flex;
  flex-direction: column;
}

.collection-group {
  margin: 1rem 0 0.5rem;
  font-size: 0.8rem;
  color: #8a7d68;
}

.collection-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 0.6rem;
}

/* ---- badges (issue #65) ---- */
.badges-grid {
  display: flex;
  flex-direction: column;
}

.badges-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 0.6rem;
}

.badge {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: #fffdf7;
  border: 1.5px solid #ece3cf;
  border-radius: 12px;
  padding: 0.6rem 0.5rem 0.55rem;
}

.badge-icon {
  font-size: 1.9rem;
  line-height: 1;
}

.badge-name {
  margin: 0.35rem 0 0;
  font-size: 0.82rem;
  font-weight: 700;
  color: #3d3428;
}

.badge-hint {
  margin: 0.12rem 0 0;
  font-size: 0.68rem;
  font-weight: 600;
  color: #8a7d68;
}

/* Earned: a warm sunlit tile with a gentle glow. */
.badge.earned {
  background: #fbf3dd;
  border-color: #e7cf94;
}

.badge.earned .badge-hint {
  color: #a3763a;
}

/* Locked: dimmed icon, and (for count badges) a progress bar toward the goal. */
.badge.locked .badge-icon {
  filter: grayscale(1) opacity(0.4);
}

.badge.locked .badge-name {
  color: #b3a488;
}

.badge-bar {
  width: 100%;
  height: 5px;
  margin: 0.4rem 0 0.2rem;
  background: #ece3cf;
  border-radius: 3px;
  overflow: hidden;
}

.badge-bar span {
  display: block;
  height: 100%;
  background: #b0823f;
  border-radius: 3px;
}

.badge-count {
  margin: 0;
  font-size: 0.66rem;
  font-weight: 700;
  color: #a3763a;
}

.stamp {
  margin: 0;
  background: #fffdf7;
  border: 1.5px solid #ece3cf;
  border-radius: 12px;
  padding: 0.35rem 0.35rem 0.5rem;
  text-align: center;
}

.stamp-photo {
  background: linear-gradient(#eef3e6, #e2ecd6);
  border-radius: 8px;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

.stamp-photo .horse-figure {
  width: 82%;
  margin: 0 auto;
}

.stamp-name {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  font-weight: 700;
  color: #3d3428;
}

/* How to earn a locked coat (e.g. "Rescue 50 horses") -- a warm little hint. */
.stamp-hint {
  margin: 0.1rem 0 0;
  font-size: 0.66rem;
  font-weight: 600;
  color: #a3763a;
}

/* Locked: a dimmed grey ghost of the coat you're still chasing. */
.stamp.locked .stamp-photo .horse-figure {
  filter: grayscale(1) brightness(1.2) opacity(0.35);
}

.stamp.locked .stamp-name {
  color: #b3a488;
  font-weight: 600;
}

/* Locked mystery: a plain question mark, no preview at all. */
.stamp.mystery .stamp-q {
  align-self: center;
  font-size: 2rem;
  font-weight: 800;
  color: #c9bfa8;
}

/* Rare and magical stamps, once collected, get a tinted frame. */
.stamp.collected.rarity-rare {
  border-color: #e6bd5c;
  box-shadow: 0 0 0 1px #f2da8f inset;
}

.stamp.collected.rarity-magical {
  border-color: #c9a3e6;
  box-shadow: 0 0 10px rgba(180, 130, 220, 0.35);
}

/* ---------- toasts & HUD reveal ---------- */

.toasts {
  position: absolute;
  top: 0.9rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  /* Above the paddock sign and nav arrows -- a story-beat toast should
     never be hidden behind scene furniture. */
  z-index: 30;
  width: max-content;
  /* Never wider than the paddock, and never wider than the phone screen minus a
     safe margin, so a long story-beat toast can't be clipped at the edge (#59). */
  max-width: min(92%, calc(100vw - 1.75rem));
  pointer-events: none;
}

.toast {
  background: #fffdf7;
  border: 1px solid #e6dcc6;
  border-radius: 12px;
  box-shadow: 0 3px 10px rgba(61, 52, 40, 0.12);
  padding: 0.5rem 0.9rem;
  font-size: 0.85rem;
  max-width: 100%;
  overflow-wrap: break-word; /* long words/URLs wrap instead of overflowing (#59) */
  text-align: center;
  animation: toast-life 5s ease forwards;
}

/* The one-time "tap Biscuit" nudge — warmer and bolder than a normal toast
   so a brand-new player's eye actually lands on it. */
.toast-intro {
  background: #ffe8a3;
  border: 2px solid #f0c955;
  color: #7a5a0f;
  font-weight: 700;
  animation: toast-life 8s ease forwards;
}

/* An attention-grabbing warm-orange toast for "you can't do that yet" nudges
   (e.g. a horse still needs care before you can rescue another). */
.toast-alert {
  background: #ffd9b0;
  border: 2px solid #e8934a;
  color: #8a4310;
  font-weight: 700;
  animation: toast-life 6s ease forwards;
}

@keyframes toast-life {
  0%   { opacity: 0; translate: 0 -8px; }
  6%   { opacity: 1; translate: 0 0; }
  88%  { opacity: 1; }
  100% { opacity: 0; translate: 0 -6px; }
}

/* Key figures in popups -- rescue counts, money, supporter tallies -- coloured
   green (the primary-button colour) so skim-readers catch them at a glance.
   Kept at the normal weight: bold green was harder to read. */
.dialog-text .fig {
  color: #5f7d42;
}

/* ---------- onboarding popups ---------- */

/* Big centred nudge, styled like the shop modal, with a playful curved arrow
   pointing toward the button it's teaching. */
.nudge-overlay {
  position: fixed;
  inset: 0;
  background: rgba(61, 52, 40, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 110;
  animation: nudge-fade 0.25s ease;
}

.nudge-overlay[hidden] {
  display: none;
}

.nudge-card {
  position: relative;
  background: #faf6ee;
  border: 1px solid #e6dcc6;
  border-radius: 22px;
  box-shadow: 0 10px 30px rgba(61, 52, 40, 0.28);
  padding: 1.9rem 1.6rem 1.6rem;
  width: 100%;
  max-width: 330px;
  text-align: center;
  animation: nudge-pop 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.nudge-emoji {
  display: block;
  font-size: 2.8rem;
  line-height: 1;
}

.nudge-text {
  font-size: 1.05rem;
  font-weight: 600;
  color: #3d3428;
  line-height: 1.4;
  margin: 0.7rem 0 1.2rem;
}

.nudge-dismiss {
  font: inherit;
  font-weight: 700;
  font-size: 0.9rem;
  color: #fffdf7;
  background: #b0823f;
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.5rem;
  cursor: pointer;
}

.nudge-dismiss:hover {
  background: #9a7135;
}

.nudge-arrow {
  position: absolute;
  left: 50%;
  width: 54px;
  height: 70px;
  color: #eba23c; /* warm amber, pops against the dark scrim */
  overflow: visible;
}

.nudge-arrow-down {
  top: calc(100% - 6px);
  animation: nudge-bob-down 1.2s ease-in-out infinite;
}

.nudge-arrow-up {
  bottom: calc(100% - 6px);
  animation: nudge-bob-up 1.2s ease-in-out infinite;
}

/* Diagonal variant: points up and to the right, toward the Shop button in the
   top-right of the HUD. Sits at the card's top-right corner. */
.nudge-arrow-up-right {
  left: auto;
  right: 4%;
  bottom: calc(100% - 12px);
  animation: nudge-bob-upright 1.2s ease-in-out infinite;
}

@keyframes nudge-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes nudge-pop {
  0%   { opacity: 0; transform: scale(0.9) translateY(6px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes nudge-bob-down {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 6px); }
}

@keyframes nudge-bob-up {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, -6px); }
}

@keyframes nudge-bob-upright {
  0%, 100% { transform: rotate(38deg) translateY(0); }
  50%      { transform: rotate(38deg) translateY(-6px); }
}

/* ---------- event dialogs (rehoming offers, milestone rewards) ---------- */

.dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(61, 52, 40, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 120;
  animation: nudge-fade 0.25s ease;
}

.dialog-overlay[hidden] {
  display: none;
}

.dialog-card {
  background: #faf6ee;
  border: 1px solid #e6dcc6;
  border-radius: 22px;
  box-shadow: 0 10px 30px rgba(61, 52, 40, 0.28);
  padding: 1.9rem 1.6rem 1.6rem;
  width: 100%;
  max-width: 340px;
  text-align: center;
  animation: nudge-pop 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.dialog-emoji {
  display: block;
  font-size: 2.8rem;
  line-height: 1;
}

.dialog-emoji[hidden] {
  display: none;
}

/* Illustrated banner on paddock-life story cards (vet visit, Visitors Day...). */
.dialog-image {
  display: block;
  width: 100%;
  border-radius: 14px;
  margin-bottom: 0.5rem;
}

.dialog-image[hidden] {
  display: none;
}

/* A card with an illustration gets to breathe a little wider than plain ones. */
.dialog-card:has(.dialog-image:not([hidden])) {
  max-width: 430px;
}

.dialog-text {
  font-size: 1.05rem;
  font-weight: 600;
  color: #3d3428;
  line-height: 1.4;
  margin: 0.7rem 0 1.2rem;
}

.dialog-buttons {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  flex-wrap: wrap;
}

.dialog-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.9rem;
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.3rem;
  cursor: pointer;
}

.dialog-btn-primary {
  color: #fffdf7;
  background: #6f8f4f;
}

.dialog-btn-primary:hover {
  background: #5f7d42;
}

.dialog-btn-ghost {
  color: #7a6f5c;
  background: #efe8d8;
}

.dialog-btn-ghost:hover {
  background: #e4dbc6;
}

/* "Tell a friend" on celebratory milestones: a quiet second line under the
   main action, so it invites sharing without competing with Collect. */
.dialog-share {
  margin-top: 0.9rem;
}

.dialog-share-btn {
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: #6f8f4f;
  background: none;
  border: none;
  padding: 0.2rem 0.4rem;
  cursor: pointer;
  border-radius: 999px;
}

.dialog-share-btn:hover {
  text-decoration: underline;
}

/* ---------- confetti ---------- */

.confetti-layer {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 200;
}

.confetti-bit {
  position: absolute;
  left: 50%;
  top: 14%;
  width: 10px;
  height: 14px;
  border-radius: 2px;
  opacity: 0;
  animation: confetti-fall var(--d, 1.2s) var(--delay, 0s) ease-out forwards;
}

@keyframes confetti-fall {
  0%   { opacity: 1; transform: translate(-50%, -50%) rotate(0); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--x) * 46vw), 78vh) rotate(var(--r)); }
}

.chip-reveal {
  animation: chip-pop 0.45s ease;
}

@keyframes chip-pop {
  0%  { transform: scale(0.5); opacity: 0; }
  70% { transform: scale(1.08); }
}

/* ---------- restore whisper (header) ---------- */

.restore-whisper {
  display: block;
  background: none;
  border: none;
  padding: 0;
  margin: 0.15rem 0 0;
  font: inherit;
  font-size: 0.78rem;
  color: #a99a7c;
  cursor: pointer;
  text-align: left;
}

.restore-whisper-link {
  text-decoration: underline;
  text-decoration-color: #d8c39a;
  color: #a3763a;
}

.restore-whisper:hover .restore-whisper-link {
  color: #8a5f28;
}

/* ---------- save-across-devices (privacy popup) ---------- */

.privacy-section {
  border-top: 1px solid #ece3cf;
  margin-top: 0.9rem;
  padding-top: 0.9rem;
}

.privacy-subhead {
  margin: 0 0 0.3rem;
  font-size: 1rem;
  color: #3d3428;
}

.privacy-sub-intro {
  margin: 0 0 0.6rem;
  font-size: 0.88rem;
  color: #5d5344;
}

.privacy-sub-intro-spaced {
  margin-top: 0.9rem;
}

.sc-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 1.1rem;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  padding: 0.5rem;
  margin-bottom: 0.6rem;
  border: 1px solid #d8c39a;
  border-radius: 10px;
  background: #fffdf7;
}

/* ---------- monthly leaderboard ---------- */

.lb-join-text {
  font-size: 0.9rem;
  color: #5d5344;
  margin: 0.25rem 0 0.5rem;
}

.lb-name-preview {
  font-size: 1.25rem;
  font-weight: 700;
  color: #4a6741;
  text-align: center;
  background: #fffdf7;
  border: 1px dashed #cdbfa3;
  border-radius: 12px;
  padding: 0.6rem 1rem;
  margin: 0 0 0.75rem;
}

.lb-join-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.lb-btn {
  padding: 0.45rem 0.9rem;
  font: inherit;
  font-size: 0.85rem;
  color: #5d5344;
  background: #faf6ee;
  border: 1px solid #d8c39a;
  border-radius: 10px;
  cursor: pointer;
}

.lb-btn:hover {
  background: #f5efe1;
}

.lb-btn-primary {
  color: #fff;
  background: #6d8a5b;
  border-color: #6d8a5b;
}

.lb-btn-primary:hover {
  background: #5d7a4c;
}

.lb-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Reigning-champion caption above the board, and the rosette badge itself
   (inline SVG, sized to the surrounding text). */
.lb-champion {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: #8a6d3b;
  margin: 0 0 0.6rem;
}

.lb-rosette {
  width: 1.05em;
  height: auto;
  flex: none;
  vertical-align: -0.25em;
}

.lb-name .lb-rosette {
  margin-left: 0.35em;
}

.lb-list {
  list-style: none;
  margin: 0.25rem 0 0.75rem;
  padding: 0;
}

.lb-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  font-size: 0.92rem;
}

.lb-row:nth-child(even) {
  background: #f5efe1;
}

.lb-you {
  background: #e8efe2;
  font-weight: 600;
}

.lb-rank {
  min-width: 1.6rem;
  text-align: center;
}

.lb-name {
  flex: 1;
}

.lb-score {
  color: #6d8a5b;
  font-weight: 600;
  white-space: nowrap;
}

.lb-status {
  color: #8a7d68;
  font-size: 0.9rem;
  padding: 0.75rem 0.25rem;
}

/* "Leave the board" reads as a footnote action, like the delete button's
   quieter cousin. */
.lb-leave {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: inherit;
  color: #9a4a3a;
  text-decoration: underline;
  cursor: pointer;
}

/* ---------- footer ---------- */

.credit {
  text-align: center;
  font-size: 0.8rem;
  color: #8a7d68;
  padding: 0.35rem 1.5rem 1.25rem;
}

.credit a {
  color: #a3763a;
  text-decoration-color: #d8c39a;
}

.credit a:hover {
  color: #8a5f28;
}

/* The "Game privacy" opener: a button that dresses like the footer's links,
   because it opens a dialog rather than navigating anywhere. */
.credit-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: #a3763a;
  text-decoration: underline;
  text-decoration-color: #d8c39a;
}

.credit-link:hover {
  color: #8a5f28;
}

/* ---------- privacy popup ---------- */

.privacy-list {
  margin: 0.75rem 0;
  padding-left: 1.2rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: #5d5344;
}

.privacy-list li + li {
  margin-top: 0.5rem;
}

.privacy-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.9rem 0 0.75rem;
}

/* Neutral action: download reads like the shop's quiet buttons. */
.privacy-export {
  padding: 0.45rem 0.9rem;
  font: inherit;
  font-size: 0.85rem;
  color: #5d5344;
  background: #faf6ee;
  border: 1px solid #d8c39a;
  border-radius: 10px;
  cursor: pointer;
}

.privacy-export:hover {
  background: #f5efe1;
}

/* Quiet danger button: present but not inviting, and it announces itself
   again (via .is-armed) before actually deleting anything. */
.privacy-delete {
  padding: 0.45rem 0.9rem;
  font: inherit;
  font-size: 0.85rem;
  color: #9a4a3a;
  background: #faf6ee;
  border: 1px solid #d8b4a8;
  border-radius: 10px;
  cursor: pointer;
}

.privacy-delete:hover {
  background: #f6ece6;
}

.privacy-delete.is-armed {
  color: #fff;
  background: #b0503c;
  border-color: #b0503c;
}

.privacy-delete:disabled {
  opacity: 0.6;
  cursor: default;
}

.privacy-meta {
  font-size: 0.8rem;
  color: #8a7d68;
  margin: 0.5rem 0 0;
}

.privacy-meta code {
  font-size: 0.75rem;
  background: #f1ead9;
  border-radius: 4px;
  padding: 0.1rem 0.3rem;
  word-break: break-all;
}

.privacy-meta a {
  color: #a3763a;
}
