
.game-2048-board{
  grid-auto-rows:1fr!important;
  align-items:stretch!important;
  justify-items:stretch!important;
  contain:layout paint;
}
.game-2048-tile{
  aspect-ratio:1 / 1!important;
  min-width:0!important;
  min-height:0!important;
  width:100%!important;
  height:100%!important;
  box-sizing:border-box!important;
  overflow:hidden;
  will-change:transform;
}
.game-2048-board.is-moving-up .game-2048-tile:not(.is-empty){
  animation:tile2048SlideUp .16s cubic-bezier(.2,.8,.2,1);
}
.game-2048-board.is-moving-down .game-2048-tile:not(.is-empty){
  animation:tile2048SlideDown .16s cubic-bezier(.2,.8,.2,1);
}
.game-2048-board.is-moving-left .game-2048-tile:not(.is-empty){
  animation:tile2048SlideLeft .16s cubic-bezier(.2,.8,.2,1);
}
.game-2048-board.is-moving-right .game-2048-tile:not(.is-empty){
  animation:tile2048SlideRight .16s cubic-bezier(.2,.8,.2,1);
}
@keyframes tile2048SlideUp{
  from{ transform:translateY(10px) scale(.985); }
  to{ transform:translateY(0) scale(1); }
}
@keyframes tile2048SlideDown{
  from{ transform:translateY(-10px) scale(.985); }
  to{ transform:translateY(0) scale(1); }
}
@keyframes tile2048SlideLeft{
  from{ transform:translateX(10px) scale(.985); }
  to{ transform:translateX(0) scale(1); }
}
@keyframes tile2048SlideRight{
  from{ transform:translateX(-10px) scale(.985); }
  to{ transform:translateX(0) scale(1); }
}
.game-2048-overlay button{
  transition:
    transform .16s ease,
    border-color .16s ease,
    background-color .16s ease,
    box-shadow .16s ease,
    color .16s ease;
}
.game-2048-overlay button:hover,
.game-2048-overlay button:focus-visible{
  transform:translateY(-2px);
  border-color:rgba(14,165,233,.48);
  box-shadow:0 18px 34px rgba(14,165,233,.16);
  outline:none;
}
@media(max-width:720px){
  .game-2048-board{
    width:100%;
    max-width:calc(100vw - 42px);
  }
  .game-2048-tile{
    font-size:clamp(1.25rem, 11vw, 2.75rem);
  }
  .game-2048-tile.tile-v-1024{
    font-size:clamp(1rem, 8.6vw, 2.25rem);
  }
  .game-2048-tile.tile-v-2048{
    font-size:clamp(.86rem, 7.4vw, 2rem);
  }
}


/* v20.18.5：2048 真滑动 / 合成动画重做 */
.game-2048-board{
  position:relative!important;
  display:block!important;
  grid-template-columns:none!important;
  grid-auto-rows:auto!important;
  align-items:initial!important;
  justify-items:initial!important;
  overflow:hidden;
}
.game-2048-cells,
.game-2048-tile-layer{
  position:absolute;
  inset:0;
}
.game-2048-cells{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  grid-template-rows:repeat(4, 1fr);
  gap:var(--game-2048-gap);
  padding:var(--game-2048-gap);
  pointer-events:none;
}
.game-2048-cell{
  border-radius:18px;
  background:rgba(226,232,240,.18);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12);
}
.game-2048-tile-layer{
  pointer-events:none;
  z-index:2;
}
.game-2048-tile{
  position:absolute!important;
  left:0!important;
  top:0!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  border-radius:18px;
  font-weight:900;
  line-height:1;
  box-sizing:border-box!important;
  overflow:hidden;
  will-change:transform;
  transition:transform 210ms cubic-bezier(.2,.86,.22,1);
  animation:none!important;
  z-index:3;
}
.game-2048-tile span{
  display:block;
  transform:translateZ(0);
}
.game-2048-tile.is-new{
  animation:tile2048AppearReal 180ms cubic-bezier(.2,.9,.2,1.25)!important;
}
.game-2048-tile.is-merged{
  z-index:5;
  animation:tile2048MergeReal 240ms cubic-bezier(.18,.9,.2,1.25)!important;
}
@keyframes tile2048AppearReal{
  0%{ opacity:0; transform:scale(.55); }
  70%{ opacity:1; transform:scale(1.08); }
  100%{ opacity:1; transform:scale(1); }
}
@keyframes tile2048MergeReal{
  0%{ transform:scale(.92); }
  48%{ transform:scale(1.18); }
  100%{ transform:scale(1); }
}
body.dark .game-2048-cell,
html.dark .game-2048-cell{
  background:rgba(148,163,184,.13);
}
@media(max-width:720px){
  .game-2048-cell,
  .game-2048-tile{
    border-radius:14px;
  }
}


