/*
 * Board styles shared by every game.
 *
 * A game bundle brings its own board rules, but the container, the error
 * state and the sizing behaviour belong to the platform so that twenty games
 * sit on the page the same way.
 */

/*
 * The container is the demo's .board-card now, in page-game.css: the mount
 * carries both classes and the page sheet owns how it looks. What is left
 * here is the part no page sheet draws - the error state, the end screen and
 * the reference harness.
 */

.board-error {
  color: var(--critical);
  text-align: center;
  margin: 0;
}

/* ---------- End-of-game screen ---------- */

.end-screen {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: end center;
  background: color-mix(in srgb, var(--ink) 55%, transparent);
  padding: var(--space-4);
  padding-bottom: max(var(--space-4), env(safe-area-inset-bottom));
}

/* Rises from the bottom: the controls were already down there, so the thumb
   does not have to travel. */
@media (min-width: 640px) {
  .end-screen { place-items: center; }
}

.end-screen__card {
  width: 100%;
  max-width: 26rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: var(--space-6) var(--space-5);
  box-shadow: 0 24px 60px -24px rgba(31, 26, 19, .45);
  animation: end-screen-rise var(--motion-medium) var(--ease);
}

@keyframes end-screen-rise {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

.end-screen__reward {
  display: flex;
  justify-content: center;
  gap: var(--space-6);
  margin-bottom: var(--space-4);
}

.end-screen__stat { display: flex; flex-direction: column; align-items: center; }

.end-screen__value {
  font-size: var(--text-3xl);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--streak);
}

.end-screen__stat + .end-screen__stat .end-screen__value { color: var(--accent); }

.end-screen__label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  font-weight: 600;
  margin-top: var(--space-1);
}

.end-screen__note {
  margin: var(--space-2) 0 0;
  text-align: center;
  font-size: var(--text-sm);
  color: var(--good);
}

.end-screen__gap {
  margin: var(--space-4) 0 var(--space-5);
  text-align: center;
  font-weight: 650;
}

.end-screen__actions { display: flex; flex-direction: column; gap: var(--space-3); }

.end-screen__quiet { margin-top: var(--space-4); text-align: center; }

.end-screen__link {
  background: none;
  border: 0;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-decoration: underline;
  cursor: pointer;
  padding: var(--space-2);
}

/* ---------- Reference module ---------- */

/* Styles for the contract conformance harness in /games/_reference.
   Not a launch game; these go when the real games land. */

.ref-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
}

.ref-cell {
  /* Never below the minimum tap target, Sudoku cells included. */
  min-height: var(--tap-min);
  min-width: var(--tap-min);
  aspect-ratio: 1;
  font: inherit;
  font-size: var(--text-lg);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease);
}

.ref-cell:hover:not(:disabled) { background: var(--surface-hover); }

/* State carried by fill and by the disabled attribute, never by colour alone. */
.ref-cell[data-done="1"] {
  background: var(--good-soft);
  color: var(--good);
  border-color: var(--good);
  cursor: default;
}

.ref-status {
  margin: 0;
  text-align: center;
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

/* ---------- Archive ---------- */

.archive-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
}

.archive-list a {
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  color: var(--text-secondary);
}

.archive-list a:hover { background: var(--surface-hover); color: var(--text-primary); }


/* ---------- Before the module arrives ---------- */

/*
 * A board-shaped grey grid, shown by the server and wiped by the module.
 *
 * Every game module clears its mount in init(), so this needs no removal
 * code and cannot be left behind by a module that throws. It is a grid
 * rather than a spinner because the point is that the page does not jump:
 * something board-shaped is there from the first paint.
 */
.board-skeleton {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
  max-width: 24rem;
  margin: 0 auto;
}

.board-skeleton span {
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  animation: board-skeleton-pulse 1.4s ease-in-out infinite;
}

/* Staggered, so it reads as loading rather than as a broken grid. */
.board-skeleton span:nth-child(3n) { animation-delay: 0.2s; }
.board-skeleton span:nth-child(3n + 1) { animation-delay: 0.4s; }

@keyframes board-skeleton-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Somebody who has asked not to see motion is told in words instead. */
@media (prefers-reduced-motion: reduce) {
  .board-skeleton span { animation: none; }
}

.board-loading {
  margin: var(--space-4) 0 0;
  text-align: center;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* ===========================================================================
 * The end screen, in the new design.
 * ===========================================================================
 *
 * Everything below this line was unstyled until the redesign reached it,
 * which is why a finished board printed "150points / Medium 1000 / Not
 * solved part credit" as a run of plain text. The score is the moment the
 * board pays out, so it gets the room: one large number, then the sum that
 * produced it as a short ledger.
 */

.end-screen__score {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.end-screen__score-value {
  font-size: var(--text-3xl);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.end-screen__score-label {
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/*
 * How the number was reached: a label on the left, its value on the right,
 * one row each. A grid rather than a flex wrap, so the values line up in a
 * column however long the labels are - which is the whole point of showing
 * somebody the arithmetic.
 */
.end-screen__breakdown {
  margin: var(--space-4) 0 0;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 var(--space-4);
  font-size: var(--text-sm);
}

.end-screen__breakdown dt,
.end-screen__breakdown dd {
  margin: 0;
  padding: var(--space-2) 0;
  border-top: 1px solid var(--line);
}

.end-screen__breakdown dt:first-of-type,
.end-screen__breakdown dt:first-of-type + dd { border-top: 0; }

.end-screen__breakdown dt { color: var(--ink-soft); }

.end-screen__breakdown dd {
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* A board lost to the mistake limit. Said once, in the colour the rest of
   the product uses for a loss, and never shouted. */
.end-screen__note--loss {
  background: var(--bad-soft);
  color: var(--bad);
  font-weight: 650;
  padding: var(--space-3);
  border-radius: var(--radius-md);
}

/* The reminder offer, which appears under the actions on the first few
   finished boards. */
.end-screen__offer {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  display: grid;
  gap: var(--space-2);
}

.end-screen__offer--done { text-align: center; }

.end-screen__offer-text {
  font-size: var(--text-sm);
  color: var(--ink-soft);
  text-align: center;
}
