/* 2048: a warm room, a recessed tray, and chunky tiles that glow hotter as
   the numbers climb. On a laptop the score and buttons move to a side panel
   and the board grows to fill the height. */
:root {
  --bg: #f3e2c4;
  --ink: #5a4632;
  --ink-soft: #8a6e52;
  --accent: #f08a3a;
  --accent-ink: #fff;
}
body {
  background: radial-gradient(ellipse at 50% 20%, #fff3dc, #ecd2a8 70%) fixed;
  min-height: 100vh;
}
.topbar .title { color: var(--ink); }

.game {
  max-width: 520px;
  margin: 0 auto;
  padding: 8px 16px 24px;
}
.logo2048 {
  margin: 4px 0 12px;
  display: flex;
  justify-content: center;
  gap: 6px;
}
.logo2048 .t {
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  font-family: var(--display);
  font-weight: 400;
  font-size: 38px;
  color: #fff;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.18);
  box-shadow: 0 5px 0 rgba(0, 0, 0, 0.18), inset 0 2px 0 rgba(255, 255, 255, 0.45);
}
.logo2048 .t2 { background: linear-gradient(#ffb066, #f08a3a); transform: rotate(-6deg); }
.logo2048 .t0 { background: linear-gradient(#ff8a6a, #ef5a3a); transform: rotate(4deg) translateY(3px); }
.logo2048 .t4 { background: linear-gradient(#ffe07a, #f2bc2a); transform: rotate(-3deg); }
.logo2048 .t8 { background: linear-gradient(#ff7aa8, #e8447a); transform: rotate(6deg) translateY(2px); }

.scores {
  display: flex;
  gap: 10px;
  align-items: stretch;
  margin-bottom: 14px;
}
.score-box {
  position: relative;
  flex: 1;
  background: linear-gradient(#a8876a, #8a6a4e);
  color: #fff;
  border-radius: 14px;
  padding: 6px 10px 8px;
  text-align: center;
  display: flex;
  flex-direction: column;
  box-shadow: 0 4px 0 #5e4430, inset 0 2px 0 rgba(255, 255, 255, 0.2);
}
.score-box .label {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0.85;
}
.score-box .value {
  font-family: var(--display);
  font-size: 26px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.scores .btn { flex: 0 0 auto; }

/* "+8" rising out of the score when points land. */
.plus {
  position: absolute;
  left: 0;
  right: 0;
  top: 18px;
  color: #fff;
  font-family: var(--display);
  font-size: 20px;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.3);
  animation: rise 600ms ease-out forwards;
  pointer-events: none;
}
@keyframes rise {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(-34px); opacity: 0; }
}

/* The board: a deep tray with sunken cells. Everything is sized from --size,
   so it fits a phone held either way and never needs to scroll. */
.board {
  --size: min(calc(100vw - 32px), 488px, calc(100vh - 260px));
  --gap: calc(var(--size) * 0.03);
  --cell: calc((var(--size) - var(--gap) * 5) / 4);
  position: relative;
  width: var(--size);
  height: var(--size);
  min-width: 260px;
  min-height: 260px;
  margin: 0 auto;
  padding: var(--gap);
  background: linear-gradient(#9a7a5c, #7a5a3e);
  border-radius: calc(var(--size) * 0.045);
  box-shadow: 0 8px 0 #5a3e28, 0 16px 30px rgba(90, 60, 30, 0.35), inset 0 2px 0 rgba(255, 255, 255, 0.25);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.cells {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  width: 100%;
  height: 100%;
}
.cells span {
  background: rgba(60, 40, 20, 0.28);
  border-radius: calc(var(--cell) * 0.14);
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.15);
}
.tiles {
  position: absolute;
  inset: var(--gap);
}
.board .overlay { border-radius: inherit; }

/* A tile sits at (--r, --c). Changing those slides it — that is the whole
   movement animation. The inner block carries the pop, so the two transforms
   never fight. */
.tile {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  transform: translate(calc(var(--c) * (var(--cell) + var(--gap))),
                       calc(var(--r) * (var(--cell) + var(--gap))));
  transition: transform 110ms ease-in-out;
}
.tile .face {
  width: 100%;
  height: calc(100% - var(--cell) * 0.06);
  border-radius: calc(var(--cell) * 0.14);
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-size: calc(var(--cell) * 0.48);
  font-variant-numeric: tabular-nums;
  background: linear-gradient(color-mix(in srgb, var(--tile-bg) 70%, #fff), var(--tile-bg));
  color: var(--tile-ink);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.12);
  box-shadow: 0 calc(var(--cell) * 0.06) 0 color-mix(in srgb, var(--tile-bg) 62%, #000), inset 0 2px 0 rgba(255, 255, 255, 0.5);
}
.tile.d3 .face { font-size: calc(var(--cell) * 0.4); }
.tile.d4 .face { font-size: calc(var(--cell) * 0.32); }
.tile.d5 .face { font-size: calc(var(--cell) * 0.26); }

.tile.new .face { animation: appear 160ms ease-out 100ms backwards; }
.tile.merged .face { animation: pop 180ms ease-out 100ms backwards; }
@keyframes appear {
  from { transform: scale(0); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
@keyframes pop {
  0% { transform: scale(0.6); opacity: 0; }
  55% { transform: scale(1.14); opacity: 1; }
  100% { transform: scale(1); }
}

/* Warm to hot as the numbers climb; past 2048 it goes dark. */
.v2    { --tile-bg: #f6ecdc; --tile-ink: #7a6250; }
.v4    { --tile-bg: #f4dfb8; --tile-ink: #7a6250; }
.v8    { --tile-bg: #f7a95c; --tile-ink: #fff; }
.v16   { --tile-bg: #f78a48; --tile-ink: #fff; }
.v32   { --tile-bg: #f56a48; --tile-ink: #fff; }
.v64   { --tile-bg: #ec4a2c; --tile-ink: #fff; }
.v128  { --tile-bg: #f2cc5a; --tile-ink: #fff; }
.v256  { --tile-bg: #f0c444; --tile-ink: #fff; }
.v512  { --tile-bg: #eebc2e; --tile-ink: #fff; }
.v1024 { --tile-bg: #e8a020; --tile-ink: #fff; }
.v2048 { --tile-bg: #ec7a1a; --tile-ink: #fff; }
.vbig  { --tile-bg: #4a3a5a; --tile-ink: #fff; }
.v1024 .face, .v2048 .face { box-shadow: 0 calc(var(--cell) * 0.06) 0 color-mix(in srgb, var(--tile-bg) 62%, #000), 0 0 22px 4px rgba(255, 200, 80, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.5); }

.how {
  text-align: center;
  color: var(--ink-soft);
  font-size: 14px;
  margin: 16px 0 0;
}

/* A laptop: the logo, scores and buttons in a column on the left, and the
   board as big as the height allows. */
@media (min-aspect-ratio: 13/10) and (min-width: 700px) {
  .topbar { max-width: none; padding-left: 24px; padding-right: 24px; }
  .game {
    max-width: none;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 48px;
    min-height: calc(100vh - 70px);
    padding-top: 0;
  }
  .side { width: 260px; }
  .logo2048 .t { width: 58px; height: 58px; font-size: 42px; }
  .scores { flex-wrap: wrap; }
  .scores .btn { flex: 1 1 100%; font-size: 20px; padding: 12px; }
  .board { --size: min(calc(100vh - 110px), calc(100vw - 380px)); margin: 0; }
  .how { text-align: left; }
}
