/* =========================================================
   GLOBAL PAGE RESET
   ========================================================= */

/* Keep the game visually locked to one screen under normal
   conditions, WITHOUT using overflow:hidden. hidden would clip
   anything that doesn't fit and make it permanently unreachable —
   no scrollbar, no way back — which is worse than just scrolling if
   the flex-shrink math below is ever wrong (long text wrap, a
   phone's browser toolbar eating extra space, larger accessibility
   font settings, etc.). overflow-y:auto is a safety net instead of a
   hard block: if everything fits (the normal case), this behaves
   identically to hidden with no visible scrollbar. If something
   doesn't fit, the page becomes scrollable instead of eating a
   button with no way to reach it. */
html, body {
  height: 100%;
  margin: 0;
  overflow-y: auto;
}

/* Ensure all buttons behave as tap-friendly UI elements
   (removes the ~300ms tap-delay browsers add by default on touch) */
button {
  touch-action: manipulation;
}


/* =========================================================
   MAIN GAME LAYOUT CONTAINER
   ========================================================= */

/* This is the vertical "game screen stack":
   Title
   Instructions
   Win message (hidden until solved)
   HUD (moves + undo)
   Canvas (main play area)
   D-pad (controls)
   Footer link

   Everything is a single flex column so the canvas can be told to
   shrink (via flex + min-height:0 below) whenever the rest of the
   stack doesn't leave enough vertical room for it. */
.game-wrapper {
  max-width: 500px;
  margin: 0 auto;

  /* Never grow taller than the screen — combined with the
     overflow-y:auto safety net above, this is what keeps the whole
     game visually locked to one screen under normal conditions, on
     both desktop and mobile. */
  max-height: 100vh;

  /* Vertical stacking, top to bottom */
  display: flex;
  flex-direction: column;

  align-items: center;
  box-sizing: border-box;

  /* Small padding so nothing touches screen edges */
  padding: 12px;

  /* CRITICAL:
     gap adds vertical spacing between every direct child.
     Too large = D-pad gets pushed off screen on short viewports. */
  gap: 6px;
}


/* =========================================================
   HEADER TEXT
   ========================================================= */

h1 {
  font-size: 32px;
  /* keep it tight so it doesn't steal vertical space from the canvas */
  margin: 2px 0;
}


/* =========================================================
   INSTRUCTIONS TEXT
   ========================================================= */

.instructions {
  font-size: 18px;
  text-align: justify;

  /* IMPORTANT:
     removing margin prevents this text from adding extra height
     on top of the .game-wrapper gap, which would eat into the
     vertical budget resizeCanvas() assumes in sokoban.js */
  margin: 0;

  /* keeps it compact and readable */
  line-height: 1.2;
}

/* =========================================================
   LEVEL LABEL
   ========================================================= */

/* Text content is set entirely by updateLevelLabel() in sokoban.js —
   this only controls its appearance. */
#level-label {
  margin: 0;
  font-size: 15px;
  font-weight: bold;
  color: #003B6F;
}

/* =========================================================
   WIN MESSAGE
   ========================================================= */

/* Visibility (display: none/block) AND text content are both set by
   sokoban.js (checkWin()) — this rule only controls spacing/look for
   whenever it IS shown. Starts hidden; see the inline style note in
   sokoban-game.html. */
#win-message {
  display: none;
  margin: 6px 0;
  font-weight: bold;
}

/* =========================================================
   NEXT LEVEL BUTTON
   ========================================================= */

/* Hidden by default (shown only by checkWin() in sokoban.js, after a
   non-final level is solved). Styled like a slightly bigger, more
   celebratory version of the undo button since it's a reward moment. */
#next-level-button {
  display: none;
  background-color: #2a3182;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  touch-action: manipulation;
  margin: 4px 0;
}

#next-level-button:active {
  background-color: #003B6F;
}

/* =========================================================
   HUD (MOVE COUNTER + UNDO)
   ========================================================= */

.hud {
  display: flex;
  align-items: center;
  justify-content: center;

  /* Fixed gap between the move counter and the undo button.
     NOTE: on very narrow phone screens (under ~320px wide) this
     fixed 100px gap can get tight against .game-wrapper's max-width.
     If it ever wraps or clips on a real device, swap this for
     `justify-content: space-between;` on a full-width .hud instead
     of a fixed gap — that scales with screen width automatically. */
  gap: 100px;

  margin: 2px 0;
}

