/* --------------------------------------------------------------------------
   Catalog
   -------------------------------------------------------------------------- */
.catalog-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 2.4rem;
}

.game-grid {
  display: grid;
  gap: 1.8rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20.5rem), 1fr));
}

.game-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  transition: transform 450ms ease, border-color 450ms ease, box-shadow 450ms ease;
}
.game-card:hover,
.game-card:focus-within {
  transform: translateY(-8px);
  border-color: var(--bdr2);
  box-shadow: var(--shadow-2);
}

/* scan line sweep */
.game-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: -100%;
  z-index: 5;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  transition: left 600ms ease;
  pointer-events: none;
}
.game-card:hover::before,
.game-card:focus-within::before {
  left: 100%;
}

.card-visual {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--bdr);
}
.card-visual .board-art {
  transition: transform 600ms ease;
}
.game-card:hover .card-visual .board-art,
.game-card:focus-within .card-visual .board-art {
  transform: scale(1.05);
}

/* A real screenshot of the game, one per theme. Both are in the markup and the
   theme picks which one paints — a <picture> would only track the OS setting,
   and this site's theme is a choice the visitor makes. */
.card-shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 320 / 200;
  object-fit: cover;
  object-position: center;
  transition: transform 600ms ease;
}
.shot-dark { display: none; }
[data-theme="deep"] .shot-light,
[data-theme="midnight"] .shot-light { display: none; }
[data-theme="deep"] .shot-dark,
[data-theme="midnight"] .shot-dark { display: block; }
.game-card:hover .card-shot,
.game-card:focus-within .card-shot {
  transform: scale(1.05);
}
/* Fades the art into the card body below it. The colour has to be the card's
   own background — it was hardcoded to the deep theme's #0c1e34, which drew a
   navy smear across the bottom of every card on the cream theme. */
.card-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 40%,
              color-mix(in srgb, var(--paper) 90%, transparent) 100%);
  pointer-events: none;
}

.card-badges {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  z-index: 3;
  display: flex;
  gap: 0.4rem;
}

.card-play {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 400ms ease;
  pointer-events: none;
}
.game-card:hover .card-play,
.game-card:focus-within .card-play {
  opacity: 1;
}
.play-circle {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 30px var(--glow);
  transform: scale(0.8);
  transition: transform 300ms ease;
}
.game-card:hover .play-circle,
.game-card:focus-within .play-circle {
  transform: scale(1);
}
.play-circle svg {
  width: 20px;
  height: 20px;
  fill: var(--btn-fg);            /* measured ink on an accent fill */
  margin-left: 3px;
}

.card-body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1.2rem 1.5rem 1.5rem;
}
.card-body h3 {
  margin: 0;
  font-size: 1.06rem;
}
.card-meta {
  display: flex;
  gap: 0.7rem;
  align-items: center;
  flex-wrap: wrap;
}
.card-meta span {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.8rem;
  margin-top: 0.5rem;
}
.card-go {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  transition: gap 300ms ease;
}
.game-card:hover .card-go {
  gap: 0.75rem;
}
.card-price {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--green);
}
.card-price.tba {
  color: var(--muted);
}

/* stretched link */
.card-link {
  color: inherit;
  text-decoration: none;
}
.card-link:hover {
  color: inherit;
}
.card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: 6px;
}

/* --------------------------------------------------------------------------
   Board art (inline SVG, real pentomino geometry)
   -------------------------------------------------------------------------- */