/* v20.18.5：2048 absolute tile 尺寸修复
   v20.14.0 留下的 .game-2048-tile width/height:100%!important 会把数字块撑成整块棋盘。
   这里强制 tile layer 下的数字块走 JS 计算的像素宽高。 */
.game-2048-tile-layer > .game-2048-tile{
  position:absolute!important;
  width:var(--tile-size, auto);
  height:var(--tile-size, auto);
  max-width:none!important;
  max-height:none!important;
  min-width:0!important;
  min-height:0!important;
  flex:none!important;
}
.game-2048-tile-layer{
  overflow:visible;
}


/* v20.18.5：2048 防闪烁动画收尾 */
.game-2048-tile.no-transition{
  transition:none!important;
}
.game-2048-tile-layer > .game-2048-tile{
  backface-visibility:hidden;
  transform-style:preserve-3d;
  contain:layout paint style;
}
.game-2048-tile.is-new{
  animation:tile2048AppearNoFlicker 180ms cubic-bezier(.2,.9,.2,1.16)!important;
}
.game-2048-tile.is-merged{
  animation:tile2048MergeNoFlicker 190ms cubic-bezier(.2,.9,.2,1.16)!important;
}
@keyframes tile2048AppearNoFlicker{
  0%{ opacity:0; transform:scale(.72); }
  60%{ opacity:1; transform:scale(1.06); }
  100%{ opacity:1; transform:scale(1); }
}
@keyframes tile2048MergeNoFlicker{
  0%{ transform:scale(1); filter:brightness(1); }
  45%{ transform:scale(1.13); filter:brightness(1.08); }
  100%{ transform:scale(1); filter:brightness(1); }
}


/* v20.18.5：2048 左上角闪现修复
   外层 .game-2048-tile 负责 translate3d 定位，不能再用 transform 做 appear/merge。
   否则 scale 动画会覆盖 translate3d，导致新块/合成块瞬间出现在左上角。 */
.game-2048-tile-layer > .game-2048-tile.is-new,
.game-2048-tile-layer > .game-2048-tile.is-merged{
  animation:none!important;
}
.game-2048-tile-inner,
.game-2048-tile > span{
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  width:100%!important;
  height:100%!important;
  transform-origin:center center;
  backface-visibility:hidden;
  pointer-events:none;
}
.game-2048-tile.is-new .game-2048-tile-inner,
.game-2048-tile.is-new > span{
  animation:tile2048InnerAppear 180ms cubic-bezier(.2,.9,.2,1.16)!important;
}
.game-2048-tile.is-merged .game-2048-tile-inner,
.game-2048-tile.is-merged > span{
  animation:tile2048InnerMerge 190ms cubic-bezier(.2,.9,.2,1.16)!important;
}
@keyframes tile2048InnerAppear{
  0%{ opacity:0; transform:scale(.72); }
  60%{ opacity:1; transform:scale(1.06); }
  100%{ opacity:1; transform:scale(1); }
}
@keyframes tile2048InnerMerge{
  0%{ transform:scale(1); filter:brightness(1); }
  45%{ transform:scale(1.13); filter:brightness(1.08); }
  100%{ transform:scale(1); filter:brightness(1); }
}
.game-2048-leaderboard{
  width:min(100%, 520px);
  margin:18px auto 0!important;
}
.game-2048-leaderboard ol{
  margin-bottom:0;
}
@media(max-width:720px){
  .game-2048-topbar{ grid-template-columns:1fr 1fr; }
}

