/*
 * Chrome for the interactive playable-puzzle widgets (Sudoku first; later tents/maze reuse the .pp-* base).
 * The board itself is SVG drawn in JS (shared WalkthroughPlayer toolkit); this file owns only the surrounding
 * controls, number pad, and state colours. Type-specific rules live under a `.pp-<type>` root when needed, or under
 * `.pp-host[data-puzzle="<type>"]` for a type that shares another's player (mini sudoku).
 *
 * Progressive enhancement: the widget host `.pp-host` shows only once the page's inline script has added `js`
 * to <html>; without JS the reader keeps the static image / PDF link that precedes it. Page chrome that does
 * nothing without JS carries the generic `.js-only` (bootstrap.override.css).
 */

html:not(.js) .pp-host {
  display: none;
}

.pp-widget {
  max-width: 30rem;
  margin: 1rem auto;
  font-family: inherit;
}

.pp-board-wrap {
  position: relative;
}

.pp-grid {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid #cfcfcf;
  border-radius: 6px;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  cursor: pointer;
}

.pp-grid:focus {
  outline: none;
}

.pp-grid:focus-visible {
  outline: 3px solid var(--board-green);
  outline-offset: 2px;
}

/* Win banner overlaid on the board. */
.pp-win {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: #ffffffd9;
  border-radius: 6px;
  text-align: center;
  padding: 1rem;
}

.pp-won .pp-win {
  display: flex;
}

.pp-win-inner {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--board-green);
}

.pp-win-time {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: #444;
}

.pp-statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0.5rem 0.1rem;
  font-size: 0.95rem;
  color: #444;
}

.pp-timer {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.pp-msg {
  min-height: 1.2em;
  color: #cc3333;
  font-weight: 600;
}

.pp-msg.pp-msg-ok {
  color: var(--board-green);
}

/* Guidance, neither a mistake nor a success. */
.pp-msg.pp-msg-note {
  color: #5f6872;
  font-weight: normal;
}

/* Number pad. */
.pp-pad {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: 0.3rem;
  margin: 0.5rem 0;
}

/* Controls take the walkthrough players' button look (.swt-btn / .twt-btn), so the play board and the
   step-by-step board beside it read as one family. */
.pp-num {
  aspect-ratio: 1 / 1;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--board-green);
  background: #ffffff;
  border: 1px solid var(--board-green);
  border-radius: 0.35rem;
  cursor: pointer;
  transition: background 0.1s ease;
}

.pp-num:hover {
  background: var(--board-green-tint);
}

.pp-num:active {
  background: #cfe8d8;
}

@media (max-width: 32rem) {
  .pp-pad {
    grid-template-columns: repeat(5, 1fr);
  }

  .pp-toolbar .pp-btn {
    min-height: 44px;
  }
}

/* Mini sudoku: a narrower board, status bar and pad, so 4×4 does not read as a toy blown up, with its four digits in
   one row. The toolbar keeps the widget's full width: at 24rem its five buttons wrap onto a second row. Keyed on the
   host, so the server placeholder, the lazy placeholder and the board all take it. */
.pp-host[data-puzzle="mini_sudoku"] .pp-board-wrap,
.pp-host[data-puzzle="mini_sudoku"] .pp-statusbar,
.pp-host[data-puzzle="mini_sudoku"] .pp-pad {
  max-width: 24rem;
  margin-left: auto;
  margin-right: auto;
}

.pp-host[data-puzzle="mini_sudoku"] .pp-pad {
  grid-template-columns: repeat(4, 1fr);
}

/* A square key would be a quarter of the board wide: 6rem tall on desktop. */
.pp-host[data-puzzle="mini_sudoku"] .pp-num {
  aspect-ratio: auto;
  min-height: 3rem;
  font-size: 1.4rem;
}

/* Quick repeated taps on a digit would otherwise trigger double-tap zoom on iOS. */
.pp-num,
.pp-btn,
.pp-difficulty-btn {
  touch-action: manipulation;
}

/* Action toolbar (pencil, erase, check, hint, reset). */
.pp-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.pp-btn {
  flex: 1 1 auto;
  min-width: 5rem;
  padding: 0.5rem 0.6rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--board-green);
  background: #ffffff;
  border: 1px solid var(--board-green);
  border-radius: 0.35rem;
  cursor: pointer;
}

.pp-btn:hover {
  background: var(--board-green-tint);
}

.pp-btn[aria-pressed="true"] {
  color: #fff;
  background: var(--board-green);
}

/* Standalone play page: difficulty tabs, next-puzzle bar, book attribution. */
.pp-difficulty {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 1rem 0;
}

.pp-difficulty-btn {
  flex: 1 1 auto;
  min-width: 5rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--board-green);
  background: #ffffff;
  border: 1px solid var(--board-green);
  border-radius: 0.35rem;
  cursor: pointer;
}