/* Move counter text */
#move-counter {
  margin: 0;
  font-size: 20px;
  font-weight: bold;
}

/* Undo button sizing */
#undo-button {
  padding: 4px 10px;
  font-size: 14px;

  /* prevents button from expanding layout if "Undo" text ever changes */
  width: 60px;
}


/* =========================================================
   CANVAS (MAIN GAME AREA)
   ========================================================= */

/* KEY IDEA:
   Canvas MUST be allowed to shrink when the screen is short,
   otherwise it pushes the D-pad off screen.

   NOTE ON SIZING — there are two systems working together here and
   they need to agree:
     1. sokoban.js sets canvas.width / canvas.height (the actual pixel
        drawing buffer) based on its own height budget math
        (window.innerHeight - 200, see resizeCanvas()).
     2. This CSS separately caps how large that canvas is *displayed*
        (max-height: 48vh below).
   If these two ever disagree (e.g. someone changes the "-200" magic
   number in JS without checking this file, or vice versa), the
   canvas can end up displayed at a different size than its internal
   pixel buffer, which stretches/blurs the pixel art instead of
   keeping crisp square tiles. Keep these two numbers in sync if you
   touch either one. */
#game-canvas {
  display: block;
  border: 2px solid #003B6F;

  /* allows the canvas to shrink in the flex column instead of
     forcing the D-pad off the bottom of the screen */
  flex: 1 1 auto;

  /* classic flexbox fix: without this, a flex item won't shrink
     below its content's natural size */
  min-height: 0;

  /* CRITICAL LIMIT:
     prevents canvas from consuming the entire screen even if there's
     leftover flex space to grow into */
  max-height: 48vh;

  /* ensures it doesn't force horizontal overflow on narrow screens */
  max-width: 100%;
}


/* =========================================================
   D-PAD (ON-SCREEN CONTROLS)
   ========================================================= */

.dpad {
  /* IMPORTANT:
     DO NOT allow flex stretching — the D-pad should stay a fixed
     size, only the canvas above it should flex/shrink */
  flex: 0 0 auto;

  /* spacing above it, separate from the .game-wrapper gap */
  margin-top: 4px;

  /* CRITICAL FIX:
     reserve exact space so nothing gets cut off — this height is
     part of the vertical budget assumed by the "-200" magic number
     in sokoban.js's resizeCanvas() (see note on #game-canvas above) */
  height: 200px;

  /* 3x3 grid with only the 4 cardinal directions filled in
     (center + corners intentionally left empty) */
  display: grid;
  grid-template-columns: 60px 60px 60px;
  grid-template-rows: 60px 60px 60px;

  gap: 4px;

  /* centers the 3x3 grid within the full-width .dpad container */
  justify-content: center;
  align-content: center;

  /* DEBUG TIP:
     if buttons still clip, temporarily add:
     border: 1px solid red;
  */
}


/* =========================================================
   D-PAD BUTTONS
   ========================================================= */

.dpad-button {
  background-color: #2a3182;
  color: white;

  border: none;
  border-radius: 6px;

  font-size: 32px;
  font-weight: bold;

  cursor: pointer;

  /* IMPORTANT for mobile taps — removes tap-delay + double-tap zoom */
  touch-action: manipulation;

  /* prevents the arrow glyph from being selected/highlighted on tap */
  user-select: none;
}

/* Visual feedback when pressed (mouse) or tapped (touch) */
.dpad-button:active {
  background-color: #003B6F;
}


/* Positioning inside the 3x3 grid — up/left/right/down only,
   the four corners and the center cell are left empty */
.dpad-up    { grid-column: 2; grid-row: 1; }
.dpad-left  { grid-column: 1; grid-row: 2; }
.dpad-right { grid-column: 3; grid-row: 2; }
.dpad-down  { grid-column: 2; grid-row: 3; }

/* =========================================================
   FOOTER
   ========================================================= */

.footer {
  text-align: center;
  margin-top: auto; /* pushes footer to the bottom of the flex column
                        naturally, without needing a fixed height */
}

/* =========================================================
   OPTIONAL: DEBUGGING HELP
   ========================================================= */

/*
If layout breaks:

1. Temporarily enable borders:
.game-wrapper { border: 2px solid red; }
#game-canvas { border: 2px solid green; }
.dpad { border: 2px solid blue; }

2. Then check:
   - canvas height too large?
   - gap too large?
   - viewport too short?
*/
