@import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Baloo+2:wght@500;600;700;800&display=swap');

body {
  font-family: 'Fredoka', 'Baloo 2', system-ui, sans-serif;
}

.font-toon {
  font-family: 'Baloo 2', 'Fredoka', system-ui, sans-serif;
}

.bg-grid {
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.07) 1px, transparent 0);
  background-size: 24px 24px;
}

/* Subtle matte grain overlay - keeps colorful surfaces from looking glossy/plastic */
.matte-grain {
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.05) 1px, transparent 0);
  background-size: 3px 3px;
}

.scrollbar-thin::-webkit-scrollbar {
  width: 6px;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
  background-color: rgba(148, 163, 184, 0.5);
  border-radius: 999px;
}
.scrollbar-thin::-webkit-scrollbar-track {
  background: transparent;
}

/* ---- Ambient animated color blobs (aurora background) ---- */
.blob {
  position: absolute;
  width: 34rem;
  height: 34rem;
  border-radius: 9999px;
  filter: blur(90px);
  mix-blend-mode: screen;
  will-change: transform;
  pointer-events: none;
}
.blob-violet { top: -9rem; left: -8rem; background: #8b5cf6; opacity: 0.35; animation: blob-drift-a 22s ease-in-out infinite alternate; }
.blob-fuchsia { top: 8%; right: -10rem; background: #ec4899; opacity: 0.3; animation: blob-drift-b 26s ease-in-out infinite alternate; }
.blob-cyan { bottom: -10rem; left: 18%; background: #22d3ee; opacity: 0.28; animation: blob-drift-c 24s ease-in-out infinite alternate; }
.blob-amber { bottom: 8%; right: 12%; width: 26rem; height: 26rem; background: #f59e0b; opacity: 0.18; animation: blob-drift-d 30s ease-in-out infinite alternate; }

@keyframes blob-drift-a { from { transform: translate(0,0) scale(1); } to { transform: translate(5rem, 4rem) scale(1.15); } }
@keyframes blob-drift-b { from { transform: translate(0,0) scale(1); } to { transform: translate(-4rem, 5rem) scale(0.9); } }
@keyframes blob-drift-c { from { transform: translate(0,0) scale(1); } to { transform: translate(4rem, -4rem) scale(1.1); } }
@keyframes blob-drift-d { from { transform: translate(0,0) scale(1); } to { transform: translate(-5rem, -3rem) scale(1.08); } }

/* ---- Entrance animations ---- */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
.fade-up {
  animation: fade-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.fade-up-1 { animation-delay: 0.05s; }
.fade-up-2 { animation-delay: 0.12s; }
.fade-up-3 { animation-delay: 0.19s; }
.fade-up-4 { animation-delay: 0.26s; }
.fade-up-5 { animation-delay: 0.33s; }

/* ---- Gradient text / animated gradient border ---- */
@keyframes gradient-shift {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
.gradient-text {
  background: linear-gradient(90deg, #a78bfa, #f472b6, #22d3ee, #a78bfa);
  background-size: 300% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: gradient-shift 6s ease-in-out infinite;
}

/* ---- Pulse ring (waiting indicators) ---- */
@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.5); }
  100% { box-shadow: 0 0 0 12px rgba(56, 189, 248, 0); }
}
.pulse-ring {
  animation: pulse-ring 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* ---- Chessboard piece + highlight animation ---- */
@keyframes piece-pop {
  from { transform: scale(0.65); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
.piece-pop {
  animation: piece-pop 0.16s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes check-glow {
  0%, 100% { box-shadow: inset 0 0 0 3px rgba(244, 63, 94, 0.9), 0 0 18px 2px rgba(244, 63, 94, 0.5); }
  50% { box-shadow: inset 0 0 0 3px rgba(244, 63, 94, 0.5), 0 0 6px 1px rgba(244, 63, 94, 0.2); }
}
.check-glow {
  animation: check-glow 1.1s ease-in-out infinite;
}

@keyframes last-move-shimmer {
  0% { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
.last-move-highlight {
  background-image: linear-gradient(120deg, rgba(251, 146, 60, 0.5), rgba(45, 212, 191, 0.45), rgba(251, 146, 60, 0.5));
  background-size: 200% 200%;
  animation: last-move-shimmer 3s linear infinite;
}

/* ---- Button press feedback ---- */
.press {
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.press:active {
  transform: scale(0.96);
}

/* ---- Flat design: solid-fill buttons/cards with a tactile offset shadow
   instead of gradients or glass blur ---- */
.flat-shadow {
  box-shadow: 5px 5px 0 0 rgba(0, 0, 0, 0.4);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.flat-shadow:hover {
  box-shadow: 7px 7px 0 0 rgba(0, 0, 0, 0.45);
  transform: translate(-2px, -2px);
}
.flat-shadow:active {
  box-shadow: 1px 1px 0 0 rgba(0, 0, 0, 0.45);
  transform: translate(3px, 3px);
}

@keyframes icon-bounce {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  30% { transform: translateY(-7px) rotate(-10deg); }
  60% { transform: translateY(0) rotate(5deg); }
}
.group:hover .bounce-target {
  animation: icon-bounce 0.6s ease;
}

@keyframes color-cycle {
  0%, 100% { color: #fb923c; }
  33% { color: #f472b6; }
  66% { color: #2dd4bf; }
}
.flat-color-cycle {
  animation: color-cycle 4s ease-in-out infinite;
}

/* ---- Cartoon design system: thick outlines, chunky comic shadows,
   wiggle/squash/bob motion instead of subtle glass/gradient effects ---- */

/* Comic-book "pop" button: thick dark outline + a big flat offset shadow
   that squashes down to almost nothing on press, like a pressed button
   sinking into the page. Works on any solid bg-color element. */
.toon-shadow {
  border: 3px solid #1e1b2e;
  box-shadow: 6px 6px 0 0 #1e1b2e;
  transition: box-shadow 0.12s ease, transform 0.12s ease;
}
.toon-shadow:hover {
  box-shadow: 8px 8px 0 0 #1e1b2e;
  transform: translate(-2px, -2px);
}
.toon-shadow:active {
  box-shadow: 1px 1px 0 0 #1e1b2e;
  transform: translate(5px, 5px);
}

@keyframes wiggle {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-6deg); }
  75% { transform: rotate(6deg); }
}
.wiggle-hover:hover {
  animation: wiggle 0.4s ease-in-out;
}

@keyframes squash {
  0% { transform: scale(1); }
  40% { transform: scale(0.92, 1.08); }
  100% { transform: scale(1); }
}
.squash-click:active {
  animation: squash 0.22s ease;
}

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
.bob {
  animation: bob 2.4s ease-in-out infinite;
}

/* Secondary float variants for layered illustration scenes (e.g. the
   hero board/mascot/sparkle grouping): same bob motion but a different
   cycle length and start delay so multiple floating pieces in one
   composition don't move in lockstep. */
.bob-slow {
  animation: bob 3.6s ease-in-out infinite;
  animation-delay: 0.4s;
}
.bob-delay {
  animation: bob 2.4s ease-in-out infinite;
  animation-delay: 0.9s;
}

@keyframes pop-in-bounce {
  0% { transform: scale(0.3) rotate(-8deg); opacity: 0; }
  60% { transform: scale(1.15) rotate(3deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
.pop-in-bounce {
  animation: pop-in-bounce 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Legal-move hint markers: bounce in, then keep gently breathing so
   possible moves feel alive instead of static. */
@keyframes hint-pulse {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50% { transform: scale(1.18); opacity: 1; }
}
.move-hint {
  animation: pop-in-bounce 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both,
             hint-pulse 1.2s ease-in-out 0.35s infinite;
}

@keyframes toon-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.toon-spin {
  animation: toon-spin 2.5s linear infinite;
}

/* ---- Warm flat-vector design system: white/cream surfaces, soft colored
   shadows instead of thick black comic outlines, gentle lift on hover.
   This is the current design direction - prefer these over .toon-shadow
   for new work (that class is kept only so nothing old breaks). ---- */
.soft-card {
  background: #fff;
  border-radius: 1.5rem;
  box-shadow: 0 2px 8px rgba(120, 72, 40, 0.08), 0 10px 24px -8px rgba(120, 72, 40, 0.12);
}

.warm-shadow {
  box-shadow: 0 4px 0 0 rgba(0, 0, 0, 0.12), 0 8px 20px -6px rgba(120, 72, 40, 0.25);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.warm-shadow:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 0 0 rgba(0, 0, 0, 0.12), 0 12px 24px -6px rgba(120, 72, 40, 0.3);
}
.warm-shadow:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.12), 0 4px 10px -4px rgba(120, 72, 40, 0.25);
}

/* Soft blob shapes for decorative illustration backdrops on a light page
   (unlike .blob, no mix-blend-mode:screen - that only works on dark bg) */
.soft-blob {
  position: absolute;
  border-radius: 9999px;
  filter: blur(2px);
  opacity: 0.5;
  pointer-events: none;
  z-index: -1;
}

/* ---- Flat "highlighter marker" swash behind a headline word - a flat
   rotated color block sitting behind the text, instead of a gradient
   underline. Used to give one word of a heading extra emphasis. ---- */
.marker-highlight {
  position: relative;
  z-index: 0;
  display: inline-block;
}
.marker-highlight::before {
  content: '';
  position: absolute;
  left: -0.12em;
  right: -0.12em;
  top: 0.36em;
  bottom: 0.02em;
  background: #FED7AA; /* orange-200, flat */
  border-radius: 0.5em 0.7em 0.6em 0.8em;
  transform: rotate(-2deg);
  z-index: -1;
}

/* ---- Move list contrast fix ----
   singleplayer.js builds each move-history row with hardcoded dark-theme
   classes (text-white for the white player's move) that predate the warm
   light theme and are outside the three color tokens the JS owns for this
   pass. On the new white .soft-card background that text is invisible, so
   this scoped override (not a class it toggles) restores legibility
   without touching singleplayer.js. */
#move-list .text-white {
  color: #292524 !important; /* stone-800 */
}
#move-list .text-slate-300 {
  color: #78716c !important; /* stone-500 - black's move, muted but legible on white */
}

/* ---- Loading dots (thinking / waiting states) ---- */
@keyframes dot-bounce {
  0%, 80%, 100% { transform: scale(0.6) translateY(0); opacity: 0.5; }
  40% { transform: scale(1) translateY(-6px); opacity: 1; }
}
.loading-dots {
  display: inline-flex;
  gap: 0.25rem;
  align-items: center;
}
.loading-dots span {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 9999px;
  background: currentColor;
  animation: dot-bounce 1s ease-in-out infinite;
}
.loading-dots span:nth-child(2) { animation-delay: 0.15s; }
.loading-dots span:nth-child(3) { animation-delay: 0.3s; }

/* ---- Turn indicator badge (whose move is it) ---- */
@keyframes turn-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(45, 212, 191, 0.5); }
  50% { box-shadow: 0 0 0 6px rgba(45, 212, 191, 0); }
}
.turn-glow {
  animation: turn-glow 1.4s ease-in-out infinite;
}

/* ---- Game-over modal ---- */
@keyframes modal-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.modal-backdrop {
  animation: modal-backdrop-in 0.2s ease-out both;
}

/* ---- Confetti (celebration on win) ---- */
@keyframes confetti-fall {
  0% { transform: translateY(-10px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(140px) rotate(540deg); opacity: 0; }
}
.confetti-piece {
  position: absolute;
  top: 0;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  animation: confetti-fall 1.15s ease-in forwards;
}
