/* Page: green table on every width; the clip grows with the game instead of keeping 4:3,
   and "Spiel vergrößern" enlarges board and card instead of zooming the whole game. */

/* Registered, so that the width of the card can change smoothly: card, board and tiles are all measured from it
   and grow together, frame by frame. */
@property --g48-card {
  syntax: '<length>';
  inherits: true;
  initial-value: 500px;
}

.page-2048 .game-section {
  background: #005000;
}

.page-2048 .game-clip {
  --g48-card: 500px;
  aspect-ratio: auto;
  transition: width 0.3s ease, --g48-card 0.3s ease;
}

.page-2048 .game-clip--large {
  --g48-card: 640px;
}

.page-2048 .game-clip--large .game-inner {
  zoom: 1;
}

@media (max-width: 850px) {
  .page-2048 .game-section {
    padding: 20px 5px;
  }
}

/* Game */

#g48-app {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* The board is a square as wide as the card allows and as high as the window allows (--g48-chrome is
   everything else on the screen), never under 240px. Four cells and five gaps fill it. */
#g48-game {
  --g48-pad: 16px;
  --g48-chrome: 170px;
  --g48-w: min(var(--g48-card), calc(100vw - 20px));
  --g48-board: max(240px, min(calc(var(--g48-w) - 2 * var(--g48-pad)), calc(100vh - var(--g48-chrome))));
  --g48-gap: calc(var(--g48-board) * 0.03);
  --g48-cell: calc((var(--g48-board) - 5 * var(--g48-gap)) / 4);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "score new" "stage stage";
  justify-items: center;
  gap: 12px 8px;
  box-sizing: border-box;
  width: var(--g48-w);
  padding: var(--g48-pad);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
  color: #1f2d1f;
  font-family: 'Inter', system-ui, sans-serif;
  text-transform: uppercase;
  user-select: none;
}

/* Buttons do not inherit the capitals on their own (the browser sets text-transform: none on them). */
#g48-game button {
  text-transform: inherit;
}

#g48-score {
  grid-area: score;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  width: 100%;
  container-type: inline-size;
}

.g48-score-box {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  padding: 6px 2px;
  background: #f1f4f1;
  border-radius: 8px;
}

.g48-score-label {
  font-size: min(12px, 6cqw);
  color: #556355;
  white-space: nowrap;
}

/* Up to seven digits fit a box on the narrowest phone. */
.g48-score-value {
  font-size: min(22px, 10cqw);
  font-weight: 600;
  line-height: 1.1;
}

/* The points just won rise out of the score and fade. */
.g48-plus {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 6px;
  font-size: 18px;
  font-weight: 600;
  color: #179a4b;
  text-align: center;
  pointer-events: none;
  animation: g48-rise 0.6s ease-out forwards;
}

/* The buttons of the other games (Games/shared/ui.css) as on the Sokoban page: light green with a green glow; under
   the mouse white with green letters and a thin green ring, no glow, because the card is white. */
#g48-new,
#g48-over-buttons button {
  padding: 10px 14px;
  font: 600 14px 'Inter', system-ui, sans-serif;
  color: #fff;
  background: #00b050;
  border: 0;
  border-radius: 8px;
  box-shadow: 0 0 8px rgba(0, 176, 80, 0.8);
  cursor: pointer;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
}

#g48-new {
  grid-area: new;
  align-self: stretch;
}

/* the question: red with a red glow */
#g48-new.g48-confirm {
  background: #e5534b;
  box-shadow: 0 0 8px rgba(229, 83, 75, 0.8);
}

/* The board and, above it, the message at the end. */
#g48-stage {
  grid-area: stage;
  position: relative;
}

#g48-board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: var(--g48-gap);
  box-sizing: border-box;
  width: var(--g48-board);
  height: var(--g48-board);
  padding: var(--g48-gap);
  background: #b7c5b7;
  border-radius: 8px;
  touch-action: none;
  cursor: grab;
}

/* While the board is held, the closed hand stays wherever the mouse goes, over buttons and outside the board too. */
html.g48-grabbing,
html.g48-grabbing * {
  cursor: grabbing !important;
}

.g48-cell {
  background: #dfe7df;
  border-radius: 5px;
}

#g48-tiles {
  position: absolute;
  inset: var(--g48-gap);
  pointer-events: none;
}

/* A tile stands at column --x and row --y (set by the script) and slides there. Size and place are shares of the
   board, not lengths: when the board grows the transform stays the same, so the tiles grow with it instead of
   sliding after it. A cell is 0.2125 of the board and a cell with its gap 0.2425 (see --g48-cell); this layer is
   the board less two gaps, 0.94. */