.pp-difficulty-btn:hover {
  background: var(--board-green-tint);
}

.pp-difficulty-active,
.pp-difficulty-active:hover {
  color: #fff;
  background: var(--board-green);
}

.pp-next-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin: 0.75rem 0 0.25rem;
}

.pp-next-bar .pp-btn {
  flex: 0 0 auto;
  min-width: 11rem;
}

/* Solving the board is the moment the next puzzle becomes the obvious action. */
.pp-next-ready,
.pp-next-ready:hover {
  color: #fff;
  background: var(--board-green);
}

.pp-next-msg {
  color: #cc3333;
  font-size: 0.9rem;
  font-weight: 600;
}

.pp-origin {
  margin-top: 0.75rem;
  text-align: center;
  font-size: 0.9rem;
  color: #555;
}

/* Online-play hub (/bulmaca-oyna). */
.pp-hub-game {
  display: flex;
  align-items: center;
  gap: 2rem;
  margin-top: 1.5rem;
  padding: 1.5rem;
  border: 1px solid #dee2e6;
  border-radius: 0.25rem;
}

.pp-hub-board-link {
  flex: 0 0 240px;
}

.pp-hub-board {
  display: block;
  width: 240px;
  height: 240px;
  border: 1px solid #dee2e6;
  border-radius: 0.25rem;
}

.pp-hub-game-body {
  flex: 1 1 auto;
  min-width: 0;
}

.pp-hub-levels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.pp-hub-play-btn {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  font-weight: 700;
  color: #fff;
  background: var(--action-green);
  border-color: var(--action-green);
}

.pp-hub-play-btn:hover,
.pp-hub-play-btn:focus {
  color: #fff;
  background: #1f5a46;
  border-color: #1f5a46;
}

.pp-hub-soon-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.pp-hub-soon {
  padding: 1rem 1.25rem;
  border: 1px solid #dee2e6;
  border-radius: 0.25rem;
}

.pp-hub-soon-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.pp-hub-soon a {
  color: var(--action-green);
}

.pp-soon-pill {
  flex: 0 0 auto;
  padding: 0.1rem 0.55rem;
  font-size: 0.8rem;
  color: #495057;
  border: 1px solid #ced4da;
  border-radius: 1rem;
}

@media (max-width: 767.98px) {
  .pp-hub-game {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    padding: 1rem;
  }

  .pp-hub-board-link {
    flex-basis: auto;
    align-self: center;
  }

  .pp-hub-levels .btn,
  .pp-hub-play-btn {
    min-height: 44px;
  }

  .pp-hub-play-btn {
    display: block;
    width: 100%;
    line-height: 30px;
  }

  .pp-hub-soon-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .pp-hub-soon a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Maze (maze-play.js). Wider than sudoku so a 40-cell maze keeps usable cells on a desktop (16px at 40rem); a phone
   still gets the full column. The board takes every touch, so a drawing stroke never scrolls the page. */
.pp-widget.pp-maze {
  max-width: 40rem;
}

.pp-maze .pp-grid {
  touch-action: none;
  cursor: crosshair;
}

/* Touch draws 45px above the finger (maze-play.js), so the bottom rows are reached from a finger resting below the
   board. any-pointer, not pointer: a touch laptop's primary pointer is fine, yet its finger still needs the strip.
   Placeholders and the widget share this rule, so the page does not shift when the maze mounts. */
@media (any-pointer: coarse) {
  .pp-maze .pp-board-wrap {
    padding-bottom: 45px;
    touch-action: none;
  }

  .pp-maze .pp-win {
    bottom: 45px;
  }
}

/* Tents (tents-play.js). A drag paints grass, so the board takes every touch and a stroke never scrolls the page; a
   tap is the same gesture, so no touch offset is needed. */
.pp-tents .pp-grid {
  touch-action: none;
}

/* Battleships (battleships-play.js). A drag paints water, so the board takes every touch, as on tents. The fleet line
   has one height and never wraps (a 10×10 fleet is about 260px wide), so the placeholder holds its place empty and the
   board's arrival does not move the page. */
.pp-battleships .pp-grid {
  touch-action: none;
}

.pp-fleet {
  display: flex;
  flex-wrap: nowrap;
  justify-content: safe center;
  align-items: center;
  gap: 0.5rem;
  height: 1.25rem;
  margin-top: 0.5rem;
  overflow: hidden;
}

.pp-fleet-ship {
  display: inline-flex;
  gap: 1px;
}

.pp-fleet-cell {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 1px;
  background: #1f3b57;
}

.pp-fleet-done .pp-fleet-cell {
  background: #c9c9c9;
}

.pp-fleet-over .pp-fleet-cell {
  background: #cc3333;
}
