/* Memory match game — styled against the site's design tokens (see :root
   in style.css). Shared card-grid/difficulty-picker pieces live in
   games.css. Covers both the setup screen and the play/board screen. */

.memory-setup {
  max-width: 640px;
  margin: 0 auto 3rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.start-play-btn {
  align-self: center;
  width: 88px;
  height: 88px;
  padding: 0;
  border: none;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--coral);
  color: var(--white);
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(226, 114, 91, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.start-play-btn:hover, .start-play-btn:focus-visible {
  transform: translateY(-2px) scale(1.05);
  background: var(--coral-deep);
}

.start-play-btn svg {
  width: 88px;
  height: 88px;
  margin-left: 5px;
  fill: currentColor;
}

.start-play-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
}

.setup-field {
  border: none;
  padding: 0;
  margin: 0;
}

.setup-field legend {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1rem;
  margin-bottom: 0.75rem;
  padding: 0;
}

.scope-options {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
  font-weight: 700;
}

.scope-options label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  padding: 0.55rem 1rem;
  border-radius: 999px;
  border: 2px solid var(--ink-soft);
  background: var(--white);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.scope-options input[type="radio"] {
  accent-color: var(--coral);
}

.scope-options label:has(input:checked) {
  background: var(--coral);
  border-color: var(--coral);
  color: var(--white);
}

.scope-detail {
  margin-top: 1.25rem;
}

.book-select-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.book-select {
  font: inherit;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-md);
  border: 2px solid var(--ink-soft);
  background: var(--white);
  color: var(--ink);
}

.book-select-cover {
  width: 120px;
  height: 120px;
  border-radius: var(--radius-sm, 6px);
  object-fit: cover;
  border: 2px solid var(--ink-soft);
  flex-shrink: 0;
}

.scope-count {
  font-weight: 700;
  margin: 0 0 1rem;
}

.custom-checklist {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 16px;
}

.custom-checklist-item {
  cursor: pointer;
  position: relative;
}

.custom-checklist-item.is-selected {
  outline: 3px solid var(--mustard);
  outline-offset: -3px;
}

.custom-checklist-item.is-selected .game-card-thumb::after {
  content: "✓";
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--mustard);
  color: var(--ink);
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
}

.custom-checklist-item .game-card-thumb {
  position: relative;
}

.custom-checklist-input {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 20px;
  height: 20px;
  z-index: 1;
}

.custom-checklist-item .game-card-info {
  padding: 10px 12px 14px;
}

.custom-checklist-item .game-card-info h3 {
  font-size: 0.95rem;
}

.custom-pairs {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: center;
  font-weight: 700;
}

.custom-pairs input[type="range"] {
  width: 100%;
  max-width: 320px;
  accent-color: var(--coral);
}

/* ---------- Board / play screen ---------- */
.memory-page {
  text-align: center;
  padding-bottom: 3rem;
}

.memory-stats {
  display: flex;
  justify-content: center;
  gap: 1.5rem;
  font-weight: 700;
  margin-top: 1.25rem;
  margin-bottom: 1.5rem;
}

/* Breaks the board out of the page's normal ~1080px content column so it
   can use the full browser window width on a big monitor, while the
   title/slider above it and the moves/timer below stay in the normal
   column. Standard full-bleed technique: size to the viewport, then
   re-center.

   Width comes from --board-viewport-width (set by memory-game.js) rather
   than 100vw, because 100vw includes the vertical scrollbar: that made this
   element a scrollbar's width too wide, so it hung off both edges and the
   centred board inside it shifted sideways every time the scrollbar
   appeared or disappeared. The 100vw fallback only applies before the
   script runs. */
.memory-board-breakout {
  width: var(--board-viewport-width, 100vw);
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  padding: 0 16px;
  box-sizing: border-box;
  /* clip, NOT auto/hidden. A non-visible overflow on one axis forces the
     other axis from visible to auto, which quietly made this a *vertical*
     scroll container: the flip animation's 3D projection sticks a few px
     below a bottom-row card, that counted as scrollable height, and the
     resulting scrollbar stole 15px of width so the centred board jumped
     sideways mid-flip. clip is the one value that doesn't drag the other
     axis along with it, so overflow-y stays visible and the projection
     can render outside the box as intended. */
  overflow-x: clip;
}

.memory-board {
  display: grid;
  /* Column count AND per-card size are both computed in JS from the
     actual window width/height/card-count (see memory-game.js) and set
     directly as an explicit grid-template-columns. Not auto-fit: this
     needs to jointly reason about width, height, and how many cards there
     are to avoid vertical scrolling, which is beyond what a single CSS
     track-sizing function can express — and auto-fit's own column-
     counting rules turned out to have real gotchas (see git history). */
  /* memory-game.js reads this back with getComputedStyle to do its
     sizing math, so this declaration is the only place it's set. */
  gap: 10px;
  justify-content: center;
  margin: 0 auto;
  padding-bottom: 4px;
}

.memory-size-control {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  margin-bottom: 1.25rem;
  font-weight: 700;
}

.memory-size-control input[type="range"] {
  width: 160px;
  accent-color: var(--coral);
}

.memory-size-debug {
  font-family: monospace;
  font-size: 0.8rem;
  color: var(--ink-soft);
  font-weight: 400;
}

.memory-card {
  border: none;
  padding: 0;
  margin: 0;
  background: none;
  aspect-ratio: 1 / 1;
  cursor: pointer;
  perspective: 800px;
}

.memory-card:disabled {
  cursor: default;
}

.memory-card-inner {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  transition: transform 0.4s ease;
  transform-style: preserve-3d;
}

.memory-card.is-flipped .memory-card-inner {
  transform: rotateY(180deg);
}

.memory-card-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.memory-card-back {
  background: radial-gradient(circle at 50% 40%, #33436640 0%, var(--ink) 75%), var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22%;
}

.memory-card-back svg {
  width: 100%;
  height: 100%;
}

.memory-card-front {
  background: var(--white);
  transform: rotateY(180deg);
}

.memory-card-front img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.memory-card.is-matched .memory-card-front {
  outline: 3px solid var(--sage);
  outline-offset: -3px;
}

.memory-board.is-locked .memory-card:not(.is-flipped) {
  cursor: default;
}

/* Applied to the outer button (not memory-card-inner, which already owns
   the flip's rotateY transform — animating transform there too would
   fight the flip mid-pop). Only ever set on the pair that just resolved,
   so re-rendering the board for a later match doesn't replay this on
   already-matched cards. */
@keyframes memory-match-pop {
  0% { transform: scale(0.9); }
  60% { transform: scale(1.08); }
  100% { transform: scale(1); }
}

.memory-card.is-newly-matched {
  animation: memory-match-pop 0.4s ease;
}

@media (prefers-reduced-motion: reduce) {
  .memory-card-inner { transition: none; }
  .memory-card.is-newly-matched { animation: none; }
}

.memory-status {
  margin-top: 1.25rem;
  font-weight: 700;
  min-height: 1.6em;
}

@keyframes memory-win-pop {
  0% { transform: scale(0.8) rotate(-1.5deg); opacity: 0; }
  60% { transform: scale(1.05) rotate(-1.5deg); opacity: 1; }
  100% { transform: scale(1) rotate(-1.5deg); opacity: 1; }
}

.memory-status.is-solved {
  font-family: var(--font-hand);
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--coral-deep);
  display: inline-block;
  transform: rotate(-1.5deg);
  animation: memory-win-pop 0.5s ease;
}

@media (prefers-reduced-motion: reduce) {
  .memory-status.is-solved { animation: none; }
}

.memory-actions {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1.75rem;
}
