:root{
  /* Colors are indirected through design vars so /api/design can override them at runtime */
  --bg1: var(--color-bg1, #0f0c29);
  --bg2: var(--color-bg2, #302b63);
  --bg3: var(--color-bg3, #24243e);
  --text: var(--color-text, #ffffff);
  --muted:rgba(255,255,255,.7);
  --card:rgba(255,255,255,.08);
  --card2:rgba(255,255,255,.12);
  --good: var(--color-good, #40f99b);
  --warn: var(--color-warn, #ffd166);
  --bad: var(--color-bad, #ff4d6d);
  --shadow: 0 12px 40px rgba(0,0,0,.35);
  --radius: 18px;
}
*{box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{
  margin:0;
  font-family: ui-rounded, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji";
  color:var(--text);
  background: radial-gradient(1200px 800px at 30% 10%, rgba(255,255,255,.08), transparent 60%),
              linear-gradient(135deg, var(--bg1), var(--bg2), var(--bg3));
}

a{color:#b8c0ff;text-decoration:none}
a:hover{text-decoration:underline}

.container{max-width:980px;margin:0 auto;padding:22px}

.header{
  display:flex;gap:14px;align-items:baseline;justify-content:space-between;flex-wrap:wrap;
  margin: 10px 0 18px 0;
}
.title{font-size:34px;letter-spacing:.2px;margin:0}
.subtitle{margin:0;color:var(--muted)}

.card{
  background: var(--card);
  border: 1px solid rgba(255,255,255,.12);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 16px;
  backdrop-filter: blur(8px);
}

.grid{display:grid;grid-template-columns:1fr;gap:14px}
@media (min-width:900px){.grid{grid-template-columns: 1.2fr .8fr}}

.row{display:flex;gap:10px;flex-wrap:wrap}

label{display:block;font-size:13px;color:var(--muted);margin:10px 0 6px}
input,select,button{
  font: inherit;
}
input,select{
  width:100%;
  padding:12px 12px;
  background: rgba(0,0,0,.22);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 12px;
  color: var(--text);
  outline:none;
}
input:focus{border-color: rgba(255,255,255,.38)}

.btn{
  padding: 12px 14px;
  border-radius: var(--btn-radius, 14px);
  border: 1px solid rgba(255,255,255,.20);
  background: var(--btn-bg, rgba(0,0,0,.45));
  color: var(--text);
  cursor:pointer;
  transition: transform .07s ease, background .15s ease;
}
.btn:hover{background: rgba(0,0,0,.55)}
.btn:active{transform: translateY(1px) scale(.99)}
.btn.primary{background: rgba(64,249,155,.22); border-color: rgba(64,249,155,.45)}
.btn.danger{background: rgba(255,77,109,.18); border-color: rgba(255,77,109,.45)}

.pills{display:flex;gap:10px;flex-wrap:wrap}
.pill{
  padding: 10px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.18);
  background: rgba(0,0,0,.18);
  cursor:pointer;
  user-select:none;
}
.pill[aria-pressed="true"]{background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.32)}

.small{font-size:13px;color:var(--muted)}

.table{width:100%;border-collapse:collapse;font-size:14px}
.table th,.table td{padding:10px 8px;border-bottom:1px solid rgba(255,255,255,.10)}
.table th{color:rgba(255,255,255,.8);font-weight:600;text-align:left}

.badge{display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border-radius:999px;background:rgba(0,0,0,.18);border:1px solid rgba(255,255,255,.14)}

.toast{
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: var(--toast-bg, rgba(0,0,0,.75));
  border: 1px solid rgba(255,255,255,.18);
  padding: var(--toast-padding, 12px 20px);
  border-radius: var(--toast-radius, 14px);
  box-shadow: var(--shadow);
  color: var(--toast-color, rgba(255,255,255,.95));
  font-size: var(--toast-font-size, 15px);
  max-width: min(560px, calc(100% - 20px));
  display:none;
  z-index: 999;
}
.toast.show{display:block}

.connLost{
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(40, 8, 12, .92);
  border: 1px solid rgba(255, 77, 109, .55);
  color: rgba(255,255,255,.95);
  padding: 10px 14px;
  border-radius: 14px;
  box-shadow: var(--shadow);
  font-size: 14px;
  z-index: 1000;
}
.connLost[hidden]{display:none}
.connLost button{
  appearance: none;
  border: 1px solid rgba(255,255,255,.35);
  background: rgba(255,255,255,.08);
  color: #fff;
  padding: 6px 12px;
  border-radius: 10px;
  font-size: 13px;
  cursor: pointer;
}
.connLost button:active{background: rgba(255,255,255,.18)}

/* ---- game room ---- */
.gameShell{height:100vh;height:100dvh;display:flex;flex-direction:column;max-width:480px;margin:0 auto;overflow:hidden}
.topBar{
  flex: 0 0 auto;
  padding: 10px 12px 6px;
}
.topBar-primary{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
}
.topBar-right{display:flex;gap:6px;align-items:center;position:relative;flex:0 0 auto}
.playerList{
  position:absolute;
  top:100%;
  right:0;
  margin-top:6px;
  background:rgba(0,0,0,.85);
  border:1px solid rgba(255,255,255,.15);
  border-radius:12px;
  padding:10px 14px;
  min-width:120px;
  max-width:200px;
  z-index:20;
  font-size:14px;
  line-height:1.6;
  white-space:nowrap;
}
.topBar-left{display:flex;align-items:center;gap:8px;flex:0 0 auto;min-width:0}
.counter{font-size:16px;font-weight:800;letter-spacing:.2px;white-space:nowrap;color:var(--muted);display:inline-flex;align-items:center}
.counter span{display:inline-block}
.topBar-height{
  font-size:13px;font-weight:700;
  color:var(--muted);
  white-space:nowrap;
  opacity:0.7;
}
.topBar-timeLeft{
  flex:1 1 auto;
  min-width:0;
  text-align:center;
  font-size:clamp(15px, 5.5vw, 26px);
  font-weight:900;
  letter-spacing:.3px;
  white-space:nowrap;
  overflow:hidden;
}
.badge-compact{padding:6px 8px;font-size:13px}
.topBar-infoBtn{cursor:pointer;font-size:14px;line-height:1;border:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.18)}
.topBar-infoBtn[aria-expanded="true"]{background:rgba(255,255,255,.15);border-color:rgba(255,255,255,.3)}
.topBar-details{
  display:flex;gap:8px;flex-wrap:wrap;align-items:center;
  padding:8px 0 2px;
  animation: topBarFadeIn .15s ease;
}
@keyframes topBarFadeIn{from{opacity:0}to{opacity:1}
}
.topBar-details[hidden]{display:none}
.badge-name{display:inline-flex;align-items:center;gap:6px}
.badge-toggle{display:inline-flex;align-items:center;gap:5px;cursor:pointer;font-size:13px}
.badge-toggle input{position:absolute;opacity:0;pointer-events:none}
.toggle-switch{
  position:relative;width:28px;height:16px;border-radius:8px;flex-shrink:0;
  background:rgba(255,255,255,.2);transition:background .2s;
}
.toggle-switch::after{
  content:'';position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;
  background:#fff;transition:transform .2s;
}
.badge-toggle input:checked+.toggle-switch{background:var(--accent,#f39c12)}
.badge-toggle input:checked+.toggle-switch::after{transform:translateX(12px)}
.diffDot{
  width:10px;height:10px;border-radius:50%;
  background:var(--muted);
  flex-shrink:0;
}
.diffDot[data-diff="easy"]{background:#40f99b}
.diffDot[data-diff="medium"]{background:#ffd166}
.diffDot[data-diff="hard"]{background:#ff4d6d}



.stage{
  position:relative;
  flex: 1 1 auto;
  overflow:hidden;
  visibility:hidden;
}
.stage.ready{
  visibility:visible;
}

.sceneBg{
  position:absolute;
  bottom:0;
  left:0;
  right:0;
  width:100%;
  min-height:100%;
  object-fit:cover;
  object-position: center bottom;
  transform-origin: center bottom;
  transform: scale(1);
  transition: transform .15s ease-out;
  pointer-events:none;
  z-index:0;
  user-select:none;
}
.ground{
  position:absolute;left:0;right:0;bottom:0;height:86px;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,.25));
  border-top: 1px solid rgba(255,255,255,.06);
  z-index:1;
}

.balloon{
  position:absolute;
  left: var(--balloon-left, 67%);
  width: var(--balloon-width, 120px);
  height: var(--balloon-height, 160px);
  transform: translateX(-50%);
  will-change: transform, top;
  cursor:pointer;
  user-select:none;
  z-index:2;
  opacity:0;
  filter: drop-shadow(0 18px 20px rgba(0,0,0,.35));
}

.balloon .hit{
  position:absolute; inset:-18px; border-radius: 60px;
}

.balloonImg{
  width:100%;
  height:100%;
  object-fit:contain;
  pointer-events:none;
  transition: transform 0.15s ease-out;
}

.wobble{animation: wobble 2.4s ease-in-out infinite}
@keyframes wobble{
  0%{transform: rotate(-2deg)}
  50%{transform: rotate(2.5deg)}
  100%{transform: rotate(-2deg)}
}

.shake{animation: shake .35s ease-in-out infinite}
@keyframes shake{
  0%{transform: translateX(-50%) translateY(0)}
  25%{transform: translateX(calc(-50% - 2px)) translateY(0)}
  75%{transform: translateX(calc(-50% + 2px)) translateY(0)}
  100%{transform: translateX(-50%) translateY(0)}
}

.feed{
  position:absolute; left:0; top:54px; bottom: 86px;
  padding: 10px 16px;
  z-index:2;
  max-width: var(--feed-max-width, fit-content);
  display:flex; flex-direction:column; justify-content:flex-end;
  pointer-events:none;
}
.feedList{
  display:flex;flex-direction:column;gap:6px;
  overflow-y:auto;
  pointer-events:auto;
}
.feedItem{
  background: var(--feed-item-bg, rgba(0,0,0,.50));
  border: 1px solid rgba(255,255,255,.12);
  padding: 8px 10px;
  border-radius: 14px;
  color: rgba(255,255,255,.92);
  font-size: var(--feed-item-font-size, 14px);
  will-change: transform, opacity;
}

.sleepBanner{
  display:flex;align-items:center;justify-content:center;gap:8px;
  padding:10px 16px;
  background:rgba(0,0,0,.55);backdrop-filter:blur(8px);
  color:rgba(255,255,255,.9);font-size:15px;font-weight:600;
  text-align:center;z-index:5;
}
.sleepBanner[hidden]{display:none}
.sleepBannerIcon{font-size:20px}
.sleepBannerText{letter-spacing:.2px}

.floatingBtns{position:absolute;top:10px;left:10px;display:flex;flex-direction:row;align-items:center;gap:10px;z-index:3}
.floatingBtns .btn{min-width:44px;min-height:44px;padding:10px;font-size:18px;line-height:1;text-align:center;white-space:nowrap}

.overlay{
  position:absolute; inset:0;
  display:none;
  align-items:center;justify-content:center;
  padding: 18px;
  background: rgba(0,0,0,.45);
  z-index:10;
}
.overlay.show{display:flex}
.overlay .popCard{will-change:transform,opacity}

.popCard{max-width:520px;width:100%;text-align:center}

/* White queen icon — used wherever the Chess Mate game shows up, since the
   black-pawn emoji disappears against the dark background. */
.chessIcon{
  display: inline-block;
  height: 1em; width: 1em;
  vertical-align: -0.15em;
  background: url('/public/chess/Chess_plt45.svg') center/contain no-repeat;
}
/* Bounce-feed badge text is small (13px); bump the queen so it reads at a
   glance like the other emoji badges. */
.feedItem .chessIcon{ height: 1.6em; width: 1.6em; vertical-align: -0.45em; }

.statsCard{
  max-width: 520px; width: 100%;
  text-align: left;
  position: relative;
  max-height: 80vh; overflow-y: auto;
}
.statsTitle{ margin: 0 0 12px; font-size: 22px; text-align: center; }
.statsClose{
  position: absolute; top: 8px; right: 10px;
  background: transparent; border: 0; color: inherit;
  font-size: 18px; cursor: pointer; padding: 6px 10px;
  border-radius: 8px; opacity: .7;
}
.statsClose:hover{ background: rgba(255,255,255,.08); opacity: 1; }
.statsSection{ margin-top: 14px; }
.statsSection h3{
  margin: 0 0 6px; font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted);
}
.statsRow{
  display: grid;
  grid-template-columns: 1.4em 1fr auto auto;
  gap: 10px; align-items: baseline;
  padding: 6px 4px;
  border-bottom: 1px solid rgba(255,255,255,.05);
  font-size: 14px;
}
.statsRow:last-child{ border-bottom: 0; }
.statsRow .rk{ color: var(--muted); font-size: 12px; }
.statsRow .nm{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statsRow .ct{ color: var(--muted); font-size: 12px; }
.statsRow .ft{ font-weight: 700; }
.statsTotals{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 4px;
}
.statsTotal{
  background: rgba(255,255,255,.06);
  border-radius: 10px;
  padding: 10px 8px;
  text-align: center;
}
.statsTotal .v{ font-size: 18px; font-weight: 700; }
.statsTotal .l{ font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ---- per-player drill-down ---- */
.statsHint{
  float: right; font-weight: 500; text-transform: none;
  letter-spacing: 0; opacity: .75;
}
/* Rows that drill down. Reset the button chrome so they sit flush with the
   plain .statsRow siblings, and add a column for the chevron. */
.statsRowBtn{
  width: 100%;
  grid-template-columns: 1.4em 1fr auto auto 0.9em;
  background: transparent; border: 0; border-bottom: 1px solid rgba(255,255,255,.05);
  color: inherit; font: inherit; text-align: left;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.statsRowBtn:hover{ background: rgba(255,255,255,.06); }
.statsRowBtn:active{ background: rgba(255,255,255,.1); }
.statsRowBtn .chev{ color: var(--muted); transition: transform .15s ease; }
.statsRowBtn.open .chev{ transform: rotate(90deg); }
.statsBack{
  background: transparent; border: 0; color: inherit; font: inherit;
  padding: 4px 6px 8px; margin: 0 0 4px -6px;
  opacity: .8; cursor: pointer; font-size: 14px;
}
.statsBack:hover{ opacity: 1; }
.statsTotals6{ grid-template-columns: repeat(3, 1fr); gap: 8px; }
.statsKv{
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 4px; font-size: 14px;
  border-bottom: 1px solid rgba(255,255,255,.05);
}
.statsKv:last-child{ border-bottom: 0; }
.statsKv .k{ color: var(--muted); }
.statsKv .v{ text-align: right; }
.statsExpandPanel{
  padding: 4px 4px 10px 14px;
  border-left: 2px solid rgba(255,255,255,.12);
  margin: 0 0 6px 6px;
}
.statsExpandPanel .statsKv{ font-size: 13px; }
/* Cross-link out of a panel into the other axis of the drill-down. */
.statsGoBtn{
  display: block; width: 100%; margin-top: 8px;
  padding: 8px 10px; border-radius: 10px;
  border: 1px solid rgba(255,255,255,.16);
  background: rgba(255,255,255,.06);
  color: inherit; font: inherit; font-size: 13px;
  text-align: left; cursor: pointer;
}
.statsGoBtn:hover{ background: rgba(255,255,255,.12); }

/* Activity charts. Bars scale to the player's own peak, so the shape of the
   week reads the same whether they bounce twice a day or fifty times. */
.statsBars{
  display: flex; align-items: flex-end; gap: 2px;
  height: 60px; padding: 2px 0;
}
.statsBar{ flex: 1; height: 100%; display: flex; align-items: flex-end; }
.statsBar i{
  display: block; width: 100%; min-height: 2px;
  background: var(--good); border-radius: 2px 2px 0 0;
}
.statsBar.empty i{ background: rgba(255,255,255,.1); height: 2px !important; }
.statsAxis{
  display: flex; justify-content: space-between;
  font-size: 10px; color: var(--muted); margin-top: 4px;
}
.statsHours{ display: flex; gap: 2px; }
.statsHour{
  position: relative; flex: 1; height: 22px;
  border-radius: 3px; background: rgba(255,255,255,.08);
}
/* --fill (0-1) is set per cell inline; drive it through opacity so the strip
   works without color-mix support. */
.statsHour::after{
  content: ''; position: absolute; inset: 0;
  border-radius: 3px; background: var(--good); opacity: var(--fill);
}
.statsWeekdays{ display: flex; gap: 4px; align-items: flex-end; }
.statsWeekday{ flex: 1; text-align: center; font-size: 10px; color: var(--muted); }
.statsWeekdayBar{ height: 40px; display: flex; align-items: flex-end; }
.statsWeekdayBar i{
  display: block; width: 100%; min-height: 2px;
  background: var(--good); border-radius: 3px 3px 0 0;
}
.statsFeed{ max-height: 240px; overflow-y: auto; }
.statsFeedRow{
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 8px; align-items: baseline;
  padding: 5px 4px; font-size: 13px;
  border-bottom: 1px solid rgba(255,255,255,.05);
}
.statsFeedRow:last-child{ border-bottom: 0; }
.statsFeedRow .dt{ color: var(--muted); }
.statsFeedRow .ft{ font-weight: 700; }
.statsFeedRow .tm{ color: var(--muted); font-size: 11px; white-space: nowrap; }
.popTitle{font-size:34px;margin:0 0 8px 0}
.popSub{margin:0;color:var(--muted)}

.confetti{position:absolute;inset:0;pointer-events:none;opacity:.8}

/* balloon pop — animated via GSAP */
.popParticle{
  position:absolute;
  border-radius:50%;
  pointer-events:none;
  z-index:20;
  will-change:transform,opacity;
}

/* ---- puzzle overlay ---- */
.puzzleOverlay{
  position:absolute; inset:0;
  display:flex;
  align-items:flex-start; justify-content:center;
  padding: 18px;
  background: rgba(0,0,0,.55);
  overflow-y:auto;
  -webkit-overflow-scrolling: touch;
  z-index:10;
}
.puzzleOverlay[hidden]{display:none}

.puzzleCard{
  position: relative;
  width: min(820px, 100%);
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 14px;
  backdrop-filter: blur(10px);
}

/* Full-screen toggle button (top-right of the puzzle card) */
.puzzleFsBtn{
  position: absolute;
  top: 8px; right: 8px;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,.20);
  background: rgba(0,0,0,.25);
  color: var(--text);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  z-index: 2;
  transition: background .15s ease, transform .12s ease;
}
@media (hover: hover){.puzzleFsBtn:hover{background: rgba(255,255,255,.14)}}
.puzzleFsBtn:active{transform: scale(.94)}
.puzzleFsBtn[aria-pressed="true"]{
  background: rgba(64,249,155,.22);
  border-color: rgba(64,249,155,.5);
}

/* Maximized layout — fills the viewport so mini-games get the most room */
.puzzleOverlay.fullscreen{
  position: fixed;
  padding: 0;
  align-items: stretch;
  background: rgba(0,0,0,.82);
}
.puzzleOverlay.fullscreen .puzzleCard{
  width: 100%;
  max-width: none;
  min-height: 100%;
  border: none;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
}

.puzzleOptions{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin: 12px 0 12px 0}

.puzzleOpt{
  padding: 10px 10px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.20);
  background: rgba(0,0,0,.18);
  color: var(--text);
  cursor:pointer;
  min-height: 64px;
  font-size: 14px;
  line-height: 1.25;
}
.puzzleOpt{transition:transform .12s ease,background .15s ease,border-color .15s ease,box-shadow .15s ease}
@media (hover: hover){.puzzleOpt:hover{background: rgba(255,255,255,.12)}}
.puzzleOpt:active{background: rgba(255,255,255,.18); transform: scale(.98)}
.puzzleOpt.failed{
  opacity:.55;
  text-decoration: line-through;
  border-color: rgba(255,77,109,.55);
}
.puzzleOpt.in-progress{
  border-color: rgba(64,249,155,.6);
  box-shadow: 0 0 0 1px rgba(64,249,155,.3);
}

/* Solitaire */
.solitaireBoard{
  --card-w: clamp(34px, 11vw, 50px);
  --card-h: calc(var(--card-w) * 1.4);
  --face-step: calc(var(--card-h) * 0.32);
  --hidden-step: calc(var(--card-h) * 0.16);
  display: flex; flex-direction: column; gap: 8px;
  align-items: stretch; user-select: none; touch-action: none;
}
.solTopRow,
.solTableauRow{
  display: grid;
  grid-template-columns: repeat(7, var(--card-w));
  gap: 4px;
  justify-content: center;
}
.solPile{
  width: var(--card-w);
  display: flex; flex-direction: column; align-items: stretch;
}
.solWasteSlot{
  grid-column: span 2;
  height: var(--card-h);
  position: relative;
}
.solWasteSlot .solCard{ position: absolute; top: 0; }
.solWasteSlot .solSlot{ width: var(--card-w); }
.solSidelineRow{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 2px;
}
.solSidelineLabel{
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .6;
}
.solSideline{ width: var(--card-w); position: relative; }
/* When the sideline has buried cards, fake a couple of card edges peeking
   out behind the top card so it reads as a stack at a glance. */
.solSideline.has-stack .solCard{
  box-shadow:
    0 1px 2px rgba(0,0,0,.32),
    2px 2px 0 0 rgba(255,255,255,.22),
    4px 4px 0 0 rgba(255,255,255,.14);
}
.solSidelineCount{
  position: absolute;
  right: -6px;
  bottom: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--accent, #7c4dff);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,.4);
  pointer-events: none;
}
.solSlot{
  width: var(--card-w); height: var(--card-h);
  border-radius: 7px; border: 1px dashed rgba(255,255,255,.28);
  background: rgba(255,255,255,.03);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; opacity: .7;
  transition: background 140ms ease, border-color 140ms ease;
}
.solSlot.canRedeal{
  cursor: pointer; opacity: 1; border-style: solid;
  border-color: rgba(64,249,155,.55);
  background: rgba(64,249,155,.10);
  animation: solSlotGlow 1.8s ease-in-out infinite;
}
@keyframes solSlotGlow{
  0%,100%{ box-shadow: 0 0 0 0 rgba(64,249,155,0); }
  50%   { box-shadow: 0 0 0 4px rgba(64,249,155,.18); }
}
.solCard{
  width: var(--card-w); height: var(--card-h);
  flex-shrink: 0;
  position: relative;
  border-radius: 7px;
  border: 1px solid rgba(0,0,0,.30);
  background: linear-gradient(180deg, #ffffff 0%, #f3f5f8 100%);
  color: #111;
  font-weight: 700;
  line-height: 1.0;
  box-shadow: 0 1px 2px rgba(0,0,0,.32), 0 0 0 0.5px rgba(0,0,0,.10) inset;
  cursor: pointer;
  box-sizing: border-box;
  overflow: hidden;
  transition: transform 90ms ease, box-shadow 120ms ease;
  will-change: transform;
}
.solCard.red{ color: #c0224a; }
.solCard.black{ color: #18202b; }
.solCard.facedown{
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.06) 0 5px, transparent 5px 10px),
    radial-gradient(circle at 50% 35%, #2e5b88 0%, #14304b 60%, #0c2236 100%);
  border-color: rgba(255,255,255,.22);
  box-shadow: 0 1px 2px rgba(0,0,0,.4), inset 0 0 0 2px rgba(255,255,255,.06);
}
.solCard.facedown::after{
  /* subtle decorative diamond on the back */
  content:'';
  position:absolute;
  inset: 20% 22%;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 4px;
  transform: rotate(45deg);
  pointer-events: none;
}
.solCard.faded{ opacity: .58; pointer-events: none; }

/* Corner pips (rank + suit at top-left, mirrored at bottom-right) */
.solCardCorner{
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  font-size: calc(var(--card-w) * 0.30);
  pointer-events: none;
}
.solCardCorner .solCardCornerSuit{
  font-size: calc(var(--card-w) * 0.30);
  margin-top: 1px;
}
.solCardCornerTL{ top: 3px; left: 4px; }
.solCardCornerBR{ bottom: 3px; right: 4px; transform: rotate(180deg); }

/* Big centered suit watermark behind the corner pips */
.solCard::before{
  content: attr(data-suit);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(var(--card-w) * 0.95);
  opacity: 0.12;
  pointer-events: none;
  line-height: 1;
}
.solCard.facedown::before{ content: none; }

.solCard.selected{
  outline: 2px solid rgba(64,249,155,.95);
  outline-offset: -1px;
  transform: translateY(-3px) scale(1.02);
  box-shadow: 0 6px 14px rgba(0,0,0,.45), 0 0 0 0.5px rgba(0,0,0,.10) inset;
  animation: solSelectPop 220ms cubic-bezier(.2,.7,.25,1);
  z-index: 4;
}
@keyframes solSelectPop{
  0%   { transform: translateY(0) scale(1); }
  60%  { transform: translateY(-5px) scale(1.04); }
  100% { transform: translateY(-3px) scale(1.02); }
}
.solCard.flip-in{
  animation: solFlipIn 360ms cubic-bezier(.4,1.4,.5,1);
  transform-origin: 50% 60%;
  z-index: 3;
}
@keyframes solFlipIn{
  0%   { transform: rotateY(85deg) scale(.97); filter: brightness(.7); }
  55%  { transform: rotateY(0deg) scale(1.06); filter: brightness(1.08); }
  100% { transform: rotateY(0deg) scale(1); filter: brightness(1); }
}
.solTableauCol .solCard + .solCard{ margin-top: calc(var(--face-step) - var(--card-h)); }
.solTableauCol .solCard.facedown + .solCard{ margin-top: calc(var(--hidden-step) - var(--card-h)); }
.solCard{ touch-action: none; }
.solCard.dragging{ visibility: hidden; }
.solDragGhost{
  position: fixed; left: 0; top: 0;
  pointer-events: none;
  z-index: 10000;
  transform: translate(-9999px,-9999px);
  filter: drop-shadow(0 12px 22px rgba(0,0,0,.55));
  will-change: transform, filter;
}
.solDragGhost .solCard{
  box-shadow: 0 4px 12px rgba(0,0,0,.48);
}
.solDragGhost.picking-up{
  animation: solPickUp 180ms cubic-bezier(.2,.8,.25,1);
}
@keyframes solPickUp{
  0%   { filter: drop-shadow(0 4px 8px rgba(0,0,0,.4)) scale(1); }
  60%  { filter: drop-shadow(0 18px 26px rgba(0,0,0,.55)); }
  100% { filter: drop-shadow(0 12px 22px rgba(0,0,0,.55)); }
}
.solDragGhost.settling{
  filter: drop-shadow(0 6px 12px rgba(0,0,0,.45));
}
.solDragGhost.springing-back{
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.35));
}
.solPile.drop-hover, .solWasteSlot.drop-hover{
  outline: 2px solid rgba(64,249,155,.95);
  outline-offset: 2px;
  border-radius: 8px;
  background: rgba(64,249,155,.10);
  box-shadow: 0 0 16px rgba(64,249,155,.45);
  transition: background 100ms ease, box-shadow 100ms ease;
}
.solPile.drop-hover-bad, .solWasteSlot.drop-hover-bad{
  outline: 2px dashed rgba(255,77,109,.75);
  outline-offset: 2px;
  border-radius: 8px;
  transition: outline-color 100ms ease;
}
.solitaireBoard .solCard:not(.facedown):not(.faded):active{
  transform: translateY(-1px);
}
.solStock .solCard.facedown:active{
  transform: scale(0.96);
  transition: transform 80ms ease;
}
.solStock:active .solSlot.canRedeal{
  transform: scale(0.96);
  transition: transform 80ms ease;
}
/* Newly-drawn waste cards slide in from stock. Class added by solRender
   when the waste actually grew on this update, so non-draw re-renders
   (selection toggles etc.) don't trigger it. */
.solCard.just-drawn{
  animation: solWasteArrive 240ms cubic-bezier(.2,.7,.25,1);
}
@keyframes solWasteArrive{
  0%   { transform: translateX(-46%) translateY(-2px); opacity: 0; }
  60%  { opacity: 1; }
  100% { transform: translate(0,0); opacity: 1; }
}

/* Edit-menu mode: drag-and-drop reorder */
.puzzleOptions.editing .puzzleOpt{
  cursor: grab;
  border-style: dashed;
  border-color: rgba(255,255,255,.45);
  touch-action: none;
  user-select: none;
}
.puzzleOptions.editing .puzzleOpt:active{ transform: none; cursor: grabbing; }
.puzzleOpt.dragging{
  cursor: grabbing;
  box-shadow: 0 12px 28px rgba(0,0,0,.45);
  opacity: .95;
  transform: scale(1.04);
}
.puzzleOpt-placeholder{
  border-radius: 14px;
  background: rgba(255,255,255,.06);
  border: 1px dashed rgba(255,255,255,.30);
  min-height: 64px;
}
.puzzleEditFooter{
  display:flex; gap:10px; justify-content:center; margin-top:8px; flex-wrap:wrap;
}
.btn.linklike{
  padding: 6px 10px;
  background: transparent;
  border-color: transparent;
  font-size: 13px;
  opacity: .8;
}
.btn.linklike:hover{ background: rgba(255,255,255,.06); opacity: 1; }

.puzzleQuestion{
  margin: 0 0 10px 0;
  font-weight: 700;
  line-height: 1.25;
}

.puzzleImageWrap{
  margin: 6px 0 10px 0;
  border-radius: 14px;
}

.puzzleImg{
  width:100%;
  height:auto;
  border-radius: 14px;
  border:1px solid rgba(255,255,255,.14);
  background: rgba(0,0,0,.25);
  touch-action: pan-x pan-y pinch-zoom;
}
.puzzleImg.zoomed{width:160%; max-width:none}

.answerGrid{display:grid;grid-template-columns:repeat(auto-fit, minmax(88px, 1fr));gap:10px;margin-bottom: 12px}

.ansBtn{
  min-height: 48px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.20);
  background: rgba(255,255,255,.12);
  color: var(--text);
  cursor:pointer;
  font-weight: 700;
  padding: 10px 10px;
  text-align: left;
  line-height: 1.15;
  white-space: normal;
}
.ansBtn{transition:transform .12s ease,background .15s ease,border-color .15s ease}
.ansBtn:active{transform: translateY(1px) scale(.99)}
.ansBtn.wrong{background: rgba(255,77,109,.22); border-color: rgba(255,77,109,.55)}
.ansBtn.right{background: rgba(64,249,155,.18); border-color: rgba(64,249,155,.55)}

/* balloon tooltip */
.balloonTooltip{
  position:absolute;
  bottom: 100%;
  margin-bottom: 12px;
  left: -50px;
  right: -50px;
  width: fit-content;
  max-width: var(--tooltip-max-width, 200px);
  margin-left: auto;
  margin-right: auto;
  background: var(--tooltip-bg, rgba(255,255,255,.95));
  color: var(--tooltip-color, #1a1a2e);
  font-weight: 700;
  font-size: var(--tooltip-font-size, 15px);
  padding: 10px 16px;
  border-radius: 14px;
  box-shadow: 0 8px 30px rgba(0,0,0,.35);
  text-align: center;
  z-index: 5;
  animation: tooltipBounce 1.5s ease-in-out infinite;
  pointer-events: none;
}
.balloonTooltip.below{
  bottom:auto;
  top:100%;
  margin-bottom:0;
  margin-top:12px;
}
.balloonTooltip[hidden]{display:none}
.balloonTooltipArrow{
  position:absolute;
  bottom:-8px;
  left:0;
  right:0;
  margin-left:auto;
  margin-right:auto;
  width:0;height:0;
  border-left:8px solid transparent;
  border-right:8px solid transparent;
  border-top:8px solid var(--tooltip-bg, rgba(255,255,255,.95));
}
.balloonTooltip.below .balloonTooltipArrow{
  bottom:auto;
  top:-8px;
  border-top:none;
  border-bottom:8px solid var(--tooltip-bg, rgba(255,255,255,.95));
}
@keyframes tooltipBounce{
  0%,100%{transform: translateY(0)}
  50%{transform: translateY(-8px)}
}
@keyframes tooltipBounceBelow{
  0%,100%{transform: translateY(0)}
  50%{transform: translateY(8px)}
}
.balloonTooltip.below{animation-name: tooltipBounceBelow}

/* puzzle card — animated via GSAP */

/* Real-time tap/drag mini-games: fast repeated tapping must never be read as a
   text-selection gesture — that's what raises iOS's Copy / Look Up callout
   mid-game. touch-action and preventDefault don't suppress the selection
   recognizer, and taps regularly land off the canvas on a title or message
   line, so the guard goes on the whole screen. These properties inherit, so
   the container covers every child. Add new fast-input games to this list. */
.flappySolve,
.circleSolve,
.colorMatchSolve{
  -webkit-user-select:none;
  user-select:none;
  -webkit-touch-callout:none;
  -webkit-tap-highlight-color:transparent;
}

/* ---- Word Guess ---- */
.wordguessSolve{touch-action:manipulation}
.wgGrid{
  display:flex;flex-direction:column;align-items:center;gap:5px;margin:10px 0;
}
.wgRow{display:flex;gap:5px}
.wgTile{
  width:52px;height:52px;
  border:2px solid rgba(255,255,255,.2);
  border-radius:4px;
  display:flex;align-items:center;justify-content:center;
  font-size:24px;font-weight:800;
  text-transform:uppercase;
  color:var(--text);
  background:transparent;
  transition:border-color .1s ease;
}
.wgTile:not(:empty){border-color:rgba(255,255,255,.4)}
.wgTile[data-state="correct"]{background:#538d4e;border-color:#538d4e}
.wgTile[data-state="present"]{background:#b59f3b;border-color:#b59f3b}
.wgTile[data-state="absent"]{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.12)}
/* wg tile flip — animated via GSAP */
.wgMessage{
  text-align:center;min-height:24px;
  font-weight:700;font-size:15px;
  margin:8px 0;color:var(--text);
}
.wgKeyboard{
  display:flex;flex-direction:column;align-items:center;gap:5px;margin:8px 0;
}
.wgKeyRow{display:flex;gap:4px}
.wgKey{
  min-width:30px;height:46px;
  border-radius:6px;border:none;
  background:rgba(255,255,255,.2);
  color:var(--text);
  font-weight:700;font-size:13px;
  cursor:pointer;padding:0 8px;
  display:flex;align-items:center;justify-content:center;
  transition:background .1s ease;
  touch-action:manipulation;
  -webkit-user-select:none;user-select:none;
}
.wgKey:active{transform:scale(.95)}
.wgKeyWide{min-width:52px;font-size:12px}
.wgKey[data-state="correct"]{background:#538d4e}
.wgKey[data-state="present"]{background:#b59f3b}
.wgKey[data-state="absent"]{background:rgba(255,255,255,.08);color:rgba(255,255,255,.4)}
@media (max-width:400px){
  .wgTile{width:44px;height:44px;font-size:20px}
  .wgKey{min-width:26px;height:40px;font-size:12px}
  .wgKeyWide{min-width:44px}
}

/* ---- emoji match ---- */
.emojiMatchSolve{touch-action:manipulation;text-align:center}
.emGrid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:8px;
  max-width:280px;
  margin:12px auto;
}
.emCard{
  aspect-ratio:1;
  border-radius:12px;
  border:2px solid rgba(255,255,255,.2);
  background:rgba(0,0,0,.25);
  font-size:28px;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  user-select:none;
  touch-action:manipulation;
  transition:transform .12s ease,border-color .15s ease,background .15s ease;
}
.emCard:active{transform:scale(.93)}
.emCard.selected{border-color:rgba(255,255,255,.7);background:rgba(255,255,255,.12)}
.emCard[data-state="revealed"]{background:rgba(255,255,255,.15);border-color:rgba(255,255,255,.35)}
.emCard[data-state="matched"]{
  background:rgba(64,249,155,.18);
  border-color:rgba(64,249,155,.5);
  cursor:default;
}
/* em card flip — animated via GSAP */
.emMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
@media (max-width:400px){
  .emGrid{max-width:240px;gap:5px}
  .emCard{font-size:20px;border-radius:10px}
}

/* ---- match three ---- */
.bejeweledSolve{
  touch-action:manipulation;
  text-align:center;
  --bj-gold:#e8c56a;
  --bj-gold-deep:#8a6420;
}
.bjHeader{margin:0 0 10px}
.bjHeader h3{
  margin:0 0 4px;
  font-size:22px;
  letter-spacing:.04em;
  color:#ffe7a8;
  text-shadow:0 1px 0 #5a3a10, 0 0 18px rgba(232,197,106,.35);
}
.bjHeader .small{margin:0 0 10px;opacity:.85}
.bjHud{
  display:flex;
  justify-content:center;
  gap:10px;
  margin:0 0 10px;
}
.bjHudChip{
  min-width:108px;
  padding:7px 14px 8px;
  border-radius:14px;
  background:
    linear-gradient(180deg, rgba(255,226,150,.18), rgba(40,18,10,.35)),
    rgba(20,8,14,.55);
  border:1px solid rgba(232,197,106,.55);
  box-shadow:inset 0 1px 0 rgba(255,240,200,.28), 0 4px 12px rgba(0,0,0,.25);
}
.bjHudLabel{
  display:block;
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:rgba(255,230,180,.72);
}
.bjHudValue{
  display:block;
  font-size:20px;
  line-height:1.15;
  font-weight:800;
  color:#fff6d4;
  font-variant-numeric:tabular-nums;
}
.bjHudValue.bjHudWarn{color:#ffd166}
.bjHudValue.bjHudBad{color:#ff6b6b}
.bjLegend{
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:6px 12px;
  margin:0 4px 4px;
  padding:0;
  font-size:11px;
  letter-spacing:.01em;
  color:rgba(255,236,210,.78);
}
.bjLegend li{
  display:inline-flex;
  align-items:center;
  gap:5px;
}
.bjLegend img{
  width:22px;height:22px;
  object-fit:contain;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.5));
}
.bjBoard{
  display:inline-block;
  margin:4px auto 0;
  padding:14px;
  border-radius:24px;
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(255,220,150,.22), transparent 55%),
    linear-gradient(180deg, #6a3a1c 0%, #3a1c10 42%, #241008 100%);
  border:2px solid var(--bj-gold);
  box-shadow:
    0 0 0 3px #2a1408,
    inset 0 1px 0 rgba(255,236,180,.55),
    inset 0 -10px 18px rgba(0,0,0,.35),
    0 16px 36px rgba(0,0,0,.45);
}
.bjGrid{
  display:grid;
  gap:5px;
  max-width:320px;
  margin:0 auto;
  position:relative;
  touch-action:none;
  overflow:visible;
  padding:8px;
  border-radius:16px;
  background:
    radial-gradient(80% 60% at 50% 35%, rgba(90,20,40,.15), rgba(10,2,8,.35)),
    url('/public/gems/board-velvet.jpg') center/cover;
  box-shadow:inset 0 6px 16px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,210,150,.12);
}
.bjCell{
  aspect-ratio:1;
  border-radius:12px;
  border:1px solid rgba(255,210,170,.08);
  background:
    radial-gradient(120% 90% at 50% 18%, rgba(255,255,255,.1), transparent 52%),
    linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.42));
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:grab;
  user-select:none;
  touch-action:none;
  position:relative;
  z-index:1;
  contain:layout style;
  box-shadow:
    inset 0 3px 6px rgba(0,0,0,.5),
    inset 0 -1px 0 rgba(255,255,255,.08);
}
.bjCell.bjCellAlt{
  background:
    radial-gradient(120% 90% at 50% 18%, rgba(255,255,255,.07), transparent 52%),
    linear-gradient(180deg, rgba(0,0,0,.12), rgba(0,0,0,.5));
}
.bjGem{
  width:88%;
  height:88%;
  object-fit:contain;
  pointer-events:none;
  user-select:none;
  -webkit-user-drag:none;
  transform:translateZ(0);
}
.bjRocketV{transform:rotate(-90deg)}
.bjHue-red{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(255,50,70,.22)}
.bjHue-blue{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(60,120,255,.24)}
.bjHue-yellow{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(255,210,60,.24)}
.bjHue-green{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(40,220,110,.22)}
.bjHue-orange{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(255,140,40,.24)}
.bjHue-purple{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(190,90,255,.24)}
.bjHue-white{box-shadow:inset 0 3px 6px rgba(0,0,0,.5), inset 0 0 14px rgba(255,255,255,.2)}
.bjCell.bjDragging{
  z-index:10;
  transform:scale(1.12);
  border-color:rgba(255,226,140,.95);
  box-shadow:0 0 0 2px rgba(255,226,140,.7),0 0 18px rgba(255,209,102,.55),0 8px 16px rgba(0,0,0,.4);
  cursor:grabbing;
  transition:none;
}
.bjCell.bjHintPulse{animation:bjHintPulse .6s ease}
@keyframes bjHintPulse{
  0%,100%{transform:scale(1)}
  50%{transform:scale(1.08);box-shadow:0 0 12px rgba(255,215,0,.45)}
}
.bjCell.bjSpecial{
  border-color:rgba(255,209,102,.7);
  box-shadow:inset 0 3px 6px rgba(0,0,0,.4), 0 0 0 1px rgba(255,209,102,.4), 0 0 14px rgba(255,209,102,.4);
}
.bjCell.bjSpecial-rocket .bjGem:not(.bjRocketV){animation:bjRocketIdle 1.1s ease-in-out infinite}
.bjCell.bjSpecial-rocket .bjRocketV{animation:bjRocketIdleV 1.1s ease-in-out infinite}
@keyframes bjRocketIdle{
  0%,100%{transform:translateX(0) translateZ(0)}
  50%{transform:translateX(2px) translateZ(0)}
}
@keyframes bjRocketIdleV{
  0%,100%{transform:rotate(-90deg) translateX(0)}
  50%{transform:rotate(-90deg) translateX(2px)}
}
.bjCell.bjSpecial-bomb{
  border-color:rgba(255,107,107,.85);
  box-shadow:inset 0 3px 6px rgba(0,0,0,.4), 0 0 0 1px rgba(255,107,107,.45), 0 0 14px rgba(255,80,80,.4);
}
.bjCell.bjSpecial-plane{
  border-color:rgba(110,198,255,.9);
  box-shadow:inset 0 3px 6px rgba(0,0,0,.4), 0 0 0 1px rgba(110,198,255,.45), 0 0 14px rgba(110,198,255,.4);
}
.bjCell.bjSpecial-rainbow{
  border-color:#ffd166;
  overflow:hidden;
  box-shadow:inset 0 3px 6px rgba(0,0,0,.35), 0 0 0 1px rgba(255,255,255,.35), 0 0 16px rgba(255,209,102,.5);
}
.bjCell.bjSpecial-rainbow::before{
  content:'';
  position:absolute;
  inset:-40%;
  background:conic-gradient(#ff6b6b,#ffd166,#40f99b,#6ec6ff,#b066ff,#ff6b6b);
  opacity:.32;
  mix-blend-mode:overlay;
  animation:bjRainbowSpin 4s linear infinite;
  pointer-events:none;
  z-index:0;
}
.bjCell.bjSpecial-rainbow .bjGem{position:relative;z-index:1}
@keyframes bjRainbowSpin{
  to{transform:rotate(1turn)}
}
.bjGrid.bjResolving .bjCell.bjSpecial-rocket .bjGem,
.bjGrid.bjResolving .bjCell.bjSpecial-rainbow::before{
  animation:none !important;
}
.bjCell.bjSpawnPulse{animation:bjSpawnPulse .45s ease}
@keyframes bjSpawnPulse{
  0%{transform:scale(.6);filter:brightness(1.8)}
  70%{transform:scale(1.12)}
  100%{transform:scale(1);filter:none}
}
.bjFxBeam{
  position:absolute;
  pointer-events:none;
  z-index:16;
  border-radius:10px;
}
.bjFxBeamH{
  height:18px;
  margin-top:-9px;
  background:linear-gradient(90deg,transparent,#fff4b0 12%,#ffe066 50%,#fff4b0 88%,transparent);
  box-shadow:0 0 18px #ffd166,0 0 6px #fff;
}
.bjFxBeamV{
  width:18px;
  margin-left:-9px;
  background:linear-gradient(180deg,transparent,#fff4b0 12%,#ffe066 50%,#fff4b0 88%,transparent);
  box-shadow:0 0 18px #ffd166,0 0 6px #fff;
}
.bjFxBeamH::after,.bjFxBeamV::after{
  content:'';
  position:absolute;
  inset:5px 8%;
  border-radius:inherit;
  background:linear-gradient(90deg,transparent,#fff 40%,#fff 60%,transparent);
  opacity:.85;
}
.bjFxBeamV::after{inset:8% 5px;background:linear-gradient(180deg,transparent,#fff 40%,#fff 60%,transparent)}
.bjFxBeamWide.bjFxBeamH{height:56px;margin-top:-28px}
.bjFxBeamWide.bjFxBeamV{width:56px;margin-left:-28px}
.bjFxShock{
  position:absolute;
  width:44px;height:44px;
  margin:-22px 0 0 -22px;
  border:4px solid #ffb347;
  border-radius:50%;
  pointer-events:none;
  z-index:16;
  box-shadow:0 0 22px #ff6b6b, 0 0 8px #fff;
}
.bjFxBurst{
  position:absolute;
  width:32px;height:32px;
  margin:-16px 0 0 -16px;
  border-radius:50%;
  background:radial-gradient(circle,#fff 0%,#ffd166 38%,rgba(255,107,107,0) 72%);
  pointer-events:none;
  z-index:16;
}
.bjFxBurstPlane{
  background:radial-gradient(circle,#fff 0%,#6ec6ff 38%,rgba(110,198,255,0) 72%);
}
.bjFxPlane,.bjFxRocketSprite,.bjFxBombSprite,.bjFxRainbowSprite,.bjFxCarry{
  position:absolute;
  width:52px;height:52px;
  margin:-26px 0 0 -26px;
  pointer-events:none;
  z-index:18;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.55));
  will-change:transform;
}
.bjFxCarry{width:28px;height:28px;margin:-14px 0 0 -14px;z-index:19}
.bjFxPlane img,.bjFxRocketSprite img,.bjFxBombSprite img,.bjFxRainbowSprite img,.bjFxCarry img{
  width:100%;height:100%;
  object-fit:contain;
}
.bjFxRainbowGlow{
  position:absolute;
  width:48px;height:48px;
  margin:-24px 0 0 -24px;
  border-radius:50%;
  background:conic-gradient(#ff6b6b,#ffd166,#40f99b,#6ec6ff,#b066ff,#ff6b6b);
  pointer-events:none;
  z-index:16;
  filter:blur(0.5px);
}
.bjFxCharge{
  position:absolute;
  width:46px;height:46px;
  margin:-23px 0 0 -23px;
  border:3px solid #ffd166;
  border-radius:50%;
  pointer-events:none;
  z-index:15;
  box-shadow:0 0 16px currentColor;
}
.bjFxTargetRing{
  position:absolute;
  width:46px;height:46px;
  margin:-23px 0 0 -23px;
  border:3px dashed #6ec6ff;
  border-radius:50%;
  pointer-events:none;
  z-index:15;
  box-shadow:0 0 14px #6ec6ff;
}
.bjFxParticle{
  position:absolute;
  width:7px;height:7px;
  margin:-3px 0 0 -3px;
  border-radius:50%;
  pointer-events:none;
  z-index:20;
  box-shadow:0 0 6px currentColor;
}
.bjFxTrail{
  position:absolute;
  width:14px;height:10px;
  margin:-5px 0 0 -7px;
  border-radius:8px;
  pointer-events:none;
  z-index:17;
  filter:blur(0.4px);
  box-shadow:0 0 10px currentColor;
}
.bjFxTendril{
  position:absolute;
  height:5px;
  border-radius:5px;
  transform-origin:0 50%;
  pointer-events:none;
  z-index:17;
  box-shadow:0 0 10px currentColor, 0 0 2px #fff;
}
.bjFxWash{
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  z-index:14;
  background:conic-gradient(#ff6b6b,#ffd166,#40f99b,#6ec6ff,#b066ff,#ff6b6b);
  mix-blend-mode:screen;
  opacity:0;
}
.bjFxFlash{
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  z-index:21;
  background:#fff;
  opacity:0;
}
.bjCell.bjFxHitRocket{
  background:rgba(255,209,102,.55) !important;
  box-shadow:0 0 16px #ffd166;
}
.bjCell.bjFxHitBomb{
  background:rgba(255,107,107,.5) !important;
  box-shadow:0 0 16px #ff6b6b;
}
.bjCell.bjFxHitPlane{
  background:rgba(110,198,255,.5) !important;
  box-shadow:0 0 14px #6ec6ff;
}
.bjCell.bjFxHitRainbow{
  background:linear-gradient(135deg,rgba(255,107,107,.5),rgba(255,209,102,.5),rgba(64,249,155,.5)) !important;
  box-shadow:0 0 16px #ffd166;
}
.bjSparkle{
  position:absolute;
  width:8px;height:8px;
  border-radius:50%;
  pointer-events:none;
  z-index:20;
}
.bjScorePop{
  position:absolute;
  font-size:18px;font-weight:900;
  color:#ffd166;
  text-shadow:0 1px 4px rgba(0,0,0,.5);
  pointer-events:none;
  z-index:30;
  transform:translate(-50%,-50%);
}
.bjMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
  color:#ffe7a8;
  text-shadow:0 1px 3px rgba(0,0,0,.45);
}
@media (max-width:400px){
  .bjBoard{padding:8px;border-radius:18px}
  .bjGrid{max-width:calc(100vw - 48px);gap:3px;padding:5px}
  .bjCell{border-radius:8px}
  .bjHudChip{min-width:92px;padding:6px 10px}
  .bjHudValue{font-size:17px}
  .bjLegend{gap:4px 8px;font-size:10px}
  .bjLegend img{width:18px;height:18px}
}

/* ---- circle drawing puzzle ---- */
.circleSolve{touch-action:manipulation;text-align:center}
.circleCanvasWrap{
  display:flex;
  justify-content:center;
  margin:12px auto;
}
#circleCanvas{
  border-radius:12px;
  border:2px solid rgba(255,255,255,.2);
  background:rgba(0,0,0,.25);
  touch-action:none;
  cursor:crosshair;
  max-width:100%;
  height:auto;
}
.circleMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
.circleActions{
  display:flex;
  gap:8px;
  justify-content:center;
  margin:8px 0;
}
@media (max-width:400px){
  #circleCanvas{width:240px;height:240px}
}

/* ---- flappy balloon ---- */
.flappySolve{touch-action:manipulation;text-align:center}
.flappyCanvasWrap{
  display:flex;
  justify-content:center;
  margin:8px auto;
}
#flappyCanvas{
  border-radius:12px;
  border:2px solid rgba(255,255,255,.2);
  background:#5aaee6;
  touch-action:none;
  cursor:pointer;
  max-width:100%;
  height:auto;
}
.flappyMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
@media (max-width:400px){
  #flappyCanvas{width:240px;height:343px}
}

/* ---- color match (Stroop) ---- */
.colorMatchSolve{touch-action:manipulation;text-align:center}
.colorMatchScorebar{
  display:flex;
  justify-content:space-between;
  align-items:center;
  font-size:13px;
  font-weight:700;
  margin:4px 0;
  opacity:.9;
}
.colorMatchTimerWrap{
  height:6px;
  width:100%;
  background:rgba(255,255,255,.12);
  border-radius:3px;
  overflow:hidden;
  margin:6px 0 12px;
}
#colorMatchTimerBar{
  height:100%;
  width:100%;
  background:var(--good, #3ad97c);
  transform-origin:left center;
  transition:transform 80ms linear, background-color 200ms;
}
.colorMatchWordWrap{
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:120px;
  margin:8px 0 16px;
  user-select:none;
}
#colorMatchWord{
  font-size:56px;
  font-weight:900;
  letter-spacing:2px;
  text-shadow:0 2px 8px rgba(0,0,0,.4);
  transition:color 0s;
}
.colorMatchButtons{
  display:grid;
  grid-template-columns:repeat(3, minmax(0,1fr));
  gap:10px;
  margin:0 0 8px;
}
.colorMatchBtn{
  border:2px solid rgba(255,255,255,.25);
  border-radius:14px;
  padding:16px 4px;
  font-weight:800;
  font-size:14px;
  color:#fff;
  text-shadow:0 1px 3px rgba(0,0,0,.5);
  cursor:pointer;
  transition:transform 80ms, border-color 120ms, opacity 120ms;
  touch-action:manipulation;
}
.colorMatchBtn:active{transform:scale(.95)}
.colorMatchBtn.correct{border-color:#fff;box-shadow:0 0 0 3px rgba(255,255,255,.5)}
.colorMatchBtn.wrong{opacity:.4}
.colorMatchBtn[disabled]{pointer-events:none}
.colorMatchMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:6px 0;
}
@media (max-width:400px){
  #colorMatchWord{font-size:44px}
}

/* ---- roller splat ---- */
.rollerSplatSolve{touch-action:manipulation;text-align:center}
.rsGrid{
  display:grid;
  gap:3px;
  max-width:280px;
  margin:12px auto;
  position:relative;
  touch-action:none;
}
.rsCell{
  aspect-ratio:1;
  border-radius:6px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:20px;
  position:relative;
  transition:background .2s ease;
}
.rsCell.rsWall{
  background:#333;
}
.rsCell.rsOpen{
  background:#fff;
  border:1px solid rgba(0,0,0,.1);
}
.rsCell.rsPainted{
  background:var(--color-good, #40f99b);
  border-color:transparent;
}
.rsCell.rsBall{
  z-index:2;
}
.rsBall::after{
  content:'';
  width:80%;
  height:80%;
  background:url('/public/balloon.png') center/contain no-repeat;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.3));
}
.rsMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
@media (max-width:400px){
  .rsGrid{max-width:240px}
}

/* ---- minesweeper ---- */
.minesweeperSolve{touch-action:manipulation;text-align:center}
.msGrid{
  display:grid;
  gap:2px;
  max-width:340px;
  margin:12px auto;
  position:relative;
  touch-action:manipulation;
  user-select:none;
  -webkit-user-select:none;
  -webkit-touch-callout:none;
}
.msCell{
  aspect-ratio:1;
  border-radius:4px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:15px;
  font-weight:800;
  background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,.16));
  border:1px solid rgba(255,255,255,.25);
  cursor:pointer;
  transition:background .12s ease;
}
.msCell.msRevealed{
  background:rgba(0,0,0,.28);
  border-color:rgba(255,255,255,.08);
  cursor:default;
}
.msCell.msFlagged{font-size:13px}
.msCell.msMine{
  background:#b3261e;
  border-color:transparent;
  font-size:14px;
}
.msCell.msMineHit{
  background:#e8453c;
  box-shadow:0 0 10px rgba(232,69,60,.8);
}
.msCell.msHinted{animation:msHintFlash 1.2s ease-out}
@keyframes msHintFlash{
  0%{box-shadow:0 0 0 3px rgba(255,213,79,.9),0 0 14px rgba(255,213,79,.8)}
  100%{box-shadow:0 0 0 0 rgba(255,213,79,0)}
}
.msCell[data-adj="1"]{color:#7cc4ff}
.msCell[data-adj="2"]{color:#40f99b}
.msCell[data-adj="3"]{color:#ff8a80}
.msCell[data-adj="4"]{color:#c6a4ff}
.msCell[data-adj="5"]{color:#ffd54f}
.msCell[data-adj="6"]{color:#4dd0e1}
.msCell[data-adj="7"]{color:#f48fb1}
.msCell[data-adj="8"]{color:#fff}
.msMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
#minesweeperFlagMode[aria-pressed="true"]{
  background:var(--color-good,#40f99b);
  color:#06231a;
}
@media (max-width:400px){
  .msGrid{max-width:300px}
  .msCell{font-size:13px}
}

/* ---- sudoku ---- */
.sudokuSolve{touch-action:manipulation;text-align:center}
.sdStatus{
  display:flex;
  justify-content:center;
  gap:14px;
  font-size:13px;
  font-weight:700;
  color:var(--muted);
  min-height:18px;
}
.sdGrid{
  display:grid;
  grid-template-columns:repeat(9,1fr);
  gap:1px;
  max-width:330px;
  margin:10px auto;
  padding:3px;
  background:rgba(0,0,0,.28);
  border-radius:8px;
  touch-action:manipulation;
  user-select:none;
  -webkit-user-select:none;
  -webkit-touch-callout:none;
}
.sdCell{
  aspect-ratio:1;
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:clamp(13px, 4vw, 17px);
  font-weight:700;
  color:var(--text);
  background:rgba(255,255,255,.12);
  border:0 solid rgba(0,0,0,.55);
  border-radius:2px;
  padding:0;
  box-sizing:border-box;
  cursor:pointer;
  transition:background .12s ease;
}
/* 3x3 box seams: a heavier rule on the box boundaries. Drawn as a border on
   the first cell of each box so the 9x9 grid still lays out as one grid. */
.sdCell[data-boxr="1"]{border-top-width:3px}
.sdCell[data-boxc="1"]{border-left-width:3px}
/* Clues are fixed and visually heavier than anything the player enters */
.sdCell.sdGiven{
  background:rgba(255,255,255,.04);
  color:var(--muted);
  font-weight:900;
  cursor:default;
}
.sdCell.sdFilled{color:var(--good)}
.sdCell.sdHinted{color:var(--warn)}
.sdCell.sdSelected{
  background:rgba(255,255,255,.36);
  box-shadow:inset 0 0 0 2px var(--warn);
}
/* Same row / column / box as the selection, and same digit elsewhere */
.sdCell.sdPeer{background:rgba(255,255,255,.2)}
.sdCell.sdMatch{box-shadow:inset 0 0 0 2px var(--good)}
.sdCell.sdWrong{animation:sdShake .4s ease}
@keyframes sdShake{
  0%,100%{transform:translateX(0);background:rgba(255,77,109,.85)}
  25%{transform:translateX(-3px)}
  75%{transform:translateX(3px)}
}
/* Pencil marks: a 3x3 mini grid of candidate digits inside the cell */
.sdNotes{
  position:absolute;
  inset:1px;
  display:grid;
  grid-template-columns:repeat(3,1fr);
  font-size:clamp(6px, 1.9vw, 8px);
  font-weight:600;
  line-height:1;
  color:var(--muted);
  pointer-events:none;
}
.sdNotes span{display:flex;align-items:center;justify-content:center}
/* Two rows of five: 1-5 on top, 6-9 plus erase below. Wider than tall so the
   pad stays big under the thumb without pushing the grid off a phone screen. */
.sdPad{
  display:grid;
  grid-template-columns:repeat(5,1fr);
  gap:6px;
  max-width:330px;
  margin:10px auto 0;
}
.sdPadBtn{
  aspect-ratio:5/4;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:clamp(20px, 6vw, 26px);
  font-weight:800;
  color:var(--text);
  background:var(--card2);
  border:1px solid rgba(255,255,255,.25);
  border-radius:6px;
  padding:0;
  cursor:pointer;
}
.sdPadBtn:active{background:rgba(255,255,255,.3)}
/* Dim a digit once all nine of it are placed */
.sdPadBtn.sdPadDone{opacity:.35}
.sdMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
#sudokuNotesMode[aria-pressed="true"]{
  background:var(--color-good,#40f99b);
  color:#06231a;
}
@media (max-width:400px){
  .sdGrid,.sdPad{max-width:296px}
}

/* ---- 2048 ---- */
.tfeSolve{touch-action:manipulation;text-align:center}
.tfeGrid{
  position:relative;
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:6px;
  max-width:280px;
  margin:12px auto;
  background:rgba(0,0,0,.2);
  border-radius:10px;
  padding:8px;
}
/* Background empty cells */
.tfeSlot{
  aspect-ratio:1;
  border-radius:8px;
  background:rgba(255,255,255,.08);
}
/* Tile layer floats on top of the grid slots */
.tfeTileLayer{
  position:absolute;
  inset:8px;
  pointer-events:none;
}
/* Individual tile */
.tfeTile{
  position:absolute;
  border-radius:8px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-weight:800;
  font-size:22px;
  user-select:none;
  -webkit-user-select:none;
  will-change:transform;
  z-index:1;
}
.tfeTile[data-value="2"]{background:#eee4da;color:#776e65}
.tfeTile[data-value="4"]{background:#ede0c8;color:#776e65}
.tfeTile[data-value="8"]{background:#f2b179;color:#fff}
.tfeTile[data-value="16"]{background:#f59563;color:#fff}
.tfeTile[data-value="32"]{background:#f67c5f;color:#fff}
.tfeTile[data-value="64"]{background:#f65e3b;color:#fff}
.tfeTile[data-value="128"]{background:#edcf72;color:#fff;font-size:19px}
.tfeTile[data-value="256"]{background:#edcc61;color:#fff;font-size:19px}
.tfeTile[data-value="512"]{background:#edc850;color:#fff;font-size:19px}
.tfeTile[data-value="1024"]{background:#edc53f;color:#fff;font-size:16px}
.tfeTile[data-value="2048"]{background:#edc22e;color:#fff;font-size:16px}
.tfeMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
@media (max-width:400px){
  .tfeGrid{max-width:240px;gap:4px;padding:6px}
  .tfeGrid .tfeTileLayer{inset:6px}
  .tfeTile{font-size:18px;border-radius:6px}
  .tfeTile[data-value="128"],.tfeTile[data-value="256"]{font-size:16px}
  .tfeTile[data-value="512"],.tfeTile[data-value="1024"],.tfeTile[data-value="2048"]{font-size:14px}
  .tfeSlot{border-radius:6px}
}

/* ---- paint toolbar ---- */
.paint-toolbar{
  position:absolute;
  right:14px;
  bottom:110px;
  z-index:9;
  background: rgba(0,0,0,.45);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 16px;
  padding: 10px;
  backdrop-filter: blur(10px);
  box-shadow: 0 18px 40px rgba(0,0,0,.35);
}
.paint-toolbar[hidden]{display:none}
.paint-row{display:flex;align-items:center;gap:8px;margin:6px 0}
.paint-swatch{
  width:22px;height:22px;border-radius:50%;
  border: 2px solid rgba(255,255,255,.35);
  box-shadow: 0 6px 14px rgba(0,0,0,.35);
  cursor:pointer;
}
.paint-swatch.isActive{border-color: rgba(255,255,255,.9)}
.paint-custom input{width:28px;height:28px;border:none;background:transparent;padding:0}
.paint-pill{
  min-width:36px;height:30px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(0,0,0,.20);
  color: rgba(255,255,255,.9);
  font-weight: 800;
  cursor:pointer;
}
.paint-pill.isActive{background: rgba(255,255,255,.20); border-color: rgba(255,255,255,.45)}

@media (max-width: 560px){
  .paint-toolbar{right:10px;bottom:96px;}
  .paint-swatch{width:26px;height:26px;}
  .paint-pill{min-width:40px;height:34px;}
}

/* Wait modal */
.waitModal{
  position:fixed;inset:0;z-index:999;
  background:rgba(0,0,0,.6);
  display:flex;align-items:center;justify-content:center;
  padding:18px;
}
.waitModal[hidden]{display:none}
.waitCard{
  background:rgba(30,30,50,.95);
  border-radius:20px;
  padding:24px 22px;
  max-width:320px;
  text-align:center;
  color:#fff;
  border:1px solid rgba(255,255,255,.12);
  box-shadow:0 12px 40px rgba(0,0,0,.5);
  animation: waitPopIn .3s ease;
}
@keyframes waitPopIn{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}

/* Fullscreen paint mode */
.paintMode{
  position:fixed;inset:0;z-index:998;
  background:linear-gradient(135deg,#0f0c29,#302b63,#24243e);
  display:flex;flex-direction:column;
}
.paintMode[hidden]{display:none}
.paintMode-header{
  flex:0 0 auto;
  display:flex;justify-content:flex-end;
  padding:12px 16px 0;
}
.paintMode-canvas{
  flex:1;
  position:relative;
  overflow:hidden;
  touch-action:none;
}
.paintMode-controls{
  flex:0 0 auto;
  padding:10px 16px 20px;
  display:flex;flex-direction:column;gap:8px;align-items:center;
  background:rgba(0,0,0,.3);
}
.paintMode-controls .paint-row{
  display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:center;
}
.paintMode-controls .paint-swatch{width:28px;height:28px}
.paintMode-controls .paint-pill{min-width:42px;height:34px}

/* ---- bounce cutscene ---- */
.bounceCutscene{
  position:fixed;inset:0;z-index:9999;
  overflow:hidden;
  align-items:center;justify-content:center;
  pointer-events:none;
  display:none;
}
.bounceCutscene.active{
  display:flex;
}
.cutsceneBg{
  position:absolute;inset:-20%;
  background:
    radial-gradient(ellipse at 50% 80%, rgba(100,180,255,.25) 0%, transparent 60%),
    linear-gradient(180deg, #0a1628 0%, #1a3050 40%, #4a8060 70%, #5a9050 85%, #3d6830 100%);
  transform-origin:center bottom;
}
.cutsceneBalloon{
  position:absolute;
  width:min(45vw, 220px);
  height:auto;
  filter:drop-shadow(0 20px 40px rgba(0,0,0,.5));
  will-change:transform;
}
.cutsceneText{
  position:absolute;
  font-size:clamp(48px, 14vw, 120px);
  font-weight:900;
  color:#fff;
  text-shadow:
    0 0 30px rgba(255,215,0,.6),
    0 4px 0 rgba(0,0,0,.3),
    0 8px 20px rgba(0,0,0,.4);
  letter-spacing:-0.02em;
  white-space:nowrap;
  will-change:transform,opacity;
  text-align:center;
}
.cutsceneText .cutsceneTime{
  display:block;
  font-size:0.42em;
  font-weight:800;
  margin-top:0.1em;
  color:#ffe9a8;
  text-shadow:
    0 0 16px rgba(255,215,0,.5),
    0 3px 0 rgba(0,0,0,.3),
    0 6px 14px rgba(0,0,0,.4);
  letter-spacing:0;
}

/* ----- Chess board ----- */
.chessBoard{
  display:grid;
  grid-template-columns:repeat(8, 1fr);
  grid-template-rows:repeat(8, 1fr);
  width:min(88vw, 360px);
  aspect-ratio:1/1;
  margin:6px auto 0;
  border-radius:8px;
  overflow:hidden;
  box-shadow:0 6px 20px rgba(0,0,0,.4);
  user-select:none;
  -webkit-user-select:none;
}
.chessSquare{
  position:relative;
  min-width:0;
  min-height:0;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:clamp(22px, 6.5vw, 34px);
  line-height:1;
  cursor:default;
}
.chessSquare.light{ background:#e9d8b5; }
.chessSquare.dark{ background:#7a5a3a; }
.chessSquare .pc{
  width:88%;
  height:88%;
  object-fit:contain;
  pointer-events:none;
  filter:drop-shadow(0 1px 1px rgba(0,0,0,.35));
  user-select:none;
  -webkit-user-select:none;
  -webkit-user-drag:none;
}
.chessSquare.selected::after{
  content:'';
  position:absolute;
  inset:0;
  background:rgba(255,235,80,.45);
  pointer-events:none;
}
.chessSquare.legal::before{
  content:'';
  position:absolute;
  width:30%;
  height:30%;
  border-radius:50%;
  background:rgba(0,0,0,.28);
  pointer-events:none;
}
.chessSquare.legal.capture::before{
  width:80%;
  height:80%;
  border-radius:50%;
  background:transparent;
  border:4px solid rgba(0,0,0,.32);
  box-sizing:border-box;
}
.chessSquare.lastmove::after{
  content:'';
  position:absolute;
  inset:0;
  background:rgba(255,235,80,.30);
  pointer-events:none;
}
.chessSquare.hint{
  box-shadow: inset 0 0 0 4px rgba(60,200,90,.85);
}
.chessSquare.hint::after{
  content:'';
  position:absolute;
  inset:0;
  background:rgba(60,200,90,.25);
  pointer-events:none;
}
.chessSquare.check::before{
  content:'';
  position:absolute;
  inset:0;
  background:radial-gradient(circle at center, rgba(255,80,80,.55) 0%, rgba(255,80,80,0) 70%);
  pointer-events:none;
}
.chessSquare[role="button"]{ cursor:pointer; }
.chessBoard.disabled .chessSquare[role="button"]{ cursor:default; }

/* Keyboard-focus indicator for accessibility. Many interactive elements
   are styled <div>s without native focus rings; this gives every focusable
   element a visible outline when reached via Tab without affecting mouse
   users (who don't trigger :focus-visible). */
:focus-visible {
  outline: 2px solid #b8c0ff;
  outline-offset: 2px;
  border-radius: 6px;
}

/* Respect the user's system "reduce motion" preference. Animations are kept
   but dramatically shortened so users who opt out don't get the bouncing /
   fireworks / cutscene motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- Flow ---- */
.flowSolve{text-align:center}
.flowBoard{
  position:relative;
  display:grid;
  gap:3px;
  max-width:320px;
  margin:12px auto;
  padding:6px;
  background:rgba(0,0,0,.25);
  border-radius:10px;
  touch-action:none;
  user-select:none;
  -webkit-user-select:none;
}
.flowCell{
  aspect-ratio:1;
  background:#1c1c2e;
  border-radius:4px;
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
}
.flowCell.flowFilled{
  /* color set via inline style */
}
/* The colored "fill" inside a cell. Renders as a shrink-from-edges
   colored square so the grid lines stay visible between cells. */
.flowFill{
  position:absolute;
  inset:0;
  border-radius:3px;
  pointer-events:none;
}
/* Path direction stubs — extend the fill out to touch the neighbouring
   cell's fill, so adjacent path cells look like one continuous flow.
   Applied via direction classes on .flowCell. */
.flowFill.dir-u{ top:-3px }
.flowFill.dir-d{ bottom:-3px }
.flowFill.dir-l{ left:-3px }
.flowFill.dir-r{ right:-3px }
/* Endpoint dot — solid colored disc, larger than path fill */
.flowEndpoint{
  position:absolute;
  width:70%;
  height:70%;
  border-radius:50%;
  z-index:2;
  pointer-events:none;
  box-shadow:0 0 0 2px rgba(255,255,255,.18) inset, 0 1px 3px rgba(0,0,0,.4);
}
.flowMessage{
  text-align:center;
  min-height:24px;
  font-weight:700;
  font-size:14px;
  margin:8px 0;
}
.flowStatus{ text-align:center }
@media (max-width:400px){
  .flowBoard{max-width:280px}
}
