:root {
  --bg: #0d1020; --bg2: #171a33;
  --ink: #eef0ff; --muted: #9aa0c8;
  --panel: rgba(255, 255, 255, .07); --panel-line: rgba(255, 255, 255, .14);
  --cell: rgba(255, 255, 255, .07);
  --tray: rgba(255, 255, 255, .06);
  --accent: #8fb0ff; --accent2: #ff86bd;
  --shadow: rgba(0, 0, 0, .45);
  --display: "Avenir Next", "Segoe UI Variable Display", "Trebuchet MS", system-ui, -apple-system, sans-serif;
  color-scheme: dark;
}
:root[data-theme="light"] {
  --bg: #f1eeff; --bg2: #fff;
  --ink: #1d2145; --muted: #6a6f9a;
  --panel: rgba(255, 255, 255, .75); --panel-line: rgba(40, 40, 110, .14);
  --cell: rgba(40, 40, 110, .08);
  --tray: rgba(255, 255, 255, .6);
  --shadow: rgba(40, 40, 110, .25);
  color-scheme: light;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; min-height: 100%; }
body {
  min-height: 100vh; min-height: 100dvh;
  font-family: var(--display); color: var(--ink);
  background: var(--bg);
  overflow-x: hidden;
  overscroll-behavior: none;
  -webkit-user-select: none; user-select: none;
  transition: background .4s, color .4s;
}
button { font: inherit; color: inherit; cursor: pointer; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* ---------- aurora background ---------- */
.aurora { position: fixed; inset: 0; overflow: hidden; z-index: 0; pointer-events: none; }
.aurora i { position: absolute; width: 60vmax; height: 60vmax; border-radius: 50%; filter: blur(70px); opacity: .5; animation: drift 26s ease-in-out infinite alternate; }
.aurora i:nth-child(1) { background: #5b6bff; left: -20vmax; top: -22vmax; }
.aurora i:nth-child(2) { background: #ff5db1; right: -24vmax; top: 10vmax; animation-duration: 32s; opacity: .38; }
.aurora i:nth-child(3) { background: #2fe0b8; left: 10vmax; bottom: -34vmax; animation-duration: 38s; opacity: .32; }
:root[data-theme="light"] .aurora i { opacity: .38; }
@keyframes drift { to { transform: translate(8vmax, 6vmax) scale(1.12); } }

/* ---------- layout ---------- */
.app {
  position: relative; z-index: 1;
  width: min(100%, 520px); margin: 0 auto;
  min-height: 100vh; min-height: 100dvh;
  padding: max(14px, env(safe-area-inset-top)) 14px max(14px, env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 14px; justify-content: center;
}
.top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.logo { width: 44px; height: 44px; flex: none; filter: drop-shadow(0 4px 10px var(--shadow)); }
.brand h1 { margin: 0; font-size: clamp(26px, 7.5vw, 34px); line-height: 1; letter-spacing: .02em; font-weight: 800; background: linear-gradient(90deg, #8af0d3, #8fb0ff 50%, #ff86bd); -webkit-background-clip: text; background-clip: text; color: transparent; }
[data-theme="light"] .brand h1 { background-image: linear-gradient(90deg, #1fae8a, #4a63e8 50%, #d63a82); }
.brand p { margin: 3px 0 0; font-size: 12px; color: var(--muted); white-space: nowrap; }
.scores { display: flex; gap: 8px; }
.box { position: relative; min-width: 76px; padding: 6px 12px 7px; border-radius: 14px; text-align: center; background: var(--panel); border: 1px solid var(--panel-line); backdrop-filter: blur(8px); box-shadow: 0 6px 18px var(--shadow); }
.box span { display: block; font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.box b { display: block; font-size: clamp(18px, 5.2vw, 24px); font-variant-numeric: tabular-nums; line-height: 1.15; }
#pop { position: absolute; left: 0; right: 0; top: 4px; font-style: normal; font-weight: 800; color: #8af0d3; opacity: 0; pointer-events: none; }
#pop.go { animation: pop-up .7s ease-out; }
@keyframes pop-up { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-34px); } }

.tools { display: flex; gap: 8px; }
.tool {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 44px; padding: 0 16px;
  border-radius: 14px; border: 1px solid var(--panel-line); background: var(--panel); backdrop-filter: blur(8px);
  font-weight: 700; font-size: 15px; letter-spacing: .01em; white-space: nowrap;
  box-shadow: 0 4px 12px var(--shadow); transition: transform .1s, filter .2s, opacity .2s, background .2s;
}
.tool svg { width: 20px; height: 20px; flex: none; }
.tool:hover:not(:disabled) { filter: brightness(1.12); }
.tool:active:not(:disabled) { transform: translateY(2px) scale(.98); }
.tool:disabled { opacity: .4; cursor: not-allowed; }
.tool.primary { border-color: transparent; color: #0b1033; background: linear-gradient(135deg, #8af0d3, #8fb0ff 55%, #c9a8ff); }
.tool.icon { width: 44px; padding: 0; }
.tools .primary { flex: 1; }
#btn-undo { flex: 1; }
#btn-sound.off .waves { display: none; }
#btn-sound.off { opacity: .6; }
#btn-theme .sun { display: none; }
:root[data-theme="light"] #btn-theme .sun { display: block; }
:root[data-theme="light"] #btn-theme .moon { display: none; }

/* ---------- board ---------- */
.stage { display: grid; place-items: center; }
.board {
  --gap: clamp(7px, 2.4vw, 12px);
  --w: max(220px, min(92vw, calc(100dvh - 270px), 500px));
  --cell: calc((var(--w) - var(--gap) * 5) / 4);
  position: relative; width: var(--w); height: var(--w);
  padding: var(--gap);
  border-radius: calc(var(--gap) * 2.4);
  background: var(--tray); border: 1px solid var(--panel-line);
  box-shadow: 0 24px 60px var(--shadow), inset 0 2px 0 rgba(255, 255, 255, .12);
  backdrop-filter: blur(10px);
  touch-action: none;                 /* swiping the board never scrolls the page */
  outline: none;
}
.board:focus-visible { box-shadow: 0 0 0 3px var(--accent), 0 24px 60px var(--shadow); }
.cells { position: absolute; inset: var(--gap); display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); }
.cells i { border-radius: calc(var(--cell) * .22); background: var(--cell); box-shadow: inset 0 2px 6px rgba(0, 0, 0, .25); }
:root[data-theme="light"] .cells i { box-shadow: inset 0 2px 5px rgba(40, 40, 110, .14); }
.tiles { position: absolute; inset: var(--gap); }
.board.nudge { animation: nudge .16s ease-out; }
.board.nudge[data-nudge="left"] { --nx: -5px; --ny: 0px; }
.board.nudge[data-nudge="right"] { --nx: 5px; --ny: 0px; }
.board.nudge[data-nudge="up"] { --nx: 0px; --ny: -5px; }
.board.nudge[data-nudge="down"] { --nx: 0px; --ny: 5px; }
@keyframes nudge { 50% { transform: translate(var(--nx), var(--ny)); } }

/* ---------- tiles ---------- */
.tile {
  position: absolute; left: 0; top: 0; width: var(--cell); height: var(--cell);
  transform: translate(calc(var(--x) * (var(--cell) + var(--gap))), calc(var(--y) * (var(--cell) + var(--gap))));
  transition: transform .12s cubic-bezier(.3, .7, .3, 1);
  --a: #fff; --b: #ccd; --t: #123;
}
.face {
  width: 100%; height: 100%; display: grid; place-items: center;
  border-radius: calc(var(--cell) * .22);
  font-weight: 800; font-size: calc(var(--cell) * .46); letter-spacing: -.02em; color: var(--t);
  font-variant-numeric: tabular-nums;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .42) 0 26%, transparent 26.3%),
    linear-gradient(315deg, rgba(0, 0, 0, .15) 0 22%, transparent 22.3%),
    linear-gradient(150deg, var(--a), var(--b));
  box-shadow: 0 calc(var(--cell) * .05) calc(var(--cell) * .12) rgba(0, 0, 0, .35), inset 0 2px 0 rgba(255, 255, 255, .55), inset 0 -4px 0 rgba(0, 0, 0, .16);
}
.tile.d3 .face { font-size: calc(var(--cell) * .37); }
.tile.d4 .face { font-size: calc(var(--cell) * .3); }
.tile.d5 .face { font-size: calc(var(--cell) * .25); }
.tile.d6 .face, .tile.d7 .face { font-size: calc(var(--cell) * .2); }
.tile.appear .face { animation: appear .2s cubic-bezier(.2, 1.4, .4, 1) both; }
.tile.merged { z-index: 2; }
.tile.merged .face { animation: merge .22s cubic-bezier(.3, 1.5, .5, 1); }
.tile.restored .face { animation: fade-in .16s ease-out; }
@keyframes appear { from { transform: scale(0); opacity: 0; } }
@keyframes merge { 45% { transform: scale(1.2); } }
@keyframes fade-in { from { opacity: 0; transform: scale(.85); } }

.v2 { --a: #9cc8ff; --b: #4f86e8; --t: #0e2250; }
.v4 { --a: #8af0d3; --b: #2fbf9b; --t: #06382d; }
.v8 { --a: #c8f57f; --b: #7cc23a; --t: #1f3a05; }
.v16 { --a: #ffe583; --b: #f2b928; --t: #4a3200; }
.v32 { --a: #ffc884; --b: #f08a2a; --t: #4a2200; }
.v64 { --a: #ffa393; --b: #ee5646; --t: #fff; }
.v128 { --a: #ff8fc3; --b: #e2438c; --t: #fff; }
.v256 { --a: #e8a5ff; --b: #b447e6; --t: #fff; }
.v512 { --a: #bba5ff; --b: #7650e8; --t: #fff; }
.v1024 { --a: #94b4ff; --b: #3f63e0; --t: #fff; }
.v2048 { --a: #fff3b0; --b: #e8a91c; --t: #4a2e00; }
.v2048 .face { box-shadow: 0 0 0 2px #fff6c4, 0 0 calc(var(--cell) * .4) rgba(255, 210, 90, .85), inset 0 2px 0 rgba(255, 255, 255, .7), inset 0 -4px 0 rgba(0, 0, 0, .16); animation: glow 1.6s ease-in-out infinite alternate; }
@keyframes glow { to { box-shadow: 0 0 0 2px #fff6c4, 0 0 calc(var(--cell) * .65) rgba(255, 210, 90, 1), inset 0 2px 0 rgba(255, 255, 255, .7), inset 0 -4px 0 rgba(0, 0, 0, .16); } }
.vbig { --a: #ffffff; --b: #bccbe8; --t: #1a2a4a; }

/* The light board uses the soft tabletop colours of the illustrated game. */
:root[data-theme="light"] { --bg:#f7f2ec; --bg2:#fffaf5; --tray:#e8dff2; --cell:#d7cce4; --panel-line:rgba(92,67,115,.2); --shadow:rgba(83,59,102,.22); }
:root[data-theme="light"] .aurora i { opacity:.18; }
:root[data-theme="light"] .board { border:7px solid #d2c0de; box-shadow:0 18px 34px rgba(77,61,89,.2),inset 0 2px 0 rgba(255,255,255,.6); }
:root[data-theme="light"] .cells i { background:#d7c8e3; border-radius:16%; box-shadow:inset 0 2px 5px rgba(91,68,106,.14); }
:root[data-theme="light"] .face { border-radius:16%; background:linear-gradient(145deg,var(--a),var(--b)); box-shadow:0 calc(var(--cell) * .045) calc(var(--cell) * .08) rgba(83,58,93,.22),inset 0 2px 0 rgba(255,255,255,.5); }
.vbig .face { box-shadow: 0 0 0 2px #fff, 0 0 calc(var(--cell) * .5) rgba(160, 200, 255, .9), inset 0 -4px 0 rgba(0, 0, 0, .12); }

/* ---------- overlay ---------- */
.overlay {
  position: absolute; inset: 0; z-index: 10; display: grid; place-items: center; padding: 14px;
  border-radius: inherit; background: rgba(8, 10, 28, .55); backdrop-filter: blur(6px);
  animation: ov-in .35s ease-out both;
}
:root[data-theme="light"] .overlay { background: rgba(240, 238, 255, .6); }
.overlay[hidden] { display: none; }
@keyframes ov-in { from { opacity: 0; } }
.card {
  position: relative; width: min(100%, 360px); padding: 22px 20px 20px; text-align: center; border-radius: 22px;
  background: linear-gradient(160deg, var(--bg2), var(--bg)); border: 1px solid var(--panel-line);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5); animation: card-in .45s cubic-bezier(.2, 1.2, .4, 1) both;
}
@keyframes card-in { from { opacity: 0; transform: translateY(24px) scale(.92); } }
.eyebrow { margin: 0; font-size: 11px; letter-spacing: .3em; text-transform: uppercase; color: var(--muted); }
.card h2 { margin: 4px 0 6px; font-size: clamp(34px, 11vw, 52px); line-height: 1; font-weight: 800; }
.overlay.win h2 { background: linear-gradient(90deg, #ffe27a, #ff9ac4 50%, #9cc8ff); -webkit-background-clip: text; background-clip: text; color: transparent; animation: shine 3s linear infinite; background-size: 200% 100%; }
@keyframes shine { to { background-position: -200% 0; } }
:root[data-theme="light"] .overlay.win h2 { background-image: linear-gradient(90deg, #e8a91c, #e2438c 50%, #4a63e8); }
.overlay.over h2 { color: #ff8aa0; }
.card p { margin: 0 0 14px; color: var(--muted); line-height: 1.45; }
.card p.eyebrow { margin: 0; }
.ov-actions { display: flex; gap: 8px; }
.ov-actions .tool { flex: 1; padding: 0 10px; }
.confetti { position: absolute; left: 50%; top: 30px; width: 0; height: 0; pointer-events: none; }
.confetti i { position: absolute; width: 8px; height: 12px; border-radius: 2px; animation: fall 1.6s cubic-bezier(.2, .7, .3, 1) both; }
@keyframes fall { 0% { transform: translate(0, 0) rotate(0); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) rotate(var(--r)); opacity: 0; } }

dialog { width: min(360px, calc(100vw - 28px)); padding: 22px; border-radius: 22px; color: var(--ink); background: linear-gradient(160deg, var(--bg2), var(--bg)); border: 1px solid var(--panel-line); box-shadow: 0 30px 80px rgba(0, 0, 0, .55); text-align: center; }
dialog::backdrop { background: rgba(5, 6, 20, .6); backdrop-filter: blur(4px); }
dialog h2 { margin: 0 0 6px; font-size: 24px; }
dialog p { margin: 0 0 16px; color: var(--muted); }

.hint { margin: 0; text-align: center; font-size: 13px; color: var(--muted); }
.hint .mob { display: none; }
@media (pointer: coarse) { .hint .desk { display: none; } .hint .mob { display: inline; } }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

@media (max-width: 400px) {
  .brand p { display: none; }
  .tool { padding: 0 10px; font-size: 14px; gap: 5px; }
  .box { min-width: 66px; padding: 5px 9px 6px; }
}
@media (max-width:640px) and (max-height:700px) and (orientation:portrait) {
  body.game-page .app { min-height:0; padding:8px 14px 12px; gap:8px; justify-content:flex-start; }
  body.game-page .board { --w:max(220px,min(92vw,calc(100dvh - 325px))); }
  .brand h1 { font-size:clamp(22px,6vw,28px); }
}
@media (max-height: 560px) and (orientation: landscape) {
  .app { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; max-width: 900px; gap: 10px 22px; }
  .app > .top, .app > .tools, .app > .hint { width: 300px; flex: none; }
  .app > .top { order: 1; } .app > .tools { order: 2; } .app > .hint { order: 3; }
  .app > .stage { order: 0; grid-row: auto; flex: none; }
  .board { --w: max(200px, calc(100dvh - 28px)); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