/* 从 site.css 迁移的 2048 页面基础样式。 */
/* v20.18.5：工具页 2048 小游戏 */
.tool-2048-page{
  min-height:calc(100vh - 120px);
  padding:clamp(28px, 5vw, 72px) clamp(16px, 4vw, 56px);
}
.tool-2048-shell{
  max-width:920px;
  margin:0 auto;
}
.game-2048-panel{
  position:relative;
  border:1px solid rgba(148,163,184,.24);
  background:
    radial-gradient(circle at 22% 12%, rgba(56,189,248,.12), transparent 32%),
    radial-gradient(circle at 82% 22%, rgba(168,85,247,.12), transparent 34%),
    rgba(255,255,255,.72);
  border-radius:32px;
  padding:clamp(16px, 4vw, 30px);
  box-shadow:0 24px 70px rgba(15,23,42,.13);
  backdrop-filter:blur(18px);
}
.game-2048-topbar{
  display:flex;
  align-items:stretch;
  gap:12px;
  margin-bottom:18px;
}
.game-2048-score-card{
  border:1px solid rgba(148,163,184,.28);
  background:rgba(255,255,255,.7);
  border-radius:18px;
  padding:.75rem .95rem;
  box-shadow:0 12px 28px rgba(15,23,42,.08);
}
.game-2048-score-card{
  min-width:96px;
}
.game-2048-score-card span{
  display:block;
  font-size:.76rem;
  color:rgba(100,116,139,.82);
}
.game-2048-score-card strong{
  display:block;
  margin-top:.1rem;
  font-size:1.45rem;
  line-height:1;
  color:#0f172a;
}
.game-2048-board-wrap{
  position:relative;
  width:min(100%, 520px);
  margin:0 auto;
}
.game-2048-board{
  --game-2048-gap:10px;
  display:grid;
  grid-template-columns:repeat(var(--game-2048-size, 4), 1fr);
  gap:var(--game-2048-gap);
  aspect-ratio:1;
  padding:var(--game-2048-gap);
  border-radius:28px;
  background:
    linear-gradient(135deg, rgba(15,23,42,.82), rgba(30,41,59,.72)),
    radial-gradient(circle at center, rgba(56,189,248,.16), transparent 60%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.18),
    0 24px 68px rgba(15,23,42,.22);
  touch-action:none;
  user-select:none;
}
.game-2048-tile{
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:18px;
  font-weight:900;
  font-size:clamp(1.45rem, 8vw, 3.35rem);
  line-height:1;
  color:#0f172a;
  background:rgba(226,232,240,.26);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26);
  transition:transform .12s ease, background-color .16s ease, color .16s ease;
}
.game-2048-tile:not(.is-empty){
  animation:tile2048Pop .14s ease-out;
}
@keyframes tile2048Pop{
  from{ transform:scale(.92); }
  to{ transform:scale(1); }
}
.game-2048-tile.tile-v-2{ background:#e0f2fe; color:#0c4a6e; }
.game-2048-tile.tile-v-4{ background:#bae6fd; color:#0c4a6e; }
.game-2048-tile.tile-v-8{ background:#a7f3d0; color:#064e3b; }
.game-2048-tile.tile-v-16{ background:#fde68a; color:#713f12; }
.game-2048-tile.tile-v-32{ background:#fdba74; color:#7c2d12; }
.game-2048-tile.tile-v-64{ background:#fca5a5; color:#7f1d1d; }
.game-2048-tile.tile-v-128{ background:#f0abfc; color:#581c87; }
.game-2048-tile.tile-v-256{ background:#c4b5fd; color:#312e81; }
.game-2048-tile.tile-v-512{ background:#67e8f9; color:#164e63; }
.game-2048-tile.tile-v-1024{ background:#facc15; color:#422006; font-size:clamp(1.12rem, 6vw, 2.7rem); }
.game-2048-tile.tile-v-2048{ background:#fb7185; color:#4c0519; font-size:clamp(1.02rem, 5vw, 2.45rem); }
.game-2048-overlay{
  position:absolute;
  inset:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:12px;
  padding:22px;
  text-align:center;
  border-radius:28px;
  background:rgba(15,23,42,.72);
  color:white;
  backdrop-filter:blur(10px);
}
.game-2048-overlay[hidden]{
  display:none;
}
.game-2048-overlay strong{
  font-size:clamp(1.8rem, 8vw, 4rem);
}
.game-2048-overlay button{
  border:0;
  border-radius:999px;
  padding:.72rem 1.08rem;
  font-weight:900;
  cursor:pointer;
  background:white;
  color:#0f172a;
}
.tool-card .tool-card-icon{
  letter-spacing:-.06em;
}
body.dark .game-2048-panel,
html.dark .game-2048-panel,
body.dark .game-2048-score-card,
html.dark .game-2048-score-card{
  background:rgba(15,23,42,.66);
  color:rgba(248,250,252,.92);
  border-color:rgba(148,163,184,.22);
}
body.dark .game-2048-score-card strong,
html.dark .game-2048-score-card strong{
  color:rgba(248,250,252,.94);
}
@media(max-width:720px){
  .tool-2048-page{
    padding:18px 12px 34px;
  }
  .game-2048-topbar{
    display:grid;
    grid-template-columns:1fr 1fr;
  }
  .game-2048-board{
    --game-2048-gap:8px;
    border-radius:22px;
  }
  .game-2048-tile{
    border-radius:14px;
  }
}
