/* ============================================================================
   Woofdoku - cozy dog park styling
   ==========================================================================*/

:root {
  --ink: #3b3335;
  --ink-soft: #7b6f70;
  --paper: #fffdfa;
  --sky-1: #eaf6ef;
  --sky-2: #f6efe6;
  --sky-3: #eceaf8;
  --line: #4a3f3d;
  --accent: #ff8f7a;
  --accent-dark: #ef6f57;
  --gold: #ffc44a;
  --radius: 20px;
  --radius-sm: 13px;
  --shadow-sm: 0 2px 6px rgba(74, 63, 61, .09);
  --shadow: 0 10px 26px rgba(74, 63, 61, .13);
  --shadow-lg: 0 22px 50px rgba(74, 63, 61, .2);
  --glass: rgba(255, 253, 250, .74);
  --font: "Baloo 2", "Nunito", "Quicksand", ui-rounded, "Segoe UI Variable Display",
          "Segoe UI", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background:
    radial-gradient(1100px 620px at 12% -8%, #d9f0e2 0%, transparent 60%),
    radial-gradient(900px 560px at 92% 4%, #fdeede 0%, transparent 58%),
    radial-gradient(900px 700px at 50% 108%, #e7e4f7 0%, transparent 62%),
    linear-gradient(170deg, var(--sky-1), var(--sky-2) 55%, var(--sky-3));
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* A field of rounded squares drifting slowly behind everything, faded out at
   the edges so it never competes with the board. */
body::before {
  content: "";
  position: fixed;
  inset: -25%;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72'%3E%3Crect x='7' y='7' width='58' height='58' rx='16' fill='none' stroke='%234a3f3d' stroke-opacity='0.07' stroke-width='2.5'/%3E%3C/svg%3E");
  background-size: 72px 72px;
  animation: grid-drift 48s linear infinite;
  -webkit-mask-image: radial-gradient(115% 80% at 50% 18%, #000 26%, transparent 72%);
  mask-image: radial-gradient(115% 80% at 50% 18%, #000 26%, transparent 72%);
}

@keyframes grid-drift {
  to { transform: translate(72px, 72px); }
}

/* two big soft glows that breathe, which is most of the "premium" feel */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(46% 34% at 16% 12%, rgba(255, 196, 143, .38), transparent 70%),
    radial-gradient(44% 32% at 88% 26%, rgba(203, 183, 247, .34), transparent 70%),
    radial-gradient(52% 34% at 50% 96%, rgba(169, 229, 195, .34), transparent 72%);
  animation: glow-breathe 14s ease-in-out infinite;
}

@keyframes glow-breathe {
  0%, 100% { opacity: .75; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.06); }
}

#app { position: relative; z-index: 1; }

#app {
  position: relative;
  max-width: 620px;
  margin: 0 auto;
  padding: max(14px, env(safe-area-inset-top)) 16px calc(28px + env(safe-area-inset-bottom));
}

/* ------------------------------------------------------------------ screens */

.screen { display: none; animation: screen-in .3s ease both; }
.screen.active { display: block; }

@keyframes screen-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------- menu top  */

.menu-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.menu-top-right { display: flex; gap: 8px; }

.icon-btn.round { border-radius: 50%; }

.avatar-chip {
  position: relative;
  width: clamp(60px, 16vw, 68px);
  height: clamp(60px, 16vw, 68px);
  display: grid;
  place-items: center;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: 30%;
  box-shadow: none;
  cursor: pointer;
  transition: transform .14s ease;
}

#hero-avatar {
  display: block;
  width: 100%;
  height: 100%;
}

#hero-avatar > .frame {
  width: 100%;
  height: 100%;
}

.avatar-chip:hover { transform: translateY(-2px) scale(1.02); }
.avatar-chip:active { transform: translateY(1px) scale(.96); box-shadow: none; }
.avatar-chip:focus-visible { outline: 3px solid #3b3335; outline-offset: 3px; }

/* -------------------------------------------------------------------- logo */

/* The supplied reference works because it is a wordmark, not a badge. Keep the
   same restrained visual language here while drawing original dog-specific
   glyphs: warm brown type, one lavender mascot, and one orange accent. */
/* The wordmark is real text, laid out by the browser.
 *
 * Earlier versions positioned each letter on a fixed slot inside an SVG. That
 * guarantees even *centres*, but letters are not equal width - W is broad, F is
 * narrow - so the visible gaps came out wildly uneven and it read as broken.
 * Letting the font kern "OF" and "KU" itself is the only way to get this right.
 *
 * Each O is a glyph whose viewBox is cropped to the ring alone, so it occupies
 * exactly one letter's worth of space. Ears, tail, legs and paws spill outside
 * the box via overflow, decorating the mark without disturbing the spacing.
 */
.logo {
  --logo-size: clamp(50px, 16.5vw, 70px);
  width: fit-content;
  margin: 2px auto 14px;
  font-size: var(--logo-size);
  font-weight: 800;
  line-height: .94;
  color: #985b3c;
  letter-spacing: -.005em;
  -webkit-user-select: none;
  user-select: none;
}

.logo-line {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Square, sized to the font's cap height so it matches the real letters. */
.logo-glyph {
  display: block;
  flex: 0 0 auto;
  width: .74em;
  height: .74em;
  margin: 0 .015em -.02em;
  overflow: visible;
}

.logo-dog-purple { fill: #8c9bf3; }
.logo-dog-face { fill: #fffaf2; }
.logo-dog-ink { fill: #76513f; }
.logo-dog-eye {
  transform-box: fill-box;
  transform-origin: center;
  animation: logo-dog-blink 4.8s linear infinite;
}

.logo-dog-smile {
  fill: none;
  stroke: #76513f;
  stroke-width: 2.2px;
  stroke-linecap: round;
}

.logo-orange-glyph {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: logo-o-hop 4.2s cubic-bezier(.4, 0, .2, 1) infinite;
}

.logo-orange-o {
  fill: none;
  stroke: #f7941f;
  stroke-width: 15px;
}

.logo-o-tail,
.logo-o-legs {
  fill: none;
  stroke: #985b3c;
  stroke-width: 7px;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.logo-o-tail {
  transform-box: fill-box;
  transform-origin: right center;
  animation: logo-o-tail-wag 1.15s ease-in-out infinite;
}

.logo-o-paw { fill: #985b3c; }
.logo-o-shadow {
  fill: rgba(112, 70, 49, .14);
  transform-box: fill-box;
  transform-origin: center;
  animation: logo-o-shadow 4.2s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes logo-o-hop {
  0%, 68%, 100% { transform: translateY(0) scale(1); }
  73% { transform: translateY(1px) scale(1.06, .94); }
  80% { transform: translateY(-9px) scale(.96, 1.04) rotate(-2deg); }
  85% { transform: translateY(-10px) scale(.97, 1.03) rotate(2deg); }
  92% { transform: translateY(1px) scale(1.08, .92); }
  96% { transform: translateY(-1px) scale(.99, 1.01); }
}

@keyframes logo-o-shadow {
  0%, 68%, 100% { opacity: .14; transform: scaleX(1); }
  73% { opacity: .19; transform: scaleX(1.14); }
  80%, 85% { opacity: .06; transform: scaleX(.62); }
  92% { opacity: .2; transform: scaleX(1.18); }
  96% { opacity: .13; transform: scaleX(.96); }
}

@keyframes logo-o-tail-wag {
  0%, 100% { transform: rotate(-8deg); }
  50% { transform: rotate(13deg); }
}

@keyframes logo-dog-blink {
  0%, 45%, 48%, 100% { transform: scaleY(1); }
  46.5% { transform: scaleY(.12); }
}

@media (prefers-reduced-motion: reduce) {
  .logo-orange-glyph,
  .logo-o-shadow,
  .logo-o-tail,
  .logo-dog-eye { animation: none; }
}

@media (max-width: 380px) {
  .logo { --logo-size: clamp(46px, 17vw, 62px); margin-top: 0; }
}

/* ---------------------------------------------------------- profile strip  */

.profile-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: rgba(255, 255, 255, .72);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: 20px;
  box-shadow: 0 6px 18px rgba(74, 63, 61, .09);
}

.ps-main { flex: 1 1 auto; min-width: 0; }
.ps-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 7px; }
.ps-top strong { font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ps-solved {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 12px;
  background: linear-gradient(160deg, #fff, #f1f9f3);
  border: 1px solid #d5eddd;
  border-radius: 15px;
}

.ps-solved strong { font-size: 19px; line-height: 1; }
.ps-solved small { font-size: 9.5px; color: var(--ink-soft); letter-spacing: .3px; }

/* --------------------------------------------------------- feature cards  */

.feature-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 18px; }

.fcard {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 12px 12px;
  min-height: 168px;
  font-family: inherit;
  border: 0;
  border-radius: 24px;
  cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}

.fcard-streak {
  background: linear-gradient(170deg, #ffd76a, #f5b12f);
  box-shadow: inset 0 -6px 0 rgba(180, 110, 10, .22), 0 8px 0 rgba(190, 120, 20, .32),
              0 16px 28px rgba(74, 63, 61, .18);
}

.fcard-board {
  background: linear-gradient(170deg, #b39cf7, #8f74ea);
  box-shadow: inset 0 -6px 0 rgba(70, 40, 150, .24), 0 8px 0 rgba(85, 55, 165, .34),
              0 16px 28px rgba(74, 63, 61, .18);
}

.fcard:hover { transform: translateY(-3px); }
.fcard:active { transform: translateY(5px); box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .2), 0 2px 0 rgba(0, 0, 0, .25); }

/* the sunburst behind the artwork */
.rays {
  position: absolute;
  top: 46%;
  left: 50%;
  width: 230%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: repeating-conic-gradient(from 0deg,
    rgba(255, 255, 255, .32) 0deg 7deg, rgba(255, 255, 255, 0) 7deg 14deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 12%, transparent 68%);
  mask-image: radial-gradient(closest-side, #000 12%, transparent 68%);
  animation: rays-spin 26s linear infinite;
  pointer-events: none;
}

@keyframes rays-spin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

.fcard-title {
  position: relative;
  align-self: flex-start;
  font-size: 16px;
  font-weight: 900;
  color: #7a4a12;
  text-shadow: 0 1.5px 0 rgba(255, 255, 255, .6);
}

.fcard-art {
  position: relative;
  font-size: 52px;
  line-height: 1;
  filter: drop-shadow(0 5px 6px rgba(120, 70, 10, .3));
  animation: art-bob 2.8s ease-in-out infinite;
}

@keyframes art-bob {
  50% { transform: translateY(-5px) rotate(-4deg); }
}

.fcard-badge,
.fcard-medal {
  position: absolute;
  top: 9px;
  right: 9px;
  display: grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  font-size: 12px;
  font-weight: 900;
  color: #7a4a12;
  background: rgba(255, 255, 255, .92);
  border-radius: 999px;
  box-shadow: 0 2px 5px rgba(74, 63, 61, .22);
}

.fcard-medal { color: #5a3fa8; }

.fcard-pill {
  position: relative;
  width: 100%;
  margin-top: auto;
  padding: 7px 10px;
  font-size: 15px;
  font-weight: 900;
  color: #7a4a12;
  background: rgba(255, 255, 255, .9);
  border-radius: 999px;
  box-shadow: inset 0 2px 4px rgba(120, 80, 20, .12);
}

.fcard-board .fcard-pill { color: #5a3fa8; }

/* the 2 / 1 / 3 podium on the leaderboard card */
.podium {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  height: 62px;
  margin-top: 4px;
}

.podium i {
  display: grid;
  place-items: center;
  width: 24px;
  font-size: 14px;
  font-style: normal;
  font-weight: 900;
  color: #fff;
  border-radius: 6px 6px 3px 3px;
}

.podium .p1 { height: 58px; background: linear-gradient(180deg, #ffd76a, #f0ab27); color: #7a4a12; box-shadow: inset 0 -4px 0 rgba(150, 90, 10, .25); }
.podium .p2 { height: 42px; background: linear-gradient(180deg, #e9e6f5, #c4bedb); color: #5f5a75; box-shadow: inset 0 -4px 0 rgba(80, 70, 110, .2); }
.podium .p3 { height: 34px; background: linear-gradient(180deg, #ffc49b, #e79462); box-shadow: inset 0 -4px 0 rgba(150, 80, 40, .25); }

/* ------------------------------------------------------- chunky 3D buttons */

.bigbtn {
  display: block;
  width: 100%;
  margin-bottom: 12px;
  padding: 17px 20px;
  font-family: inherit;
  font-size: 21px;
  font-weight: 900;
  color: #fff;
  text-shadow: 0 2px 3px rgba(120, 60, 20, .3);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease;
}

.bigbtn-primary {
  background: linear-gradient(180deg, #ffa257, #f0812f);
  box-shadow: inset 0 -5px 0 rgba(170, 80, 15, .3), 0 8px 0 #d76a22,
              0 16px 26px rgba(215, 106, 34, .34);
}

.bigbtn-blue {
  background: linear-gradient(180deg, #9fb4f7, #7f92ee);
  text-shadow: 0 2px 3px rgba(50, 60, 140, .3);
  box-shadow: inset 0 -5px 0 rgba(50, 60, 150, .28), 0 8px 0 #6b7ad8,
              0 16px 26px rgba(107, 122, 216, .32);
}

.bigbtn:hover { transform: translateY(-2px); }

.bigbtn-primary:active {
  transform: translateY(6px);
  box-shadow: inset 0 -2px 0 rgba(170, 80, 15, .3), 0 2px 0 #d76a22;
}

.bigbtn-blue:active {
  transform: translateY(6px);
  box-shadow: inset 0 -2px 0 rgba(50, 60, 150, .28), 0 2px 0 #6b7ad8;
}

.btn-timer {
  display: block;
  width: fit-content;
  margin: -8px auto 18px;
  padding: 5px 14px;
  font-size: 12.5px;
  font-weight: 800;
  color: #6b5f52;
  background: rgba(255, 255, 255, .85);
  border-radius: 999px;
  box-shadow: 0 3px 8px rgba(74, 63, 61, .12);
}

/* --------------------------------------------------------- small menu row  */

.menu-mini {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  width: min(100%, 420px);
  margin: 0 auto;
}

.menu-mini button {
  padding: 11px 6px;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink);
  background: rgba(255, 255, 255, .8);
  border: 1px solid rgba(255, 255, 255, .95);
  border-radius: 15px;
  box-shadow: 0 4px 10px rgba(74, 63, 61, .08);
  cursor: pointer;
  transition: transform .14s ease;
}

.menu-mini button:hover { transform: translateY(-2px); }
.menu-mini button:active { transform: translateY(1px); }

/* -------------------------------------------------------------- containers */

.card {
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* ---------------------------------------------------------------- hero card */

.hero { display: flex; gap: 14px; align-items: center; padding: 16px; margin-bottom: 18px; }

.hero-avatar {
  position: relative;
  flex: 0 0 auto;
  width: 68px;
  height: 68px;
  font-size: 36px;
  line-height: 1;
  display: grid;
  place-items: center;
  border: 2px solid #fff;
  border-radius: 22px;
  background: linear-gradient(160deg, #fff, #ffeede);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform .16s ease;
}

.hero-avatar:hover { transform: translateY(-2px) scale(1.03); }
.hero-avatar:active { transform: scale(.96); }

.hero-pencil {
  position: absolute;
  right: -4px;
  bottom: -4px;
  font-size: 13px;
  background: #fff;
  border-radius: 50%;
  padding: 3px;
  box-shadow: var(--shadow-sm);
}

.hero-main { flex: 1 1 auto; min-width: 0; }
.hero-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hero-top h2 { margin: 0; font-size: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.badge {
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  background: linear-gradient(140deg, #fff2cf, #ffe0a8);
  border: 1px solid #ffd98f;
  white-space: nowrap;
}

.progress {
  height: 9px;
  margin: 9px 0 5px;
  border-radius: 999px;
  background: rgba(74, 63, 61, .1);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #7fd8a6, #ffc44a);
  transition: width .55s cubic-bezier(.3, 1.4, .5, 1);
}

.hero-hint { margin: 0; font-size: 12px; color: var(--ink-soft); }
.hero-stats { display: flex; gap: 14px; margin-top: 7px; font-size: 12px; color: var(--ink-soft); }
.hero-stats strong { color: var(--ink); font-size: 14px; }

/* -------------------------------------------------------------- menu tiles */

.menu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 14px;
  text-align: left;
  font-family: inherit;
  color: var(--ink);
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, .82);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: transform .16s ease, box-shadow .16s ease;
}

.tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.tile:active { transform: translateY(0) scale(.975); }
.tile-wide { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 12px; }
.tile-wide .tile-label { flex: 0 0 auto; }
.tile-wide small { margin-left: auto; text-align: right; }

.tile-primary {
  background: linear-gradient(150deg, #fff, #ffe6dd 120%);
  border-color: #ffd0c2;
}

.tile-icon { font-size: 26px; line-height: 1.1; }
.tile-label { font-weight: 800; font-size: 16px; }
.tile small { color: var(--ink-soft); font-size: 11.5px; }

/* ------------------------------------------------------------------ topbar */

.topbar { display: flex; align-items: center; gap: 10px; padding: 4px 0 14px; }
.topbar-title { flex: 1 1 auto; min-width: 0; text-align: center; }
.topbar-title h2 { margin: 0; font-size: 19px; }
.topbar-title p { margin: 2px 0 0; font-size: 12px; color: var(--ink-soft); }

.icon-btn {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  font-size: 17px;
  font-family: inherit;
  color: var(--ink);
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, .85);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform .14s ease;
}

.icon-btn:hover { transform: translateY(-2px); }
.icon-btn:active { transform: scale(.92); }

/* -------------------------------------------------------------------- tabs */

.tabs { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 12px; }

.tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 9px 3px;
  font-family: inherit;
  color: var(--ink-soft);
  background: rgba(255, 253, 250, .6);
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: transform .14s ease, background .14s ease;
}

.tab { padding: 8px 2px; }
.tab strong { font-size: 12.5px; }
.tab small { font-size: 8.5px; letter-spacing: 0; }
.tab:hover { transform: translateY(-2px); }

.tab.active {
  color: var(--ink);
  background: linear-gradient(160deg, #fff, #ffe9dd);
  border-color: #ffd0c2;
  box-shadow: var(--shadow-sm);
}

.level-count { margin: 0 0 10px; font-size: 12px; color: var(--ink-soft); text-align: center; }

/* ------------------------------------------------------------ level cards */

.level-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 10px; }

.level-card {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  font-family: inherit;
  color: var(--ink);
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, .85);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease;
}

.level-card:hover { transform: translateY(-3px) rotate(-1deg); box-shadow: var(--shadow); }
.level-card:active { transform: scale(.95); }
.level-no { font-size: 19px; font-weight: 800; }
.level-state { font-size: 13px; line-height: 1; color: var(--ink-soft); }
.level-best { font-size: 10px; color: var(--ink-soft); }
.level-card.done { background: linear-gradient(160deg, #fff, #e4f7ea); border-color: #b6e6c8; }

/* boss levels - every 4th - need a real pattern, so they are flagged */
.level-card.boss {
  background: linear-gradient(160deg, #fff8e8, #ffe9b8);
  border-color: #f0c351;
  box-shadow: 0 3px 0 rgba(200, 150, 40, .28), var(--shadow-sm);
}

.level-card.boss.done { background: linear-gradient(160deg, #fff8e8, #d9f2e2); border-color: #7fc9a0; }
.level-card.boss .level-no { color: #9a6a12; }

.level-card.locked,
.level-card.locked.done,
.level-card.boss.locked,
.level-card:disabled {
  color: #8f8985;
  background: linear-gradient(160deg, #f8f5f2, #ebe7e3);
  border-color: #dcd6d0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55), 0 2px 5px rgba(72, 60, 53, .08);
  cursor: not-allowed;
  opacity: .72;
  filter: saturate(.35);
}

.level-card.locked:hover,
.level-card.locked:active,
.level-card:disabled:hover,
.level-card:disabled:active {
  transform: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55), 0 2px 5px rgba(72, 60, 53, .08);
}

.level-card.locked .level-no,
.level-card.boss.locked .level-no,
.level-card.locked .level-best { color: #8f8985; }
.level-card.locked .level-state { font-size: 14px; filter: grayscale(1); }

/* ------------------------------------------------------------- game status */

.statusbar { display: flex; justify-content: center; gap: 7px; flex-wrap: wrap; margin-bottom: 10px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  font-size: 12.5px;
  font-weight: 700;
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, .85);
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
}

.chip b { font-variant-numeric: tabular-nums; }
.chip-lives { letter-spacing: 1px; }
.chip-lives.no-lives { background: #ffe9e5; border-color: #ffc4b8; color: #c14733; letter-spacing: 0; }

/* ---------------------------------------------------------- rule reminders */

.rulechips { display: flex; justify-content: center; gap: 6px; margin-bottom: 12px; }

.rulechip {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, .85);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
}

.rulechip b { font-size: 10px; font-weight: 700; line-height: 1.3; color: var(--ink); }

/* a tiny 3x3 board that shows the rule rather than describing it */
.mini {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 11px);
  grid-template-rows: repeat(3, 11px);
  gap: 1.5px;
}

.mini i {
  position: relative;
  border-radius: 3px;
  background: #f2ebe4;
}

.mini i.mint { background: #5fc189; }
.mini i.sky { background: #58a7dd; }
.mini i.coral { background: #f0716d; }
.mini i.peach { background: #f09a4e; }

.mini i.x::after,
.mini i.dog::after {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  line-height: 1;
}

.mini i.x::after {
  content: "✕";
  font-size: 8px;
  font-weight: 900;
  color: #fff;
  text-shadow: 0 1px 1px rgba(74, 63, 61, .25);
}

.mini i.dog::after { content: "🐶"; font-size: 8.5px; }

@media (max-width: 400px) {
  .rulechip { gap: 6px; padding: 6px 7px; }
  .rulechip b { font-size: 9px; }
  .mini { grid-template-columns: repeat(3, 9px); grid-template-rows: repeat(3, 9px); }
  .mini i.x::after { font-size: 7px; }
  .mini i.dog::after { font-size: 7.5px; }
}

/* ------------------------------------------------------------ difficulty  */

.diff-row { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.diff-label { flex: 0 0 auto; font-size: 11.5px; font-weight: 700; color: var(--ink-soft); }
.diff-tabs { flex: 1 1 auto; display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }

.diff-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 7px 4px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  background: rgba(255, 253, 250, .6);
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: transform .14s ease;
}

.diff-tab small { font-size: 9.5px; font-weight: 600; }
.diff-tab:hover { transform: translateY(-2px); }

.diff-tab.active {
  color: var(--ink);
  background: linear-gradient(160deg, #fff, #ffe9dd);
  border-color: #ffd0c2;
  box-shadow: var(--shadow-sm);
}

/* ------------------------------------------------------------------- board */

.board-holder { display: flex; justify-content: center; }

.board {
  position: relative;
  width: 100%;
  max-width: 520px;
  aspect-ratio: 1;
  padding: clamp(9px, 2.6vw, 15px);
  background: #fff;
  border: 0;
  border-radius: 24px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .9) inset,
    0 10px 26px rgba(74, 63, 61, .11),
    0 2px 6px rgba(74, 63, 61, .06);
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

/* One box shared by the park art and the tappable squares. Sizing the glyphs
   from this container (cqw) keeps them tied to the real square size instead of
   guessing from the viewport, which is what let dogs spill outside a square. */
.board-inner {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 18px;
  overflow: hidden;
}

.board.solved { animation: board-cheer .6s ease; }

@keyframes board-cheer {
  0%, 100% { transform: none; }
  30% { transform: scale(1.025) rotate(-.5deg); }
  65% { transform: scale(1.01) rotate(.4deg); }
}

.board-cells {
  position: relative;
  z-index: 2;
  /* the board owns the gesture: dragging paints fences instead of scrolling */
  touch-action: none;
  display: grid;
  /* explicit rows: without these, rows size to their content and a square
     holding a dog grows taller than an empty one, skewing the whole grid */
  grid-template-columns: repeat(var(--n), 1fr);
  grid-template-rows: repeat(var(--n), 1fr);
  gap: var(--gap, 4px);
  width: 100%;
  height: 100%;
}

/* Each square is a raised tile in its park's colour, separated by white
   gutters. --tile is set per cell by the board; --cell is the measured size, so
   the rounding, the 3D lip and the glyph all scale with the real square. */
.cell {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 0;
  padding: 0;
  border: 0;
  background: var(--tile, #efe7e0);
  border-radius: clamp(4px, calc(var(--cell, 44px) * .19), 14px);
  box-shadow:
    inset 0 calc(var(--cell, 44px) * -.1) 0 rgba(88, 68, 52, .15),
    inset 0 1.5px 0 rgba(255, 255, 255, .5),
    0 2px 3px rgba(74, 63, 61, .1);
  font-family: inherit;
  font-size: calc(var(--cell, 44px) * .52);
  line-height: 1;
  overflow: hidden;
  cursor: pointer;
  transition: transform .1s ease, box-shadow .1s ease, filter .12s ease;
}

.cell:hover { filter: brightness(1.05); }

/* pressed tiles sink into the board */
.cell.pressing {
  transform: translateY(calc(var(--cell, 44px) * .05));
  box-shadow:
    inset 0 calc(var(--cell, 44px) * -.03) 0 rgba(88, 68, 52, .18),
    0 1px 2px rgba(74, 63, 61, .1);
}

/* Tiles show the park colour solid - no translucent film over the top. Only
   hover and press tint them, so nothing looks washed out. */
.cell::after {
  content: "";
  position: absolute;
  inset: 0;
  background: transparent;
  transition: background .12s ease;
  pointer-events: none;
}

.cell:focus-visible { outline: 3px solid #fff; outline-offset: -3px; z-index: 3; }

.mark { position: relative; z-index: 2; display: block; }
.mark.pop { animation: mark-pop .34s cubic-bezier(.24, 1.6, .4, 1); }

@keyframes mark-pop {
  from { transform: scale(.2) rotate(-16deg); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* Fences are a drawn cross, not an emoji, so the colour is ours to choose:
   white for your own notes, red when a dog turned out to be wrong. */
.mark.cross {
  width: calc(var(--cell, 44px) * .42);
  height: calc(var(--cell, 44px) * .42);
}

.mark.cross::before,
.mark.cross::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: 19%;
  min-height: 2px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(74, 63, 61, .3);
  transform: translate(-50%, -50%) rotate(45deg);
}

.mark.cross::after { transform: translate(-50%, -50%) rotate(-45deg); }

.cell.is-wrong .mark.cross::before,
.cell.is-wrong .mark.cross::after {
  background: #e8443f;
  box-shadow: 0 1px 3px rgba(150, 30, 25, .45);
}

.cell.is-wrong { animation: wrong-flash .5s ease; }

@keyframes wrong-flash {
  0%, 100% { box-shadow: inset 0 0 0 0 rgba(233, 61, 61, 0); }
  25% { box-shadow: inset 0 0 0 999px rgba(233, 61, 61, .5); }
}

.cell.has-dog .mark { filter: drop-shadow(0 2px 3px rgba(74, 63, 61, .32)); }



.cell.is-hinted::before {
  content: "";
  position: absolute;
  inset: 6%;
  border-radius: 12px;
  box-shadow: 0 0 0 3px var(--gold), 0 0 18px 4px rgba(255, 196, 74, .75);
  z-index: 1;
  animation: hint-glow 1.7s ease-in-out infinite;
}

@keyframes hint-glow {
  50% { box-shadow: 0 0 0 3px var(--gold), 0 0 26px 9px rgba(255, 196, 74, .45); }
}

.cell.shake { animation: cell-shake .45s cubic-bezier(.36, .07, .19, .97); z-index: 4; }
.cell.nudge { animation: cell-nudge .3s ease; }

/* the park closing up: each cross eases in as the sweep passes over it */
.cell.sealing .mark { animation: seal-pop .42s cubic-bezier(.22, 1.35, .36, 1) both; }

@keyframes seal-pop {
  0% { transform: scale(.3) rotate(-25deg); opacity: 0; }
  55% { transform: scale(1.18) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

.cell.sealing::after { animation: seal-flash .42s ease; }

@keyframes seal-flash {
  0% { background: rgba(255, 255, 255, .5); }
  100% { background: transparent; }
}

.cell.is-sealed .mark.cross::before,
.cell.is-sealed .mark.cross::after { opacity: .8; }

@keyframes cell-nudge {
  50% { transform: scale(1.06); }
}

.board.lost { filter: grayscale(.65) brightness(.94); transition: filter .5s ease; }

@keyframes cell-shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

/* The free starter dog carries no ring. It used to get a dashed white outline,
   but a dog is already unmistakable in a square, so the marker only added noise.
   The .is-anchor class is still applied and still distinguishes the gift dog
   from a placed one in the DOM. */

/* ----------------------------------------------------------- game actions */

.game-actions { display: flex; flex-wrap: wrap; gap: 9px; justify-content: center; margin: 16px 0 8px; }

.btn {
  padding: 11px 17px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(160deg, var(--accent), var(--accent-dark));
  border: 0;
  border-radius: 14px;
  box-shadow: 0 5px 14px rgba(239, 111, 87, .34);
  cursor: pointer;
  transition: transform .14s ease, box-shadow .14s ease;
}

.btn:hover { transform: translateY(-2px); box-shadow: 0 9px 20px rgba(239, 111, 87, .4); }
.btn:active { transform: translateY(0) scale(.96); }

.btn-ghost {
  color: var(--ink);
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow: var(--shadow-sm);
}

.btn-ghost:hover { box-shadow: var(--shadow); }
.btn-ghost.on { background: linear-gradient(160deg, #fff, #e4f7ea); border-color: #b6e6c8; }
.btn-block { display: block; width: 100%; margin-top: 14px; }

.version-tag { margin: 18px 0 0; color: #a89bb5; font-size: 11px; text-align: center; letter-spacing: .02em; }

.btn-power { display: inline-flex; align-items: center; gap: 7px; }

.pip {
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  font-size: 11px;
  color: var(--accent-dark);
  background: #fff;
  border-radius: 999px;
}

.btn:disabled { cursor: not-allowed; opacity: .5; box-shadow: none; transform: none; }
.btn.spent { filter: grayscale(.5); }

/* settings toggles */
.toggle-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 9px;
  padding: 12px 14px;
  text-align: left;
  font-family: inherit;
  color: var(--ink);
  background: #faf7f3;
  border: 1px solid #f0e8e0;
  border-radius: 15px;
  cursor: pointer;
}

.toggle-row > span:first-child { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; }
.toggle-row b { font-size: 14px; }
.toggle-row small { font-size: 11px; color: var(--ink-soft); }

.switch {
  flex: 0 0 auto;
  position: relative;
  width: 42px;
  height: 24px;
  background: #ddd3ca;
  border-radius: 999px;
  transition: background .18s ease;
}

.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
  transition: transform .18s cubic-bezier(.3, 1.4, .5, 1);
}

.toggle-row.on { background: #eafaf0; border-color: #b6e6c8; }
.toggle-row.on .switch { background: #67cc95; }
.toggle-row.on .switch::after { transform: translateX(18px); }

.controls-hint { margin: 6px 0 0; text-align: center; font-size: 11.5px; color: var(--ink-soft); }

/* ------------------------------------------------------------------ modals */

.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(59, 51, 53, .42);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.modal.open { display: flex; animation: fade-in .2s ease; }

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

.sheet {
  width: 100%;
  max-width: 400px;
  max-height: 88vh;
  overflow-y: auto;
  padding: 18px;
  background: var(--paper);
  border-radius: 24px;
  box-shadow: var(--shadow-lg);
  animation: sheet-in .3s cubic-bezier(.22, 1.3, .4, 1);
}

@keyframes sheet-in {
  from { opacity: 0; transform: translateY(18px) scale(.96); }
  to { opacity: 1; transform: none; }
}

.sheet-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.sheet-head h3 { margin: 0; flex: 1 1 auto; font-size: 18px; }
.sheet-lead { margin: 0 0 12px; font-size: 13.5px; color: var(--ink-soft); }

.field { display: block; margin-bottom: 14px; }
.field > span, .field-label { display: block; margin-bottom: 5px; font-size: 12.5px; font-weight: 700; }
.field small { display: block; margin-top: 4px; font-size: 11px; color: var(--ink-soft); }

.field input {
  width: 100%;
  padding: 11px 13px;
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 13px;
}

.field input:focus { outline: 0; border-color: var(--accent); }

/* ------------------------------------------------------ avatars and frames */

.dogav { display: block; width: 100%; height: 100%; }

/* A frame is a ring around the dog. Each tier adds a richer ring, and the last
   one glows, so the profile keeps earning new looks as you solve more parks. */
.frame {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: 8%;
  border-radius: 30%;
  background: #f2ebe4;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .85);
}

.frame-basic { background: linear-gradient(160deg, #f4eee7, #e4dad0); }
.frame-bronze { background: linear-gradient(160deg, #e8b48a, #c07a48); }
.frame-silver { background: linear-gradient(160deg, #eceff3, #b9c1cc); }
.frame-ocean {
  background:
    radial-gradient(circle at 24% 18%, rgba(255, 255, 255, .82) 0 5%, transparent 6%),
    conic-gradient(from 210deg, #075985, #22d3ee, #e0f2fe, #0ea5e9, #164e63, #075985);
  box-shadow: inset 0 0 0 2px rgba(224, 247, 255, .9), 0 0 11px rgba(14, 165, 233, .38);
}
.frame-mint { background: linear-gradient(160deg, #a9e5c3, #4fae7d); }
.frame-fire {
  background: conic-gradient(from 20deg, #7f1d1d, #ef4444, #f97316, #fde047, #f97316, #dc2626, #7f1d1d);
  box-shadow: inset 0 0 0 2px rgba(255, 244, 190, .92), 0 0 13px rgba(249, 115, 22, .58);
  animation: fire-frame-pulse 1.7s ease-in-out infinite;
}
.frame-gold { background: linear-gradient(160deg, #ffe08a, #e0a92a); }
.frame-sakura {
  background:
    radial-gradient(circle at 18% 22%, #fff 0 4%, transparent 5%),
    radial-gradient(circle at 78% 70%, #ffe4ef 0 7%, transparent 8%),
    conic-gradient(from 45deg, #9f5879, #f9a8d4, #ffe4ef, #f472b6, #9f5879);
  box-shadow: inset 0 0 0 2px rgba(255, 246, 250, .9), 0 0 10px rgba(244, 114, 182, .35);
}
.frame-berry { background: linear-gradient(160deg, #f7abcf, #b4569a); }
.frame-cosmic {
  background:
    radial-gradient(circle at 28% 18%, #fff 0 2%, transparent 3%),
    radial-gradient(circle at 72% 78%, #fde68a 0 2%, transparent 3%),
    radial-gradient(circle at 80% 28%, #c4b5fd 0 3%, transparent 4%),
    conic-gradient(from 200deg, #111827, #312e81, #7c3aed, #0f766e, #111827);
  box-shadow: inset 0 0 0 2px rgba(224, 231, 255, .86), 0 0 14px rgba(124, 58, 237, .5);
  animation: cosmic-frame-glow 3.6s ease-in-out infinite;
}
.frame-rainbow { background: conic-gradient(#ff9d94, #f0c351, #5fc189, #58a7dd, #a68ae4, #e87aa9, #ff9d94); }

@keyframes fire-frame-pulse {
  50% { box-shadow: inset 0 0 0 2px #fff3b0, 0 0 20px rgba(239, 68, 68, .72); }
}

@keyframes cosmic-frame-glow {
  50% { box-shadow: inset 0 0 0 2px #e0e7ff, 0 0 20px rgba(45, 212, 191, .58); }
}

.frame-legend {
  background: conic-gradient(#fff2b0, #ffd155, #ff9d5c, #ffd155, #fff2b0);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .9), 0 0 14px 3px rgba(255, 200, 70, .75);
  animation: halo 3.4s linear infinite;
}

@keyframes halo {
  to { filter: hue-rotate(20deg); }
}

.frame-rainbow { animation: frame-spin 8s linear infinite; }
.frame-legend { animation: frame-spin 8s linear infinite, halo 3.4s ease-in-out infinite; }

@keyframes frame-spin {
  to { transform: rotate(360deg); }
}

/* the dog must not spin with its frame */
.frame-rainbow .dogav, .frame-legend .dogav { animation: frame-spin 8s linear infinite reverse; }

.frame > .dogav {
  background: #fffdfa;
  border-radius: 26%;
}

.profile-hero { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-bottom: 14px; }
.profile-preview { width: 92px; }
.profile-hero strong { font-size: 15px; }

/* minmax(0, 1fr), not 1fr: a bare 1fr track floors at the item's automatic
   minimum size, so the avatar artwork refused to shrink and the fourth column
   overflowed off-screen on narrow phones. Because .avatar-opt is aspect-ratio 1,
   an over-wide track also grew taller and pushed into the frame picker below. */
.avatar-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin: 6px 0 4px; }

.avatar-opt {
  position: relative;
  aspect-ratio: 1;
  min-width: 0;
  padding: 5px;
  overflow: visible;
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 15px;
  cursor: pointer;
  transition: transform .14s ease;
}

.avatar-opt:hover { transform: translateY(-2px) scale(1.05); }
.avatar-opt.selected { border-color: var(--accent); background: #fff1ec; box-shadow: 0 0 0 3px rgba(255, 143, 122, .22); }
.avatar-opt.selected::after {
  content: "✓";
  position: absolute;
  right: -5px;
  bottom: -5px;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  color: #fff;
  font-size: 12px;
  font-weight: 900;
  background: #22b879;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 3px 7px rgba(25, 122, 84, .28);
}

.frame-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 6px 0 4px; }

.frame-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  gap: 4px;
  padding: 7px 4px;
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 15px;
  cursor: pointer;
  transition: transform .14s ease;
}

.frame-opt .frame { width: min(56px, 100%); }
.frame-opt small { font-size: 9px; color: var(--ink-soft); line-height: 1.15; text-align: center; }
.frame-opt:hover { transform: translateY(-2px); }
.frame-opt.selected { border-color: var(--accent); background: #fff1ec; }
.frame-opt.locked { opacity: .6; }
.frame-lock { display: grid; place-items: center; width: 100%; height: 100%; font-size: 14px; }

/* level complete banner */
#banner {
  position: fixed;
  left: 50%;
  top: 42%;
  z-index: 95;
  padding: 16px 30px;
  font-size: clamp(24px, 7vw, 34px);
  font-weight: 800;
  color: #fff;
  white-space: nowrap;
  background: linear-gradient(150deg, #ffb27a, #ff7f96);
  border: 3px solid #fff;
  border-radius: 20px;
  box-shadow: 0 16px 40px rgba(74, 63, 61, .32);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.6) rotate(-4deg);
}

#banner.show { animation: banner-in 1.25s cubic-bezier(.2, 1.5, .4, 1) forwards; }

@keyframes banner-in {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.5) rotate(-8deg); }
  18% { opacity: 1; transform: translate(-50%, -50%) scale(1.08) rotate(2deg); }
  30% { transform: translate(-50%, -50%) scale(1) rotate(-1deg); }
  78% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(-1deg); }
  100% { opacity: 0; transform: translate(-50%, -58%) scale(.94) rotate(0); }
}

/* ------------------------------------------------------------ rank ladder */

.sheet-ranks { max-width: 430px; }

.rank-overview {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 11px;
  padding: 13px;
  color: #342d53;
  background:
    radial-gradient(circle at 8% 0%, rgba(255, 255, 255, .95), transparent 37%),
    linear-gradient(145deg, #eee9ff, #e7f2ff);
  border: 1px solid #d4caf7;
  border-radius: 17px;
}

.rank-overview-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  font-size: 26px;
  background: #fff;
  border-radius: 15px;
  box-shadow: var(--shadow-sm);
}

.rank-overview-copy { display: flex; flex-direction: column; min-width: 0; }
.rank-overview-copy small { font-size: 8.5px; font-weight: 900; letter-spacing: .12em; color: #776ca6; }
.rank-overview-copy strong { font-size: 17px; }
.rank-overview-copy span { font-size: 10.5px; line-height: 1.3; color: var(--ink-soft); }
.rank-overview-count { display: flex; flex-direction: column; align-items: flex-end; color: #665ac5; }
.rank-overview-count strong { font-size: 20px; line-height: 1; }
.rank-overview-count small { font-size: 9px; }

.rank-progress {
  height: 8px;
  margin: 9px 4px 0;
  overflow: hidden;
  background: #e5e0ef;
  border-radius: 999px;
}

.rank-progress span {
  display: block;
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, #7e6de1, #54a3df);
  border-radius: inherit;
  transition: width .35s ease;
}

.rank-explainer { margin: 9px 3px 12px; font-size: 10.5px; line-height: 1.4; color: var(--ink-soft); text-align: center; }
.rank-list { display: flex; flex-direction: column; gap: 6px; }

.rank-tier {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  min-height: 51px;
  padding: 8px 10px;
  background: #faf8f6;
  border: 1px solid #eee8e2;
  border-radius: 14px;
}

.rank-tier.complete { background: linear-gradient(145deg, #f5fcf7, #eaf8ef); border-color: #ccead7; }
.rank-tier.current {
  background: linear-gradient(145deg, #fff8ec, #ffedcf);
  border-color: #f1c978;
  box-shadow: 0 4px 12px rgba(190, 133, 35, .16);
}
.rank-tier.locked { color: #77716d; background: #f7f4f1; }

.rank-tier-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  font-size: 18px;
  background: #fff;
  border-radius: 11px;
  box-shadow: 0 2px 6px rgba(74, 63, 61, .08);
}

.rank-tier.locked .rank-tier-icon { filter: grayscale(.72); opacity: .68; }
.rank-tier-copy { display: flex; flex-direction: column; min-width: 0; }
.rank-tier-copy strong { font-size: 12.5px; }
.rank-tier-copy small { font-size: 9.5px; color: var(--ink-soft); }
.rank-tier-state { min-width: 33px; font-size: 10px; font-weight: 900; color: #55a979; text-align: center; }
.rank-tier.current .rank-tier-state { padding: 4px 6px; color: #8b5b08; background: #ffe0a2; border-radius: 999px; }
.rank-tier.locked .rank-tier-state { filter: grayscale(1); opacity: .55; }
.rank-legend-note { margin: 11px 3px; padding: 9px 10px; font-size: 10.5px; color: #6f5c2d; text-align: center; background: #fff8e8; border: 1px solid #f1ddb0; border-radius: 12px; }

/* leaderboard */
.sheet-leaderboard { max-width: 560px; }
/* Three tabs: Today / All time / Endless. */
.lb-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-bottom: 10px; }

.lb-tab {
  padding: 9px 4px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-soft);
  background: #faf7f3;
  border: 1px solid #f0e8e0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.lb-tab.active {
  color: var(--ink);
  background: linear-gradient(160deg, #fff, #ffe9dd);
  border-color: #ffd0c2;
}

.lb-round {
  display: grid;
  justify-items: center;
  gap: 2px;
  margin: 2px 0 14px;
  padding: 11px 14px;
  color: #69461b;
  background: linear-gradient(145deg, #fff9e9, #ffe9c7);
  border: 1px solid #f2d39c;
  border-radius: 16px;
}
.lb-round[hidden], .lb-podium[hidden], .lb-list-title[hidden] { display: none; }
.lb-round span { font-size: 9.5px; font-weight: 900; letter-spacing: 1.2px; }
.lb-round strong { font-size: 25px; line-height: 1.1; font-variant-numeric: tabular-nums; letter-spacing: 1px; }
/* "29d 18:15:42" is four characters longer than "01:40:03", so the season clock
   trades a little size for fitting on a 320px sheet. */
.lb-round.is-season strong { font-size: 20px; letter-spacing: .4px; }
.lb-round small { font-size: 10px; color: #84663d; }

.lb-podium {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 8px;
  margin: 0 0 14px;
}
.lb-podium:empty { display: none; }
.lb-podium-card {
  position: relative;
  order: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 13px 8px 11px;
  text-align: center;
  background: linear-gradient(155deg, #fff, #f8f3ed);
  border: 1px solid #eadfd4;
  border-radius: 18px;
  box-shadow: var(--shadow-sm);
}
.lb-podium-card.rank-1 { order: 2; min-height: 172px; padding-top: 17px; background: linear-gradient(155deg, #fffdf2, #ffe7a9); border-color: #efc96e; }
.lb-podium-card.rank-2 { order: 1; min-height: 150px; background: linear-gradient(155deg, #fff, #edf1f5); border-color: #cdd5de; }
.lb-podium-card.rank-3 { order: 3; min-height: 140px; background: linear-gradient(155deg, #fffaf5, #f3d4bd); border-color: #dfb392; }
.lb-podium-card.me { outline: 3px solid rgba(255, 143, 122, .32); border-color: #ff9f87; }
.lb-podium-medal { position: absolute; top: -11px; font-size: 24px; filter: drop-shadow(0 2px 2px rgba(70, 45, 20, .14)); }
.lb-podium-avatar { width: 58px; margin: 5px 0 6px; }
.lb-podium-card.rank-1 .lb-podium-avatar { width: 68px; }
.lb-podium-card strong { max-width: 100%; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-podium-card > small { min-height: 24px; margin-top: 2px; font-size: 9.5px; line-height: 1.25; color: var(--ink-soft); }
.lb-podium-score { margin-top: auto; padding-top: 7px; font-size: 15px; font-weight: 900; color: #bf4055; font-variant-numeric: tabular-nums; }
.lb-podium-score small { display: block; font-size: 8.5px; font-weight: 700; color: var(--ink-soft); }

.lb-list-title { margin: 0 2px 7px; font-size: 11px; letter-spacing: .7px; text-transform: uppercase; color: var(--ink-soft); }
.lb-note { margin: 9px 0 0; font-size: 11px; line-height: 1.4; color: var(--ink-soft); text-align: center; }
.lb-empty { padding: 12px; font-size: 12px; color: var(--ink-soft); text-align: center; }
.lb-gap { padding: 2px 12px; font-size: 16px; letter-spacing: 3px; }

.lb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }

.lb-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  background: #faf7f3;
  border: 1px solid #f0e8e0;
  border-radius: 14px;
}

.lb-row.me { background: linear-gradient(150deg, #fff4ee, #ffe7dc); border-color: #ffc9b6; box-shadow: var(--shadow-sm); }
.lb-row.me.outside { position: relative; margin-top: 4px; border-width: 2px; }
/* Unofficial local total: visibly provisional so it is never mistaken for a
   confirmed placement. */
.lb-row.me.provisional { margin-top: 4px; border-style: dashed; background: #fffaf6; }
.lb-pos { flex: 0 0 34px; font-size: 13px; font-weight: 900; color: var(--ink-soft); }
.lb-who { flex: 1 1 auto; display: flex; align-items: center; gap: 9px; min-width: 0; }
.lb-avatar { flex: 0 0 auto; width: 34px; }
.lb-stack { display: flex; flex-direction: column; min-width: 0; }
.lb-stack strong { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-stack small { font-size: 10px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-you-label { font-size: 8px !important; font-weight: 900; letter-spacing: .7px; color: #b35442 !important; }
.lb-score { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; font-size: 11.5px; color: var(--ink-soft); }
.lb-score b { font-size: 12px; color: var(--ink); }
.lb-score small { font-size: 9.5px; }

/* ---- endless tab -----------------------------------------------------------
   This tab is a personal record rather than a ranking, so a row carries a grid
   size and a bar showing that size's share of your clears, in place of the
   position and player that a real leaderboard row shows. */


@media (max-width: 440px) {
  .sheet-leaderboard { padding-right: 11px; padding-left: 11px; }

  /* Three tabs share the row on a phone, so the labels give back some width. */
  .lb-tab { padding: 8px 3px; font-size: 11px; }

  /* Phones keep the real 2 / 1 / 3 podium: the raised centre is what makes it
     read as a podium at a glance, and flattening it into three list rows lost
     that. Only the scale changes here, never the layout or the order. */
  .lb-podium { gap: 5px; margin-bottom: 12px; }
  .lb-podium-card { padding: 11px 3px 9px; border-radius: 15px; }
  .lb-podium-card.rank-1 { min-height: 152px; padding-top: 15px; }
  .lb-podium-card.rank-2 { min-height: 133px; }
  .lb-podium-card.rank-3 { min-height: 124px; }
  .lb-podium-medal { top: -9px; font-size: 20px; }
  .lb-podium-avatar { width: 45px; margin: 4px 0 5px; }
  .lb-podium-card.rank-1 .lb-podium-avatar { width: 53px; }
  .lb-podium-card strong { font-size: 10.5px; }
  .lb-podium-card > small { min-height: 22px; font-size: 8.5px; line-height: 1.2; }
  .lb-podium-score { padding-top: 5px; font-size: 13.5px; }
  .lb-podium-score small { font-size: 7.5px; }
  .lb-row { gap: 7px; padding-right: 8px; padding-left: 8px; }
  .lb-pos { flex-basis: 30px; }
  .lb-score small { display: none; }
}

/* Smallest phones still get the podium shape, just tighter again. */
@media (max-width: 344px) {
  .sheet-leaderboard { padding-right: 8px; padding-left: 8px; }
  .lb-podium { gap: 4px; }
  .lb-podium-card { padding: 10px 2px 8px; }
  .lb-podium-card.rank-1 { min-height: 140px; }
  .lb-podium-card.rank-2 { min-height: 123px; }
  .lb-podium-card.rank-3 { min-height: 115px; }
  .lb-podium-avatar { width: 39px; }
  .lb-podium-card.rank-1 .lb-podium-avatar { width: 46px; }
  .lb-podium-card strong { font-size: 9.5px; }
  .lb-podium-card > small { font-size: 8px; }
  .lb-podium-score { font-size: 12.5px; }
}

/* titles */
.badge-title { background: linear-gradient(140deg, #efe6ff, #ded0ff); border-color: #c9b6f5; }
.titles-list { display: flex; flex-direction: column; gap: 6px; }
.title-group { margin: 12px 0 2px; font-size: 11px; letter-spacing: .5px; text-transform: uppercase; color: var(--ink-soft); }

.title-row {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
  font-family: inherit;
  color: var(--ink);
  background: #faf7f3;
  border: 1px solid #f0e8e0;
  border-radius: 14px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.title-row.locked { opacity: .55; }
.title-row.earned { background: linear-gradient(150deg, #fff, #f3fbf5); border-color: #cdebd7; position: relative; overflow: hidden; }
.title-row.equipped { box-shadow: var(--shadow-sm); }

/* ---- shared pseudo-element base ---- */
.title-row.earned::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ============================================================
   UNIQUE TITLE EFFECTS — 22 titles, 22 looks
   ============================================================ */

/* --- ACCURACY GROUP --- */

/* Keen Nose 🎯 — crosshair lock-on pulse, warm green */
.title-row.tt-keen { background: linear-gradient(150deg, #f2f8ee, #e6f2dc); border-color: #b5d9a0; }
.title-row.tt-keen::after {
  background: radial-gradient(circle at 50% 50%, rgba(80, 160, 50, .1) 0%, transparent 60%);
  animation: keen-lock 3s ease-in-out infinite;
}
.title-row.tt-keen .title-stack strong { color: #438a2a; }
@keyframes keen-lock {
  0%, 100% { transform: scale(.9); opacity: .3; }
  50% { transform: scale(1.1); opacity: 1; }
}

/* Unerring 🔍 — scanning magnifier sweep, steel blue */
.title-row.tt-unerring { background: linear-gradient(150deg, #edf5fc, #daeaf8); border-color: #a0c8e8; }
.title-row.tt-unerring::after {
  inset: -50% 0;
  background: linear-gradient(100deg, transparent 38%, rgba(70, 140, 210, .12) 44%, rgba(70, 140, 210, .2) 50%, rgba(70, 140, 210, .12) 56%, transparent 62%);
  animation: unerring-scan 2.8s ease-in-out infinite;
}
.title-row.tt-unerring .title-stack strong { color: #2570a8; }
@keyframes unerring-scan {
  0% { transform: translateX(-90%); }
  100% { transform: translateX(90%); }
}

/* Flawless Tracker 💎 — diamond sparkle refraction, ice blue-white */
.title-row.tt-flawless { background: linear-gradient(150deg, #f4faff, #e8f0ff, #faf8ff); border-color: #b0c8f0; }
.title-row.tt-flawless::after {
  background:
    radial-gradient(circle at 25% 30%, rgba(160, 200, 255, .2), transparent 40%),
    radial-gradient(circle at 75% 70%, rgba(200, 170, 255, .15), transparent 40%),
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .3), transparent 30%);
  animation: flawless-sparkle 3s ease-in-out infinite alternate;
}
.title-row.tt-flawless .title-stack strong {
  background: linear-gradient(135deg, #4080d0, #8060c0, #40a0d0);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
@keyframes flawless-sparkle {
  0% { opacity: .4; transform: rotate(-1deg) scale(.98); }
  50% { opacity: 1; transform: rotate(0deg) scale(1.01); }
  100% { opacity: .6; transform: rotate(1deg) scale(.99); }
}

/* --- SAVES GROUP --- */

/* Life Saver ❤️ — heartbeat pulse, warm pink */
.title-row.tt-saver { background: linear-gradient(150deg, #fff0f2, #ffe4e8); border-color: #f0b8c0; }
.title-row.tt-saver::after {
  background: radial-gradient(circle at 50% 50%, rgba(240, 80, 100, .1), transparent 55%);
  animation: saver-beat 1.5s ease-in-out infinite;
}
.title-row.tt-saver .title-stack strong { color: #c04058; }
@keyframes saver-beat {
  0%, 100% { transform: scale(1); opacity: .4; }
  15% { transform: scale(1.08); opacity: .9; }
  30% { transform: scale(1); opacity: .5; }
  45% { transform: scale(1.05); opacity: .8; }
}

/* Shepherd of Strays 💗 — warm heart ripple, deep rose */
.title-row.tt-shepherd { background: linear-gradient(150deg, #fdf0f4, #f8dce6, #fef4f7); border-color: #e8a8c0; }
.title-row.tt-shepherd::after {
  background:
    radial-gradient(circle at 30% 50%, rgba(220, 80, 130, .08), transparent 50%),
    radial-gradient(circle at 70% 50%, rgba(200, 60, 110, .06), transparent 50%);
  animation: shepherd-ripple 4s ease-in-out infinite;
}
.title-row.tt-shepherd .title-stack strong { color: #b03870; }
@keyframes shepherd-ripple {
  0%, 100% { opacity: .3; transform: scale(.95); }
  50% { opacity: 1; transform: scale(1.05); }
}

/* Life Guardian 🛡️ — shield gleam, steel silver */
.title-row.tt-guardian { background: linear-gradient(150deg, #f0f4f8, #e4ecf4, #f2f6fa); border-color: #b0c4d8; }
.title-row.tt-guardian::after {
  inset: -60% 0;
  background: linear-gradient(115deg, transparent 40%, rgba(180, 210, 240, .2) 47%, rgba(220, 230, 245, .3) 50%, rgba(180, 210, 240, .2) 53%, transparent 60%);
  animation: guardian-gleam 3.5s ease-in-out infinite;
}
.title-row.tt-guardian .title-stack strong { color: #3a6890; }
@keyframes guardian-gleam {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* Unshaken 🏰 — fortress stone, amber grit */
.title-row.tt-unshaken { background: linear-gradient(150deg, #f8f2e8, #f0e4d0, #f6f0e4); border-color: #d8c098; }
.title-row.tt-unshaken::after {
  background:
    radial-gradient(ellipse at 20% 80%, rgba(180, 140, 60, .08), transparent 50%),
    radial-gradient(ellipse at 80% 20%, rgba(160, 120, 40, .06), transparent 50%);
  animation: unshaken-grit 5s ease-in-out infinite alternate;
}
.title-row.tt-unshaken .title-stack strong { color: #8a6820; }
@keyframes unshaken-grit {
  0% { opacity: .4; }
  100% { opacity: .9; }
}

/* Storm Walker 🌩️ — dark storm cloud flicker, electric grey-purple */
.title-row.tt-stormwalker { background: linear-gradient(150deg, #eee8f4, #e0d4f0, #e8e0f0); border-color: #b8a0d8; }
.title-row.tt-stormwalker::after {
  background: radial-gradient(ellipse at 60% 40%, rgba(140, 100, 200, .12), transparent 55%);
  animation: storm-flash 3s ease-in-out infinite;
}
.title-row.tt-stormwalker .title-stack strong { color: #6840a0; }
@keyframes storm-flash {
  0%, 78%, 84%, 100% { opacity: .2; }
  80% { opacity: 1; }
  82% { opacity: .1; }
  86% { opacity: .8; }
}

/* --- LOGIC GROUP --- */

/* Unaided 🧠 — neural pulse, soft pink-grey */
.title-row.tt-unaided { background: linear-gradient(150deg, #f8f0f4, #f0e8ee); border-color: #d8c0d0; }
.title-row.tt-unaided::after {
  background: radial-gradient(circle at 40% 50%, rgba(180, 100, 160, .08), transparent 55%);
  animation: neural-pulse 3.5s ease-in-out infinite;
}
.title-row.tt-unaided .title-stack strong { color: #884878; }
@keyframes neural-pulse {
  0%, 100% { opacity: .3; transform: scale(.97); }
  50% { opacity: 1; transform: scale(1.03); }
}

/* Chain Reader ⛓️ — chain links shimmer, dark iron */
.title-row.tt-chainreader { background: linear-gradient(150deg, #f0eff2, #e4e0ea, #eeedf2); border-color: #b8b0c8; }
.title-row.tt-chainreader::after {
  inset: -40% 0;
  background: repeating-linear-gradient(90deg, transparent, transparent 18%, rgba(120, 100, 160, .1) 20%, transparent 22%);
  animation: chain-slide 4s linear infinite;
}
.title-row.tt-chainreader .title-stack strong { color: #5a4880; }
@keyframes chain-slide {
  0% { transform: translateX(-30%); }
  100% { transform: translateX(30%); }
}

/* --- DEVOTION GROUP --- */

/* Park Regular 📅 — sunrise warmth, gentle orange */
.title-row.tt-regular { background: linear-gradient(150deg, #fff8f0, #ffeedd); border-color: #e8c89a; }
.title-row.tt-regular::after {
  background: radial-gradient(ellipse at 50% 90%, rgba(255, 160, 50, .08), transparent 60%);
  animation: sunrise-glow 4s ease-in-out infinite;
}
.title-row.tt-regular .title-stack strong { color: #a06820; }
@keyframes sunrise-glow {
  0%, 100% { opacity: .3; }
  50% { opacity: 1; }
}

/* All Weather Walker ☔ — rain streaks, cool grey-blue */
.title-row.tt-allweather { background: linear-gradient(150deg, #eef2f8, #dce6f2, #e8eef6); border-color: #a0b8d4; }
.title-row.tt-allweather::after {
  background:
    repeating-linear-gradient(170deg, transparent, transparent 8px, rgba(100, 150, 200, .05) 8px, rgba(100, 150, 200, .05) 9px);
  animation: rain-fall 1.5s linear infinite;
}
.title-row.tt-allweather .title-stack strong { color: #3868a0; }
@keyframes rain-fall {
  0% { transform: translateY(-10px); }
  100% { transform: translateY(10px); }
}

/* The Legend 👑 — royal gold aurora, majestic */
.title-row.tt-legend { background: linear-gradient(150deg, #fdf8e8, #f8ecc0, #fdf6e0); border-color: #e0c870; box-shadow: 0 0 14px rgba(220, 180, 40, .12); }
.title-row.tt-legend::after {
  background:
    radial-gradient(ellipse at 30% 30%, rgba(255, 200, 50, .12), transparent 50%),
    radial-gradient(ellipse at 70% 70%, rgba(255, 180, 30, .08), transparent 50%);
  animation: legend-aurora 5s ease-in-out infinite alternate;
}
.title-row.tt-legend .title-stack strong {
  background: linear-gradient(135deg, #b88a10, #d4a020, #c09018);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: 800;
}
@keyframes legend-aurora {
  0% { opacity: .4; transform: rotate(-1deg); }
  100% { opacity: 1; transform: rotate(1deg); }
}

/* --- TODAY GROUP --- */

/* Top Dog of the Day 🥇 — blazing gold spotlight */
.title-row.tt-topdog { background: linear-gradient(150deg, #fff8e0, #ffe8a0, #fff4d0); border-color: #e0b830; box-shadow: 0 0 16px rgba(240, 190, 40, .15); }
.title-row.tt-topdog::after {
  inset: -80% 0;
  background: linear-gradient(105deg, transparent 40%, rgba(255, 220, 60, .25) 47%, rgba(255, 240, 120, .3) 50%, rgba(255, 220, 60, .25) 53%, transparent 60%);
  animation: topdog-shine 3s ease-in-out infinite;
}
.title-row.tt-topdog .title-stack strong {
  background: linear-gradient(135deg, #c08800, #e0a800, #d09000);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: 800;
}
@keyframes topdog-shine {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(110%); }
}

/* Park Deputy 🥈 — silver polish sweep */
.title-row.tt-deputy { background: linear-gradient(150deg, #f6f6fa, #e8e8f0, #f2f2f8); border-color: #c0c0d0; }
.title-row.tt-deputy::after {
  inset: -60% 0;
  background: linear-gradient(105deg, transparent 40%, rgba(200, 200, 220, .25) 47%, rgba(230, 230, 245, .35) 50%, rgba(200, 200, 220, .25) 53%, transparent 60%);
  animation: deputy-polish 3.5s ease-in-out infinite;
}
.title-row.tt-deputy .title-stack strong { color: #606880; }
@keyframes deputy-polish {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* Very Good Boy 🥉 — bronze warm glow */
.title-row.tt-goodboy { background: linear-gradient(150deg, #faf4ee, #f0e4d4, #f6f0e8); border-color: #d4b890; }
.title-row.tt-goodboy::after {
  background: radial-gradient(circle at 50% 50%, rgba(200, 150, 80, .1), transparent 55%);
  animation: bronze-glow 3s ease-in-out infinite;
}
.title-row.tt-goodboy .title-stack strong { color: #907040; }
@keyframes bronze-glow {
  0%, 100% { opacity: .3; transform: scale(.97); }
  50% { opacity: .9; transform: scale(1.02); }
}

/* --- CHAMPIONS GROUP --- */

/* Top Dog I 🏆 — first trophy, copper gleam */
.title-row.tt-topdog-i { background: linear-gradient(150deg, #f8f0e8, #f0e0cc); border-color: #d8b888; }
.title-row.tt-topdog-i::after {
  inset: -50% 0;
  background: linear-gradient(105deg, transparent 42%, rgba(200, 160, 80, .15) 48%, rgba(220, 180, 100, .2) 50%, rgba(200, 160, 80, .15) 52%, transparent 58%);
  animation: trophy1-gleam 4s ease-in-out infinite;
}
.title-row.tt-topdog-i .title-stack strong { color: #907030; }
@keyframes trophy1-gleam {
  0% { transform: translateX(-90%); }
  100% { transform: translateX(90%); }
}

/* Top Dog II 🏆 — double trophy, amber flame */
.title-row.tt-topdog-ii { background: linear-gradient(150deg, #fff4e4, #ffe4c0, #fff0d8); border-color: #e0b060; }
.title-row.tt-topdog-ii::after {
  background:
    radial-gradient(ellipse at 30% 70%, rgba(240, 160, 30, .1), transparent 45%),
    radial-gradient(ellipse at 70% 30%, rgba(240, 140, 20, .08), transparent 45%);
  animation: trophy2-flame 2.5s ease-in-out infinite alternate;
}
.title-row.tt-topdog-ii .title-stack strong { color: #b07818; }
@keyframes trophy2-flame {
  0% { opacity: .4; transform: scale(1); }
  100% { opacity: 1; transform: scale(1.03); }
}

/* Top Dog III 🏆 — triple trophy, molten amber */
.title-row.tt-topdog-iii { background: linear-gradient(150deg, #fff0d4, #ffd8a0, #ffeccc); border-color: #d8a040; }
.title-row.tt-topdog-iii::after {
  background:
    radial-gradient(ellipse at 20% 50%, rgba(255, 140, 20, .1), transparent 40%),
    radial-gradient(ellipse at 50% 50%, rgba(255, 160, 40, .08), transparent 40%),
    radial-gradient(ellipse at 80% 50%, rgba(255, 140, 20, .1), transparent 40%);
  animation: trophy3-molten 3s ease-in-out infinite;
}
.title-row.tt-topdog-iii .title-stack strong { color: #c07010; }
@keyframes trophy3-molten {
  0%, 100% { opacity: .4; }
  33% { opacity: 1; }
  66% { opacity: .6; }
}

/* Top Dog IV 🏆 — prismatic trophy, purple-gold shift */
.title-row.tt-topdog-iv { background: linear-gradient(150deg, #f4ecff, #e8d8f8, #fdf4e8); border-color: #c0a0e0; box-shadow: 0 0 10px rgba(160, 110, 220, .1); }
.title-row.tt-topdog-iv::after {
  inset: -70% 0;
  background: linear-gradient(105deg, transparent 38%, rgba(160, 100, 240, .15) 44%, rgba(240, 200, 60, .12) 50%, rgba(160, 100, 240, .15) 56%, transparent 62%);
  animation: trophy4-prism 4s ease-in-out infinite;
}
.title-row.tt-topdog-iv .title-stack strong {
  background: linear-gradient(135deg, #7040c0, #c09020);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
@keyframes trophy4-prism {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(110%); }
}

/* Top Dog V 🏆 — radiant trophy, double-pulse gold-violet */
.title-row.tt-topdog-v { background: linear-gradient(150deg, #f8f0ff, #e8d0f8, #fef4e0); border-color: #b890e0; box-shadow: 0 0 14px rgba(170, 120, 230, .14); }
.title-row.tt-topdog-v::after {
  background:
    radial-gradient(circle at 30% 40%, rgba(180, 120, 255, .12), transparent 45%),
    radial-gradient(circle at 70% 60%, rgba(255, 200, 50, .1), transparent 45%);
  animation: trophy5-radiant 3s ease-in-out infinite alternate;
}
.title-row.tt-topdog-v .title-stack strong {
  background: linear-gradient(135deg, #8050d0, #d0a020, #8050d0);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: 800;
}
@keyframes trophy5-radiant {
  0% { opacity: .3; transform: scale(.98); }
  100% { opacity: 1; transform: scale(1.02); }
}

/* Ultimate Dog 👑 — cosmic crown, full aurora with starfield */
.title-row.tt-ultimate-dog { background: linear-gradient(150deg, #f0e8ff, #dcc8f8, #f8ecd8, #e0d0f8); border-color: #b080e0; box-shadow: 0 0 20px rgba(160, 80, 240, .18), 0 0 40px rgba(255, 180, 40, .08); }
.title-row.tt-ultimate-dog::after {
  inset: -100% 0;
  background:
    linear-gradient(105deg, transparent 35%, rgba(180, 100, 255, .2) 42%, rgba(255, 210, 60, .2) 50%, rgba(180, 100, 255, .2) 58%, transparent 65%);
  animation: ultimate-cosmic 4.5s ease-in-out infinite;
}
.title-row.tt-ultimate-dog .title-stack strong {
  background: linear-gradient(135deg, #8030e0, #e0a010, #c050d0, #e0a010);
  background-size: 200% 100%;
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: 800;
  animation: ultimate-text 4s ease-in-out infinite;
}
@keyframes ultimate-cosmic {
  0% { transform: translateX(-120%) rotate(-1deg); }
  100% { transform: translateX(120%) rotate(1deg); }
}
@keyframes ultimate-text {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

/* ---- equipped ring per tier ---- */
.title-row.equipped.tier-earth { border-color: #6daa58; box-shadow: 0 0 0 2px rgba(76, 153, 55, .2), var(--shadow-sm); }
.title-row.equipped.tier-water { border-color: #5a9fd4; box-shadow: 0 0 0 2px rgba(50, 140, 220, .2), var(--shadow-sm); }
.title-row.equipped.tier-fire { border-color: #e07830; box-shadow: 0 0 0 2px rgba(220, 100, 20, .2), var(--shadow-sm); }
.title-row.equipped.tier-thunder { border-color: #9a6ce0; box-shadow: 0 0 8px rgba(160, 100, 240, .25), 0 0 0 2px rgba(160, 100, 240, .15), var(--shadow-sm); }

/* reduce motion: keep colors, drop animations */
@media (prefers-reduced-motion: reduce) {
  .title-row.earned::after { animation: none !important; opacity: .5; transform: none; }
  .title-row .title-stack strong { animation: none !important; }
}
.title-icon { flex: 0 0 auto; font-size: 22px; }
.title-stack { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.title-stack strong { font-size: 13.5px; }
.title-stack small { font-size: 10.5px; color: var(--ink-soft); }
.title-tick { flex: 0 0 auto; font-weight: 800; color: #8b6fd6; }

.lb-saved { font-size: 15px !important; font-variant-numeric: tabular-nums; }

.victory-saved {
  margin: 12px 0 0;
  padding: 9px 12px;
  font-size: 15px;
  font-weight: 800;
  color: #c1435a;
  background: linear-gradient(150deg, #fff2f4, #ffe3e8);
  border: 1px solid #ffc8d1;
  border-radius: 14px;
}

.victory-place { margin: 10px 0 0; font-size: 13px; font-weight: 700; }
.victory-title-win { margin: 6px 0 0; font-size: 13.5px; font-weight: 800; color: #7d5cc6; }

.daily-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px;
  background: linear-gradient(150deg, #f2f9f4, #fdf1e6);
  border: 1px solid #e2eee6;
  border-radius: 16px;
}

.rules { margin: 0; padding-left: 20px; font-size: 13.5px; line-height: 1.6; }
.rules li { margin-bottom: 8px; }

/* ----------------------------------------------------------------- victory */

.sheet-victory { text-align: center; }
.sheet-victory h3 { margin: 6px 0 2px; font-size: 25px; }
.victory-sub { margin: 0 0 14px; font-size: 13px; color: var(--ink-soft); }

/* happy dog flanked by two poppers */
.party { display: flex; align-items: center; justify-content: center; gap: 4px; }

.happy-dog {
  font-size: 58px;
  line-height: 1.1;
  animation: dog-bounce 1.1s cubic-bezier(.3, 1.5, .5, 1) infinite;
  transform-origin: 50% 90%;
}

@keyframes dog-bounce {
  0%, 100% { transform: translateY(0) rotate(-3deg) scale(1); }
  35% { transform: translateY(-11px) rotate(3deg) scale(1.06); }
  60% { transform: translateY(0) rotate(-2deg) scale(.98); }
}

.party-popper {
  font-size: 30px;
  animation: popper-shake .9s ease-in-out infinite;
}

.party-popper.left { transform-origin: 80% 80%; animation-delay: .1s; }
.party-popper.right { transform-origin: 20% 80%; animation-delay: .35s; }

@keyframes popper-shake {
  0%, 100% { transform: rotate(0) scale(1); }
  30% { transform: rotate(-16deg) scale(1.14); }
  60% { transform: rotate(10deg) scale(1.04); }
}

.btn-big { padding: 13px 20px; font-size: 15px; }

.linkbtn {
  margin-top: 12px;
  padding: 6px;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--ink-soft);
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}

.linkbtn:hover { color: var(--ink); }

.victory-crest { font-size: 52px; animation: crest-in .6s cubic-bezier(.2, 1.6, .4, 1); }

.lost-crest {
  font-size: 52px;
  filter: grayscale(.7);
  animation: crest-drop .55s cubic-bezier(.3, 1.3, .5, 1);
}

@keyframes crest-drop {
  from { transform: translateY(-18px) rotate(-12deg); opacity: 0; }
  to { transform: none; opacity: 1; }
}

@keyframes crest-in {
  from { transform: scale(.3) rotate(-25deg); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.victory-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; }

.vstat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 9px 4px;
  background: #faf7f3;
  border: 1px solid #f0e8e0;
  border-radius: 13px;
}

.vstat small { font-size: 10px; color: var(--ink-soft); }
.vstat strong { font-size: 14px; font-variant-numeric: tabular-nums; }
.victory-note { margin: 12px 0 0; font-size: 13px; color: var(--ink-soft); }
.victory-rank { margin: 12px 0 0; font-size: 15px; font-weight: 800; color: #d9822b; }
.victory-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 18px; }

/* ---------------------------------------------------------------- fx layer */

#fx-layer { position: fixed; inset: 0; z-index: 90; pointer-events: none; overflow: hidden; }

.fx { position: fixed; will-change: transform, opacity; }

.fx-spark {
  font-size: 17px;
  transform: translate(-50%, -50%);
  animation: fx-fly var(--dur, 700ms) cubic-bezier(.16, .8, .3, 1) forwards;
}

@keyframes fx-fly {
  from { transform: translate(-50%, -50%) scale(.4); opacity: 1; }
  70% { opacity: 1; }
  to {
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy)))
               scale(var(--scale, 1)) rotate(var(--rot));
    opacity: 0;
  }
}

.fx-ribbon {
  width: 7px;
  height: 13px;
  border-radius: 3px;
  background: var(--col, #ffb4c6);
  transform: translate(-50%, -50%);
  animation: fx-fly var(--dur, 800ms) cubic-bezier(.16, .8, .3, 1) forwards;
}

.fx-ring {
  width: var(--size, 40px);
  height: var(--size, 40px);
  margin: calc(var(--size, 40px) / -2) 0 0 calc(var(--size, 40px) / -2);
  border: 3px solid var(--col, #fff);
  border-radius: 50%;
  animation: fx-ring 600ms ease-out forwards;
}

@keyframes fx-ring {
  from { transform: scale(.3); opacity: .95; }
  to { transform: scale(2.1); opacity: 0; }
}

.fx-fall, .fx-fall-emoji {
  transform: translate(-50%, -50%);
  animation: fx-fall var(--dur, 1600ms) linear var(--delay, 0ms) forwards;
}

.fx-fall { width: 8px; height: 14px; border-radius: 3px; background: var(--col, #ffb4c6); }
.fx-fall-emoji { font-size: 18px; }

@keyframes fx-fall {
  from { transform: translate(-50%, -50%) rotate(0); opacity: 1; }
  to { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)); opacity: 0; }
}

/* party poppers: shoot up out of the corner, then tumble down */
.fx-pop, .fx-pop-emoji {
  transform: translate(-50%, -50%);
  animation: fx-pop var(--dur, 1800ms) cubic-bezier(.2, .55, .35, 1) var(--delay, 0ms) forwards;
}

.fx-pop { width: 6px; height: var(--len, 14px); border-radius: 3px; background: var(--col, #ffb4c6); }
.fx-pop-emoji { font-size: 19px; }

@keyframes fx-pop {
  0% { transform: translate(-50%, -50%) rotate(0); opacity: 1; }
  45% {
    transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy)))
               rotate(calc(var(--rot) * .6));
    opacity: 1;
  }
  100% {
    transform: translate(calc(-50% + var(--dx) * 1.15), calc(-50% + var(--dy) + var(--fall)))
               rotate(var(--rot));
    opacity: 0;
  }
}

.toast {
  position: fixed;
  left: 50%;
  top: 18px;
  transform: translateX(-50%);
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  background: rgba(59, 51, 53, .92);
  border-radius: 999px;
  box-shadow: var(--shadow);
  animation: toast-in .26s ease;
}

.toast-out { animation: toast-out .5s ease forwards; }

@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -12px); } }
@keyframes toast-out { to { opacity: 0; transform: translate(-50%, -12px); } }

/* --------------------------------------------------------------- responsive */

@media (max-width: 440px) {
  #app { padding-left: 12px; padding-right: 12px; }
  .menu-grid { gap: 10px; }
  .tile { padding: 14px 12px; }
  .level-grid { grid-template-columns: repeat(auto-fill, minmax(66px, 1fr)); gap: 8px; }
  .tab small { display: none; }
  .victory-stats { grid-template-columns: repeat(2, 1fr); }
  /* keep the three game buttons on one row */
  .game-actions { gap: 7px; }
  .game-actions .btn { padding: 10px 11px; font-size: 12.5px; }
}

@media (min-width: 720px) {
  #app { padding-top: 26px; }
  .board { max-width: 520px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ===================================================== seven-day streak reward */

/* A premium black-metal ring earned from the Daily Walk, not solved levels. */
.frame-night {
  isolation: isolate;
  background:
    radial-gradient(circle at 28% 18%, rgba(255, 255, 255, .42) 0 3%, transparent 4%),
    conic-gradient(from 35deg, #050608, #343b46, #090b0f, #7d8794, #171a20, #030405, #3d444f, #050608);
  box-shadow:
    inset 0 0 0 2px rgba(235, 241, 248, .82),
    inset 0 0 0 5px rgba(5, 6, 8, .88),
    0 0 0 1px #090b0e,
    0 6px 14px rgba(10, 12, 16, .32),
    0 0 14px rgba(118, 133, 154, .28);
  animation: night-hound-glow 3.4s ease-in-out infinite;
}

.frame-night::before {
  content: "";
  position: absolute;
  inset: 5%;
  z-index: 2;
  pointer-events: none;
  border: 1px solid rgba(227, 234, 243, .55);
  border-radius: 26%;
  box-shadow: inset 0 0 7px rgba(0, 0, 0, .65);
}

.frame-night > .dogav {
  box-shadow: 0 0 0 2px rgba(11, 13, 17, .72);
}

@keyframes night-hound-glow {
  50% {
    box-shadow:
      inset 0 0 0 2px rgba(255, 255, 255, .92),
      inset 0 0 0 5px rgba(5, 6, 8, .9),
      0 0 0 1px #090b0e,
      0 7px 16px rgba(10, 12, 16, .38),
      0 0 20px rgba(120, 143, 174, .46);
  }
}

.daily-calendar {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 5px;
  margin: 11px 0 10px;
  padding: 0;
  list-style: none;
}

.daily-calendar-day {
  position: relative;
  min-width: 0;
  padding: 6px 2px 5px;
  text-align: center;
  color: #9a8f8e;
  background: #f7f3ef;
  border: 1px solid #ebe3dc;
  border-radius: 11px;
  box-shadow: inset 0 1px rgba(255, 255, 255, .7);
}

.daily-weekday,
.daily-month {
  display: block;
  overflow: hidden;
  font-size: 7.5px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: .2px;
  text-transform: uppercase;
  text-overflow: clip;
  white-space: nowrap;
}

.daily-day-number {
  display: block;
  margin: 2px 0 1px;
  font-size: 15px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.daily-mark {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  margin: 5px auto 0;
  font-size: 10px;
  font-weight: 900;
  color: #a99f9d;
  background: #e9e3de;
  border-radius: 50%;
}

.daily-calendar-day.completed {
  color: #326d55;
  background: linear-gradient(160deg, #f3fff7, #dcf5e6);
  border-color: #b9e3c9;
}

.daily-calendar-day.completed .daily-mark {
  color: #fff;
  background: linear-gradient(145deg, #58bd86, #359c68);
  box-shadow: 0 2px 5px rgba(53, 156, 104, .28);
}

.daily-calendar-day.current {
  color: var(--ink);
  border-color: #ff9f81;
  box-shadow: 0 0 0 2px rgba(255, 143, 122, .2), inset 0 1px #fff;
  transform: translateY(-2px);
}

.daily-calendar-day.current:not(.completed) {
  background: linear-gradient(160deg, #fff8f2, #ffede3);
}

.daily-calendar-day.current:not(.completed) .daily-mark {
  font-size: 11px;
  background: #ffd7c8;
}

.daily-calendar-day.reward-day:not(.completed) {
  border-style: dashed;
  border-color: #d7b257;
  background: linear-gradient(160deg, #fffdf4, #fff4d5);
}

.daily-calendar-day.reward-day .daily-mark {
  font-size: 12px;
}

.daily-reward {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0 0 12px;
  padding: 10px 11px;
  background: linear-gradient(145deg, #f3f4f6, #e4e7eb);
  border: 1px solid #cfd4db;
  border-radius: 16px;
  box-shadow: var(--shadow-sm);
}

.daily-reward.unlocked {
  background: linear-gradient(145deg, #f7fafc, #e4edf6);
  border-color: #9eacbd;
  box-shadow: 0 7px 18px rgba(31, 39, 50, .14), 0 0 0 2px rgba(137, 156, 181, .12);
}

.daily-reward-preview {
  position: relative;
  flex: 0 0 52px;
  width: 52px;
}

.daily-reward-preview > .frame { width: 52px; }

.daily-reward-lock {
  position: absolute;
  right: -5px;
  bottom: -4px;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  font-size: 10px;
  color: #fff;
  background: #252a32;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 3px 7px rgba(15, 18, 23, .28);
}

.daily-reward.unlocked .daily-reward-lock { background: #3ca56d; }
.daily-reward-copy { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.daily-reward-copy small { font-size: 8px; font-weight: 900; letter-spacing: 1.2px; color: #687383; }
.daily-reward-copy strong { margin: 1px 0 2px; font-size: 14px; color: #20242b; }
.daily-reward-copy span { font-size: 9.5px; line-height: 1.25; color: #747d89; }

.victory-frame-win {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 0 0;
  padding: 11px 13px;
  text-align: left;
  color: #f8fafc;
  background: linear-gradient(145deg, #272c34, #0b0d11);
  border: 1px solid #657080;
  border-radius: 16px;
  box-shadow: 0 8px 20px rgba(12, 14, 18, .24);
}

.victory-frame-preview { flex: 0 0 54px; width: 54px; }
.victory-frame-preview > .frame { width: 54px; }
.victory-frame-copy { display: flex; flex-direction: column; min-width: 0; }
.victory-frame-copy small { font-size: 8px; font-weight: 900; letter-spacing: 1px; color: #aeb9c8; }
.victory-frame-copy strong { margin: 2px 0; font-size: 15px; color: #fff; }
.victory-frame-copy span { font-size: 10px; color: #c6ced8; }

@media (max-width: 380px) {
  .daily-calendar { gap: 3px; }
  .daily-calendar-day { padding-right: 1px; padding-left: 1px; border-radius: 9px; }
  .daily-weekday, .daily-month { font-size: 7px; }
  .daily-day-number { font-size: 14px; }
}

/* ========================================================== app launch loader */

body.app-loading { overflow: hidden; }
body.app-loading #app { visibility: hidden; }

.app-loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  padding:
    max(20px, env(safe-area-inset-top))
    max(18px, env(safe-area-inset-right))
    max(20px, env(safe-area-inset-bottom))
    max(18px, env(safe-area-inset-left));
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: contain;
  background:
    radial-gradient(70% 46% at 18% 4%, rgba(255, 215, 177, .62), transparent 72%),
    radial-gradient(62% 44% at 88% 22%, rgba(204, 193, 255, .55), transparent 72%),
    radial-gradient(70% 50% at 50% 105%, rgba(166, 230, 196, .48), transparent 74%),
    linear-gradient(155deg, #f2faf5 0%, #fff8ee 52%, #f0eefb 100%);
  opacity: 1;
  visibility: visible;
  transition: opacity .42s ease, visibility 0s linear .42s;
}

.app-loader::before {
  content: "";
  position: absolute;
  inset: -20%;
  pointer-events: none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='76' height='76' viewBox='0 0 76 76'%3E%3Crect x='8' y='8' width='60' height='60' rx='17' fill='none' stroke='%23985b3c' stroke-opacity='.055' stroke-width='2.5'/%3E%3C/svg%3E");
  background-size: 76px 76px;
  -webkit-mask-image: radial-gradient(circle at 50% 45%, #000 12%, transparent 72%);
  mask-image: radial-gradient(circle at 50% 45%, #000 12%, transparent 72%);
  animation: loader-grid-drift 22s linear infinite;
}

.app-loader::after {
  content: "";
  position: absolute;
  width: min(92vw, 500px);
  aspect-ratio: 1;
  pointer-events: none;
  background: radial-gradient(circle, rgba(255, 255, 255, .82), rgba(255, 255, 255, 0) 68%);
  border-radius: 50%;
  animation: loader-glow 3s ease-in-out infinite;
}

.app-loader.is-leaving {
  opacity: 0;
  visibility: hidden;
}

.loader-stage {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(100%, 430px);
  text-align: center;
  animation: loader-stage-in .7s cubic-bezier(.2, 1.15, .35, 1) both;
}

.loader-wordmark {
  --logo-size: clamp(54px, 18vw, 76px);
  width: fit-content;
  height: auto;
  margin-bottom: -10px;
  overflow: visible;
  filter: drop-shadow(0 8px 13px rgba(99, 67, 50, .1));
}

.loader-puppy-wrap {
  position: relative;
  width: clamp(174px, 48vw, 215px);
  margin: -4px auto 0;
}

.loader-puppy {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.loader-puppy-shadow { fill: rgba(84, 61, 50, .14); }
.loader-puppy-character {
  transform-box: view-box;
  transform-origin: 110px 174px;
  animation: loader-puppy-bob 2.2s ease-in-out infinite;
}

.loader-puppy-tail {
  fill: none;
  stroke: #bd763d;
  stroke-width: 16px;
  stroke-linecap: round;
  transform-box: view-box;
  transform-origin: 157px 132px;
  will-change: transform;
  animation: loader-tail-base 1.3s cubic-bezier(.45, 0, .2, 1) infinite;
}

.loader-puppy-tail-tip {
  transform-box: view-box;
  transform-origin: 188.375px 107.25px;
  will-change: transform;
  animation: loader-tail-tip 1.3s cubic-bezier(.45, 0, .2, 1) infinite;
}

.loader-puppy-body,
.loader-puppy-head { fill: #e7a157; }
.loader-puppy-chest,
.loader-puppy-muzzle,
.loader-puppy-foot { fill: #fff1d6; }
.loader-puppy-ear { fill: #bd763d; }
.loader-puppy-blaze { fill: #fff0d0; opacity: .9; }
.loader-puppy-leg,
.loader-puppy-rest-paw {
  fill: none;
  stroke: #d58e49;
  stroke-width: 17px;
  stroke-linecap: round;
}

.loader-puppy-eye { fill: #3c3333; transform-box: fill-box; transform-origin: center; animation: loader-blink 4.2s linear infinite; }
.loader-eye-shine { fill: #fff; }
.loader-puppy-nose { fill: #3d3333; }
.loader-puppy-mouth { fill: none; stroke: #4b3a37; stroke-width: 2.8px; stroke-linecap: round; }
.loader-puppy-tongue { fill: #ff8fa2; }
.loader-puppy-collar { fill: none; stroke: #8c9bf3; stroke-width: 9px; stroke-linecap: round; }
.loader-puppy-tag { fill: #ffc54f; stroke: #d99d28; stroke-width: 2px; }

.loader-spark {
  position: absolute;
  z-index: 2;
  color: #f3aa31;
  text-shadow: 0 3px 8px rgba(210, 133, 24, .22);
  animation: loader-sparkle 1.5s ease-in-out infinite;
}

.loader-spark-one { top: 19%; right: -2%; font-size: 22px; }
.loader-spark-two { top: 5%; right: 13%; font-size: 13px; animation-delay: .45s; }
.loader-spark-three { top: 36%; right: -7%; font-size: 18px; animation-delay: .8s; }

.loader-quote {
  display: grid;
  place-items: center;
  width: min(100%, 370px);
  min-height: 58px;
  margin: -2px auto 13px;
  padding: 11px 18px;
  font-size: clamp(13px, 3.8vw, 16px);
  font-weight: 750;
  line-height: 1.35;
  color: #5f5050;
  background: rgba(255, 255, 255, .64);
  border: 1px solid rgba(255, 255, 255, .9);
  border-radius: 18px;
  box-shadow: 0 8px 22px rgba(86, 67, 62, .08);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.loader-quote::before,
.loader-quote::after {
  color: #d59470;
  font-size: 18px;
  line-height: 0;
}

.loader-progress {
  width: min(58vw, 226px);
  height: 8px;
  padding: 2px;
  overflow: hidden;
  background: rgba(128, 105, 95, .13);
  border: 1px solid rgba(126, 101, 91, .12);
  border-radius: 99px;
  box-shadow: inset 0 1px 3px rgba(80, 58, 49, .1);
}

.loader-progress span {
  display: block;
  width: 7%;
  height: 100%;
  background: linear-gradient(90deg, #8c9bf3, #aa8eea 48%, #f79454);
  border-radius: inherit;
  box-shadow: 0 0 9px rgba(140, 155, 243, .46);
  animation: loader-progress-fill 1.8s cubic-bezier(.2, .7, .25, 1) forwards;
}

.app-loader.is-ready .loader-progress span {
  width: 100%;
  animation: none;
  transition: width .18s ease-out;
}

.loader-status-text {
  margin: 7px 0 0;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .7px;
  color: #897b7c;
  text-transform: uppercase;
}

@keyframes loader-stage-in {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to { opacity: 1; transform: none; }
}

@keyframes loader-grid-drift {
  to { transform: translate(76px, 76px); }
}

@keyframes loader-glow {
  50% { transform: scale(1.08); opacity: .75; }
}

@keyframes loader-puppy-bob {
  0%, 100% { transform: translateY(0) rotate(-.8deg); }
  50% { transform: translateY(-4px) rotate(.8deg); }
}

@keyframes loader-tail-base {
  0%, 100% { transform: rotate(-3deg); }
  6% { transform: rotate(-5deg); }
  34% { transform: rotate(5deg); }
  47% { transform: rotate(6deg); }
  72% { transform: rotate(-4deg); }
  86% { transform: rotate(-5deg); }
}

@keyframes loader-tail-tip {
  0%, 100% { transform: rotate(-2deg); }
  12% { transform: rotate(-4deg); }
  40% { transform: rotate(7deg); }
  54% { transform: rotate(5deg); }
  78% { transform: rotate(-6deg); }
  92% { transform: rotate(-4deg); }
}

@keyframes loader-blink {
  0%, 45%, 48%, 100% { transform: scaleY(1); }
  46.5% { transform: scaleY(.12); }
}

@keyframes loader-sparkle {
  0%, 100% { transform: translateY(0) scale(.72) rotate(-8deg); opacity: .45; }
  50% { transform: translateY(-4px) scale(1.12) rotate(8deg); opacity: 1; }
}

@keyframes loader-progress-fill {
  0% { width: 7%; }
  58% { width: 62%; }
  100% { width: 88%; }
}

@media (max-width: 380px) {
  .loader-wordmark { --logo-size: clamp(50px, 19vw, 64px); }
  .loader-puppy-wrap { width: min(52vw, 195px); }
  .loader-quote { min-height: 54px; padding: 9px 13px; }
}

@media (max-height: 620px) and (orientation: landscape) {
  .loader-stage { transform: scale(.84); }
  .loader-wordmark { --logo-size: 50px; }
  .loader-puppy-wrap { width: 150px; }
  .loader-quote { min-height: 45px; margin-bottom: 8px; padding: 7px 13px; }
}



/* ---------------------------------------------------- grantable park skins */

.skin-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 6px 0 14px;
}

.skin-opt {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 9px 10px;
  font: inherit;
  color: var(--ink);
  text-align: left;
  background: rgba(255, 255, 255, .76);
  border: 1.5px solid rgba(74, 63, 61, .12);
  border-radius: 13px;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform .14s ease, border-color .14s ease, background .14s ease;
}

.skin-opt:hover { transform: translateY(-2px); }
.skin-opt.selected { border-color: var(--accent); background: #fff1ec; }
.skin-opt.locked { opacity: .58; }
.skin-icon { font-size: 20px; }
.skin-copy { display: flex; min-width: 0; flex-direction: column; line-height: 1.05; }
.skin-copy strong { overflow: hidden; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.skin-copy small { overflow: hidden; font-size: 8.5px; color: var(--ink-soft); text-overflow: ellipsis; white-space: nowrap; }
.skin-swatches { display: flex; gap: 2px; }
.skin-swatches i { display: block; width: 7px; height: 22px; border: 1px solid rgba(0, 0, 0, .08); border-radius: 5px; }

body[data-skin="sunset"] {
  --sky-1: #fff0df;
  --sky-2: #fff7ef;
  --sky-3: #f6d8df;
  --accent: #ef7a62;
  --accent-dark: #da5f4b;
  --gold: #ffbd55;
}

body[data-skin="mint"] {
  --sky-1: #e0f5e8;
  --sky-2: #f2fbf4;
  --sky-3: #dff4ef;
  --accent: #57b98d;
  --accent-dark: #3b9b72;
  --gold: #f0bd55;
}

body[data-skin="midnight"] {
  --sky-1: #dce3fb;
  --sky-2: #f0effc;
  --sky-3: #cad4f3;
  --accent: #697ae8;
  --accent-dark: #5061cc;
  --gold: #f0b95d;
}

body[data-skin="starlight"] {
  --sky-1: #ece9ff;
  --sky-2: #f8f3ff;
  --sky-3: #dfe7ff;
  --accent: #8d7de8;
  --accent-dark: #7161ce;
  --gold: #f1b85a;
}

/* The three below fill the hues the original set left out: teal, pink and
   amber. Each keeps a light sky so the board and ink contrast stay unchanged. */
body[data-skin="lagoon"] {
  --sky-1: #d9f2f2;
  --sky-2: #eefaf9;
  --sky-3: #cdeaf0;
  --accent: #2fa3a8;
  --accent-dark: #1f8489;
  --gold: #eeb84f;
}

body[data-skin="bloom"] {
  --sky-1: #ffe6f0;
  --sky-2: #fff4f8;
  --sky-3: #fbdcec;
  --accent: #e8618f;
  --accent-dark: #c94674;
  --gold: #f7b95c;
}

body[data-skin="autumn"] {
  --sky-1: #fbe9d2;
  --sky-2: #fff6e9;
  --sky-3: #f3dcc4;
  --accent: #c96a34;
  --accent-dark: #a85224;
  --gold: #e8a53f;
}

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

/* ------------------------------------------------------------- tutorial */

.howto-tutorial-note {
  margin: 6px 0 10px;
  font-size: 11px;
  color: var(--ink-soft);
  text-align: center;
}

.sheet-tutorial { text-align: center; }

.tut-progress {
  height: 6px;
  margin: 2px 0 10px;
  overflow: hidden;
  background: #efe7df;
  border-radius: 99px;
}

.tut-progress > span {
  display: block;
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, #ffb08f, var(--accent));
  border-radius: 99px;
  transition: width .3s ease;
}

.tut-step-count {
  margin: 0;
  font-size: 9.5px;
  font-weight: 900;
  letter-spacing: 1.1px;
  color: var(--ink-soft);
  text-transform: uppercase;
}

.tut-title { margin: 4px 0 6px; font-size: 17px; }

.tut-body {
  margin: 0 auto 12px;
  max-width: 34ch;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.tut-body b { color: var(--ink); }

/* The practice grid is deliberately its own component: it must not inherit the
   live board's measured --cell/--gap variables, which only exist in-game. */
.tut-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  width: min(258px, 78vw);
  margin: 0 auto 10px;
}

.tut-cell {
  position: relative;
  aspect-ratio: 1;
  min-width: 0;
  padding: 0;
  display: grid;
  place-items: center;
  font-size: clamp(19px, 6.4vw, 27px);
  line-height: 1;
  background: var(--tile, #eee);
  border: 0;
  border-radius: 13px;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .55), 0 2px 4px rgba(120, 92, 72, .13);
  cursor: pointer;
  transition: transform .14s ease, filter .2s ease, opacity .2s ease;
  touch-action: manipulation;
}

.tut-cell:hover { transform: translateY(-1px); }

/* Fence cross drawn in CSS, matching the real board rather than an emoji. */
.tut-mark.cross::before,
.tut-mark.cross::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44%;
  height: 3px;
  background: rgba(255, 255, 255, .95);
  border-radius: 3px;
  box-shadow: 0 1px 2px rgba(120, 92, 72, .3);
}

.tut-mark.cross::before { transform: translate(-50%, -50%) rotate(45deg); }
.tut-mark.cross::after { transform: translate(-50%, -50%) rotate(-45deg); }

.tut-cell.has-dog { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .8), 0 3px 8px rgba(120, 92, 72, .22); }
.tut-cell.tut-fade { opacity: .38; }
.tut-cell.tut-hl { filter: brightness(1.06) saturate(1.25); box-shadow: inset 0 0 0 3px rgba(255, 143, 122, .75); }

/* The one square the player is being asked to tap. */
.tut-cell.tut-target {
  z-index: 1;
  animation: tut-ring 1.25s ease-in-out infinite;
}

@keyframes tut-ring {
  0%, 100% { box-shadow: inset 0 0 0 3px #fff, 0 0 0 3px var(--accent), 0 0 0 8px rgba(255, 143, 122, .28); }
  50% { box-shadow: inset 0 0 0 3px #fff, 0 0 0 4px var(--accent), 0 0 0 14px rgba(255, 143, 122, 0); }
}

.tut-board.solved .tut-cell { animation: tut-pulse .7s ease; }

@keyframes tut-pulse {
  50% { transform: scale(1.05); }
}

.tut-say {
  min-height: 16px;
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  color: #b35442;
  opacity: 0;
  transition: opacity .2s ease;
}

.tut-say.show { opacity: 1; }

#tut-skip {
  display: block;
  margin: 8px auto 0;
  font-size: 11.5px;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .tut-cell.tut-target { animation: none; box-shadow: inset 0 0 0 3px #fff, 0 0 0 4px var(--accent); }
  .tut-board.solved .tut-cell { animation: none; }
  .tut-progress > span { transition: none; }
}

/* ------------------------------------------------------------- languages */

.setting-block { margin: 12px 0 4px; }
.setting-block .field-label small { font-weight: 600; color: var(--ink-soft); }

.lang-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 6px;
}

.lang-tab {
  min-width: 0;
  padding: 10px 4px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-soft);
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 13px;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: transform .14s ease, border-color .14s ease, background .14s ease;
}

.lang-tab:hover { transform: translateY(-1px); }

.lang-tab.active {
  color: var(--ink);
  background: #fff1ec;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 143, 122, .18);
}

/* ------------------------------------------------------------ bug reports */

.report-form textarea,
.report-file input {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 13px;
}

.report-form textarea {
  min-height: 130px;
  line-height: 1.45;
  resize: vertical;
}

.report-form textarea:focus,
.report-file input:focus { outline: 0; border-color: var(--accent); }

.report-file input { padding: 8px; font-size: 12px; }
.report-file input::file-selector-button {
  margin-right: 9px;
  padding: 7px 10px;
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  background: #faf7f3;
  border: 1px solid #e4d9d0;
  border-radius: 9px;
  cursor: pointer;
}

.report-preview {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: -2px 0 12px;
  padding: 9px;
  background: #faf7f3;
  border: 1px solid #ece3dc;
  border-radius: 13px;
}

.report-preview[hidden] { display: none; }
.report-preview img {
  flex: 0 0 auto;
  width: 72px;
  height: 54px;
  object-fit: cover;
  background: #eee7e1;
  border-radius: 9px;
}
.report-preview > div { min-width: 0; display: grid; gap: 4px; }
.report-preview span {
  overflow: hidden;
  font-size: 11px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.report-preview .linkbtn { width: max-content; margin: 0; font-size: 11px; }

.report-status {
  min-height: 18px;
  margin: 5px 0 10px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--ink-soft);
}
.report-status.success { color: #287c55; }
.report-status.error { color: #b43e49; }
.report-status.partial { color: #976019; }
.report-actions { display: flex; gap: 8px; }
.report-actions .btn { flex: 1 1 0; margin: 0; }

@media (max-width: 420px) {
  .report-actions { flex-direction: column; }
  .report-actions .btn { width: 100%; }
}

/* ----------------------------------------------------------------- legal */

.legal-links { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }

.legal-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 13px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  text-align: left;
  background: #fff;
  border: 2px solid #ece3dc;
  border-radius: 13px;
  cursor: pointer;
  transition: transform .14s ease, border-color .14s ease;
}

.legal-link::after { content: "›"; font-size: 17px; color: var(--ink-soft); }
.legal-link:hover { transform: translateY(-1px); border-color: #dfd1c5; }

.legal-updated {
  margin: 0 0 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--ink-soft);
  text-transform: uppercase;
}

/* Long documents scroll inside the sheet rather than pushing the close button
   off the bottom of a phone screen. */
.legal-body {
  max-height: 56vh;
  margin-bottom: 12px;
  padding-right: 4px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.legal-body p {
  margin: 0 0 11px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-soft);
}

.legal-body p:last-child { margin-bottom: 0; }
.legal-body b { color: var(--ink); }

/* ---------------------------------------------------------------- mascot */

.mascot {
  width: min(198px, 54vw);
  margin: 0 auto 4px;
  line-height: 0;
}

.mascot-svg { width: 100%; height: auto; overflow: visible; }

/* Shared paint, taken from the loading-screen puppy so it is the same dog. */
.mascot-shadow { fill: rgba(84, 61, 50, .14); }
.mascot-body, .mascot-head { fill: #e7a157; }
.mascot-chest, .mascot-muzzle, .mascot-foot { fill: #fff1d6; }
.mascot-ear { fill: #bd763d; }
.mascot-blaze { fill: #fff0d0; opacity: .9; }
.mascot-leg, .mascot-paw { fill: none; stroke: #d58e49; stroke-width: 11px; stroke-linecap: round; }
.mascot-tail { fill: none; stroke: #bd763d; stroke-width: 12px; stroke-linecap: round; }
.mascot-eye { fill: #3c3333; }
.mascot-shine { fill: #fff; }
.mascot-nose { fill: #3d3333; }
.mascot-mouth-happy, .mascot-mouth-sad { fill: none; stroke: #4b3a37; stroke-width: 2.8px; stroke-linecap: round; }
.mascot-brow { fill: none; stroke: #3c3333; stroke-width: 3.2px; stroke-linecap: round; }
.mascot-tongue { fill: #ff8fa2; }
.mascot-collar { fill: none; stroke: #8c9bf3; stroke-width: 9px; stroke-linecap: round; }
.mascot-tag { fill: #ffc54f; stroke: #d99d28; stroke-width: 2px; }
.mascot-tear { fill: #7fc4f5; }
.mascot-spark { font-size: 20px; fill: var(--gold); }

/* Water pooling on the ground. Two stacked ellipses give it a rim, and the
   highlights read as a reflective surface. */
.mascot-pool { fill: #6bb9ef; }
.mascot-pool-lip { fill: #93d0f7; }
.mascot-pool-shine { fill: rgba(255, 255, 255, .72); }

/* Every animated group rotates about its own joint, not the viewBox origin. */
.mascot-char, .mascot-head-group, .mascot-tail, .mascot-tail-tip,
.mascot-ear-l, .mascot-ear-r, .mascot-spark, .mascot-tear {
  transform-box: view-box;
}

.mascot-tail { transform-origin: 157px 138px; }
.mascot-tail-tip { transform-origin: 188px 113px; }
.mascot-ear-l { transform-origin: 74px 66px; }
.mascot-ear-r { transform-origin: 146px 66px; }
.mascot-head-group { transform-origin: 110px 120px; }
.mascot-char { transform-origin: 110px 182px; }

/* Mood switches which face is visible. */
.mascot.is-cheer .mascot-brows-sad,
.mascot.is-cheer .mascot-mouth-sad,
.mascot.is-cheer .mascot-tears,
.mascot.is-cheer .mascot-puddle { display: none; }

/* Crying keeps the eyes open and wide. Hiding them behind squint lines made the
   dog look furious rather than sad. */
.mascot.is-cry .mascot-mouth-happy,
.mascot.is-cry .mascot-tongue,
.mascot.is-cry .mascot-sparks { display: none; }

.mascot.is-cry .mascot-eyes-open {
  transform-box: view-box;
  transform-origin: 110px 80px;
  transform: scale(1.14);
  animation: mascot-eye-wobble 2.6s ease-in-out infinite;
}

@keyframes mascot-eye-wobble {
  0%, 100% { transform: scale(1.14) translateY(0); }
  50% { transform: scale(1.18) translateY(1px); }
}

/* ---- cheering ---- */

.mascot.is-cheer .mascot-char { animation: mascot-hop 620ms ease-in-out infinite; }
.mascot.is-cheer .mascot-head-group { animation: mascot-nod 620ms ease-in-out infinite; }
.mascot.is-cheer .mascot-tail { animation: mascot-wag 180ms ease-in-out infinite; }
.mascot.is-cheer .mascot-tail-tip { animation: mascot-wag-tip 180ms ease-in-out infinite; }
.mascot.is-cheer .mascot-ear-l { animation: mascot-flap-l 620ms ease-in-out infinite; }
.mascot.is-cheer .mascot-ear-r { animation: mascot-flap-r 620ms ease-in-out infinite; }
.mascot.is-cheer .mascot-shadow { animation: mascot-shadow-pulse 620ms ease-in-out infinite; }
.mascot.is-cheer .mascot-tongue { animation: mascot-pant 310ms ease-in-out infinite; transform-box: view-box; transform-origin: 110px 112px; }

@keyframes mascot-hop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  18% { transform: translateY(2px) scale(1.05, .95); }
  50% { transform: translateY(-16px) scale(.97, 1.04); }
  82% { transform: translateY(1px) scale(1.03, .97); }
}

@keyframes mascot-nod {
  0%, 100% { transform: rotate(-3deg); }
  50% { transform: rotate(3deg); }
}

@keyframes mascot-wag {
  0%, 100% { transform: rotate(-22deg); }
  50% { transform: rotate(16deg); }
}

@keyframes mascot-wag-tip {
  0%, 100% { transform: rotate(-14deg); }
  50% { transform: rotate(14deg); }
}

@keyframes mascot-flap-l {
  0%, 100% { transform: rotate(6deg); }
  50% { transform: rotate(-13deg); }
}

@keyframes mascot-flap-r {
  0%, 100% { transform: rotate(-6deg); }
  50% { transform: rotate(13deg); }
}

@keyframes mascot-shadow-pulse {
  0%, 100% { transform: scale(1); opacity: .95; }
  50% { transform: scale(.82); opacity: .5; }
}

@keyframes mascot-pant {
  0%, 100% { transform: scaleY(1); }
  50% { transform: scaleY(1.4); }
}

.mascot-spark { opacity: 0; animation: mascot-twinkle 1.5s ease-in-out infinite; }
.mascot-spark.s1 { animation-delay: 0s; }
.mascot-spark.s2 { animation-delay: .28s; }
.mascot-spark.s3 { animation-delay: .56s; }
.mascot-spark.s4 { animation-delay: .84s; }
.mascot-spark.s5 { animation-delay: 1.1s; font-size: 15px; }

@keyframes mascot-twinkle {
  0%, 100% { opacity: 0; transform: scale(.5) rotate(0deg); }
  40% { opacity: 1; transform: scale(1.15) rotate(18deg); }
  70% { opacity: .5; transform: scale(.9) rotate(-8deg); }
}

/* ---- crying ---- */

.mascot.is-cry .mascot-char { animation: mascot-slump 2.6s ease-in-out infinite; }
.mascot.is-cry .mascot-head-group { animation: mascot-droop 2.6s ease-in-out infinite; }
.mascot.is-cry .mascot-tail { transform: rotate(34deg); }
.mascot.is-cry .mascot-ear-l { transform: rotate(-19deg); }
.mascot.is-cry .mascot-ear-r { transform: rotate(19deg); }
.mascot.is-cry .mascot-body, .mascot.is-cry .mascot-head { fill: #dfa065; }

@keyframes mascot-slump {
  0%, 100% { transform: translateY(4px) scale(1.02, .97); }
  50% { transform: translateY(6px) scale(1.03, .95); }
}

/* A small sob shudder rather than a bounce. */
@keyframes mascot-droop {
  0%, 100% { transform: rotate(4deg) translateY(3px); }
  46% { transform: rotate(4.5deg) translateY(4px); }
  50% { transform: rotate(3deg) translateY(2px); }
  54% { transform: rotate(4.5deg) translateY(4px); }
}

.mascot-tear { opacity: 0; animation: mascot-tear-fall 1.5s ease-in infinite; }
.mascot-tear.t2 { animation-delay: .38s; }
.mascot-tear.t3 { animation-delay: .75s; }
.mascot-tear.t4 { animation-delay: 1.12s; }

/* A trembling lip sells "about to cry" better than any extra tear. */
.mascot.is-cry .mascot-mouth-sad {
  transform-box: view-box;
  transform-origin: 110px 110px;
  animation: mascot-lip-quiver 340ms ease-in-out infinite;
}

@keyframes mascot-lip-quiver {
  0%, 100% { transform: translateX(-.6px) scaleY(1); }
  50% { transform: translateX(.6px) scaleY(1.12); }
}

/* Rolls from the eye down past the muzzle and fades. It deliberately stops
   short of the chest: a tear tracking across the body looked wrong. */
@keyframes mascot-tear-fall {
  0% { opacity: 0; transform: translateY(0) scale(.5); }
  18% { opacity: 1; transform: translateY(2px) scale(1); }
  72% { opacity: .9; transform: translateY(28px) scale(1.05); }
  100% { opacity: 0; transform: translateY(40px) scale(.72); }
}

/* The pool creeps outwards as if still filling, with a slow surface shimmer. */
.mascot.is-cry .mascot-puddle {
  transform-box: view-box;
  transform-origin: 110px 184px;
  animation: mascot-pool-grow 3.4s ease-in-out infinite;
}

@keyframes mascot-pool-grow {
  0%, 100% { transform: scale(.94, .9); opacity: .92; }
  50% { transform: scale(1.03, 1.06); opacity: 1; }
}

.mascot-pool-shine { animation: mascot-pool-shimmer 2.6s ease-in-out infinite; }
.mascot-pool-shine:last-of-type { animation-delay: 1.1s; }

@keyframes mascot-pool-shimmer {
  0%, 100% { opacity: .3; }
  50% { opacity: .85; }
}



/* Entry: the dog arrives rather than appearing. */
.mascot.is-in .mascot-char { animation-delay: 320ms; }
.mascot.is-in .mascot-svg { animation: mascot-enter 420ms cubic-bezier(.2, 1.5, .35, 1) both; }

@keyframes mascot-enter {
  from { opacity: 0; transform: translateY(26px) scale(.72); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .mascot * { animation: none !important; }
  .mascot-spark, .mascot-tear { opacity: .9; }
}

/* ------------------------------------------------- themed result sheets */

/* Win and loss now read as different places, not the same card with new text.
   Both stay inside the app's palette: warm sun for a win, cool dusk for a loss. */
.sheet-victory {
  background:
    radial-gradient(120% 78% at 50% -12%, rgba(255, 196, 74, .34) 0%, transparent 62%),
    linear-gradient(168deg, #fffdf4, #fff4e2 58%, #ffeacd);
  border: 1px solid #f3d9a6;
}

#modal-victory .sheet-victory h3 { color: #8a5a1c; }
#modal-victory .victory-sub { color: #a67b46; }

#modal-lost .sheet-victory {
  background:
    radial-gradient(120% 78% at 50% -12%, rgba(140, 155, 243, .26) 0%, transparent 62%),
    linear-gradient(168deg, #fbfcff, #eef1fb 58%, #e6eaf7);
  border: 1px solid #cfd6ee;
}

#modal-lost .sheet-victory h3 { color: #46527f; }
#modal-lost .victory-note { color: #6b7495; }
#modal-lost .vstat { background: rgba(255, 255, 255, .72); border-color: #d8dEEF; }

/* ----------------------------------------------- menu: Play + Infinite Parks */

#btn-infinite-big { margin-top: 11px; }

/* Sub-label under a big button, e.g. the endless-parks tally. */
.bigbtn-note {
  margin: 7px 0 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
  text-align: center;
}