.g48-tile {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(100% * 0.2125 / 0.94);
  height: calc(100% * 0.2125 / 0.94);
  transform: translate(calc(var(--x) * 100% * 0.2425 / 0.2125), calc(var(--y) * 100% * 0.2425 / 0.2125));
  transition: transform 0.1s ease-in-out;
}

.g48-tile-in {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: calc(var(--g48-cell) * 0.46);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  border-radius: 5px;
}

.g48-d3 .g48-tile-in { font-size: calc(var(--g48-cell) * 0.38); }
.g48-d4 .g48-tile-in { font-size: calc(var(--g48-cell) * 0.3); }
.g48-d5 .g48-tile-in { font-size: calc(var(--g48-cell) * 0.24); }

/* From light greens over the green of the table to gold; 2048 glows, anything above it is dark. */
.g48-v2 .g48-tile-in { color: #3a4a3a; background: #eef3ee; }
.g48-v4 .g48-tile-in { color: #3a4a3a; background: #d9e9d3; }
.g48-v8 .g48-tile-in { color: #1f2d1f; background: #a6dbaa; }
.g48-v16 .g48-tile-in { color: #fff; background: #2e9b55; }
.g48-v32 .g48-tile-in { color: #fff; background: #1d7f42; }
.g48-v64 .g48-tile-in { color: #fff; background: #005000; }
.g48-v128 .g48-tile-in { color: #1f2d1f; background: #f6dc7a; }
.g48-v256 .g48-tile-in { color: #1f2d1f; background: #f4d058; }
.g48-v512 .g48-tile-in { color: #1f2d1f; background: #f1c339; }
.g48-v1024 .g48-tile-in { color: #1f2d1f; background: #ffb300; box-shadow: 0 0 12px 2px rgba(255, 179, 0, 0.35); }
.g48-v2048 .g48-tile-in { color: #1f2d1f; background: #ff9800; box-shadow: 0 0 18px 4px rgba(255, 152, 0, 0.5); }
.g48-vbig .g48-tile-in { color: #fff; background: #1f2d1f; }

/* A tile made by a merge lies above the ones sliding in, and pops; a new tile grows from nothing. */
.g48-merged {
  z-index: 2;
}

.g48-merged .g48-tile-in {
  animation: g48-pop 0.2s ease;
}

.g48-new .g48-tile-in {
  animation: g48-appear 0.2s ease;
}

#g48-over {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 16px;
  box-sizing: border-box;
  background: rgba(238, 243, 238, 0.88);
  border-radius: 8px;
  text-align: center;
  animation: g48-fade 0.4s ease;
}

#g48-over.g48-show {
  display: flex;
}

#g48-over.g48-win {
  background: rgba(255, 214, 110, 0.88);
}

#g48-over-text {
  margin: 0;
  font-size: calc(var(--g48-board) * 0.075);
  font-weight: 600;
  line-height: 1.2;
}

#g48-over-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

#g48-over-buttons button[hidden] {
  display: none;
}

#g48-new:focus-visible,
#g48-over-buttons button:focus-visible {
  outline: 3px solid #00b050;
  outline-offset: 2px;
}

/* Hover only where there is a mouse: after a tap on a phone it would stick to the button. */
@media (hover: hover) {
  #g48-new:not(.g48-confirm):hover,
  #g48-over-buttons button:hover {
    color: #00b050;
    background: #fff;
    box-shadow: inset 0 0 0 1px #00b050;
  }

  #g48-new.g48-confirm:hover {
    background: #ef6a62;
  }

  /* as in the other games: while one button is under the mouse, the other loses its glow */
  #g48-over-buttons:has(button:hover) button:not(:hover) {
    box-shadow: none;
  }
}

@keyframes g48-appear {
  0% { opacity: 0; transform: scale(0); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes g48-pop {
  0% { transform: scale(0); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

@keyframes g48-rise {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-40px); }
}

@keyframes g48-fade {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .page-2048 .game-clip,
  .g48-tile,
  .g48-tile-in,
  #g48-over {
    transition: none !important;
    animation: none !important;
  }
}

/* Tablets: the page header stands above the game. */
@media (min-width: 851px) and (max-width: 1024px) {
  #g48-game {
    --g48-chrome: 210px;
  }
}

/* The narrowest phones: a little less padding. */
@media (max-width: 360px) {
  #g48-game {
    --g48-pad: 12px;
  }

  #g48-new {
    padding: 10px;
  }
}

/* Phones held sideways: board on the left, score and button beside it. */
@media (orientation: landscape) and (max-height: 500px) {
  #g48-game {
    --g48-w: min(600px, calc(100vw - 20px));
    --g48-board: max(200px, calc(100vh - 110px));
    grid-template-areas: "stage score" "stage new";
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    align-items: start;
    column-gap: 16px;
  }

  #g48-new {
    align-self: start;
    justify-self: stretch;
  }

  .g48-score-value {
    font-size: min(18px, 10cqw);
  }
}