.board-art {
  width: 100%;
  height: auto;
}
.board-art .cell-glyph {
  fill: none;
  stroke: var(--muted);
  stroke-width: 1;
  opacity: 0.25;
}
.board-art .piece-a {
  fill: var(--accent);
  fill-opacity: 0.1;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linejoin: round;
}
.board-art .piece-b {
  fill: var(--accent-2);
  fill-opacity: 0.12;
  stroke: var(--accent-2);
  stroke-width: 2;
  stroke-linejoin: round;
}
.board-art .piece-quiet {
  fill: var(--muted);
  fill-opacity: 0.1;
  stroke: var(--muted);
  stroke-width: 1.5;
  stroke-linejoin: round;
  opacity: 0.7;
}
.board-art .piece-gap {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-dasharray: 4 7;
  opacity: 0.6;
}
.board-art .guide {
  stroke: var(--muted);
  stroke-width: 1;
  stroke-dasharray: 2 6;
  stroke-linecap: round;
  opacity: 0.5;
}
.board-art .art-tint-a {
  fill: var(--accent);
  opacity: 0.04;
}
.board-art .art-tint-b {
  fill: var(--accent-2);
  opacity: 0.05;
}

/* a piece slowly settling, resting, and beginning again */
@keyframes settle {
  0% {
    transform: translateY(-88px);
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  38% {
    transform: translateY(0);
  }
  86% {
    transform: translateY(0);
    opacity: 1;
  }
  94% {
    transform: translateY(0);
    opacity: 0;
  }
  100% {
    transform: translateY(-88px);
    opacity: 0;
  }
}
.fall-piece {
  animation: settle 18s cubic-bezier(0.3, 0.6, 0.2, 1) infinite;
}
.fall-piece.late {
  animation-delay: 9s;
  animation-duration: 22s;
}

/* hover previews — the tiles play a little of themselves on intent */
.game-card .gap-fill {
  opacity: 0;
}
.game-card:hover .gap-fill,
.game-card:focus-within .gap-fill {
  animation: gapfill 2.8s ease-in-out infinite;
}
@keyframes gapfill {
  0% {
    opacity: 0;
    transform: translateY(-26px);
  }
  28% {
    opacity: 1;
    transform: none;
  }
  68% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: none;
  }
}
.game-card:hover .drop-piece,
.game-card:focus-within .drop-piece {
  animation: carddrop 3s ease-in infinite;
}
.game-card:hover .guide,
.game-card:focus-within .guide {
  animation: guidepulse 1.2s ease-in-out infinite alternate;
}
@keyframes carddrop {
  0% {
    transform: none;
    opacity: 1;
  }
  38% {
    transform: translateY(40px);
  }
  72% {
    transform: translateY(40px);
    opacity: 1;
  }
  84% {
    transform: translateY(40px);
    opacity: 0;
  }
  85% {
    transform: none;
    opacity: 0;
  }
  100% {
    transform: none;
    opacity: 1;
  }
}
@keyframes guidepulse {
  from {
    opacity: 0.35;
  }
  to {
    opacity: 0.85;
  }
}

/* ---------------- the rails ----------------
   The catalog is grouped by STATUS rather than genre: one game per genre would
   be a row of one, and a row of one is a card wearing a heading. */
.rail-group + .rail-group { margin-top: 2.6rem; }
.rail-title {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.9rem;
}
/* The scroller carries tabindex so a keyboard can reach it, and anything
   focusable must show that it is. */
.rail:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
  border-radius: 4px;
}

/* Below 49rem each rail is a horizontal scroller, the way a streaming app does
   it. Vertical stacking is what does not survive a third game: every release
   makes the page longer and pushes the newest one further down.

   The cards are 74% of the rail, so the NEXT one is always half in frame —
   that peek is the only thing telling somebody the row scrolls, and a row of
   full-width cards silently reads as a list with one item.

   The negative margin against equal padding is what lets a card run to the
   screen edge while its content stays on the same 1rem gutter as the rest of
   the page. overflow-x on the rail is what stops that bleed becoming a
   sideways scroll on the whole document. */
@media (max-width: 49rem) {
  .rail {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 74%;
    gap: 0.85rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    margin-inline: -1rem;
    padding: 0.25rem 1rem 0.6rem;
  }
  .rail::-webkit-scrollbar { width: 0; height: 0; }
  .rail > .game-card { scroll-snap-align: start; }
}
