/* game.css — the name-every-demon game.
 *
 * Deliberately plain: the site's own default palette and type, no artwork of
 * its own beyond the quiet header. The one thing that matters here is that it
 * stays fast with 1,621 rows on the page, so:
 *
 *  - each block of a hundred is content-visibility:auto, which makes the
 *    browser skip layout and paint for every block not near the viewport;
 *  - the sticky bar has a solid ground, not backdrop-filter, which would be
 *    re-blurred over a long list on every scroll frame;
 *  - nothing animates except one row at a time, and only transform/opacity.
 */

.hero--game { min-height: 38svh; }

.game { position: relative; }

/* The bar ---------------------------------------------------------------- */

.gbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--field) 97%, transparent);
  border-block: var(--rule) solid var(--rule-colour);
  padding-block: var(--space-3);
}

.gbar__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-3) var(--space-5);
  align-items: center;
}

.ginput {
  width: 100%;
  min-width: 0;
  font: 600 var(--step-2) / 1.1 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  border: var(--rule) solid var(--rule-colour);
  border-radius: 3px;
  padding: 0.7rem 1rem;
}

.ginput::placeholder { color: var(--muted); font-weight: 400; }
.ginput:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ginput:disabled { opacity: 0.6; }

.gscore,
.gtime {
  margin: 0;
  font-family: var(--font-mono);
  white-space: nowrap;
}

.gscore { display: flex; align-items: baseline; gap: 0.45rem; }

.gscore__n {
  display: inline-block;
  font: 900 var(--step-4) / 1 var(--font-display);
  letter-spacing: -0.03em;
  color: var(--ink);
}

.gscore__of { font-size: var(--step--1); color: var(--muted); }
.gscore__pct { font-size: var(--step--1); color: var(--accent); }
.gtime { font-size: var(--step-1); color: var(--ink); min-width: 4.2ch; text-align: right; }

.gbar__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3);
}

.gstatus {
  margin: 0;
  min-height: 1.5em;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.08em;
  color: var(--muted);
}

.glast {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  min-width: 0;
  max-width: 100%;
  font: inherit;
  color: var(--ink);
  background: none;
  border: 0;
  padding: 0.15rem 0;
  cursor: pointer;
}

.glast[hidden] { display: none; }
.glast:hover .glast__name { text-decoration: underline; }

.glast__label,
.glast__rank {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.glast__name {
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gtools { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-left: auto; }

.gbtn {
  font: 500 var(--step--2) / 1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  background: none;
  border: var(--rule) solid var(--rule-colour);
  border-radius: 2px;
  padding: 0.6rem 0.85rem;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease);
}

.gbtn:hover,
.gbtn:focus-visible {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.gbtn[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}

.gbtn__state { color: var(--accent); margin-left: 0.25rem; }
.gbtn--primary { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }

/* The list --------------------------------------------------------------- */

.glist { margin-top: var(--space-7); }

.gblock {
  content-visibility: auto;
  /* The remembered size ("auto") takes over once a block has been drawn;
     this only steadies the scrollbar before then. */
  contain-intrinsic-block-size: auto 42rem;
  margin-bottom: var(--space-7);
}

.gblock__title {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  font-size: var(--step-2);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: var(--rule) solid var(--rule-colour);
}

.gblock__count {
  margin-left: auto;
  font: 500 var(--step--1) / 1 var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--muted);
}

.gblock.is-done .gblock__count { color: var(--accent); }

.gblock__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  column-gap: var(--space-5);
}

.slot {
  display: grid;
  grid-template-columns: 3.3rem minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-3);
  min-height: 2.15rem;
  padding: 0.3rem 0.4rem;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
}

.slot__rank {
  font: 400 var(--step--2) / 1 var(--font-mono);
  letter-spacing: 0.05em;
  color: var(--muted);
  opacity: 0.75;
}

.slot__name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
}

/* An unnamed slot is a dash, not a blank, and says nothing about the length
   of the name behind it. */
.slot__name:empty::before {
  content: "";
  display: block;
  width: 3.2rem;
  height: 2px;
  margin-top: 0.62em;
  background: color-mix(in srgb, var(--ink) 14%, transparent);
}

.slot.is-found .slot__rank { color: var(--accent); opacity: 1; }
.slot__by { font-weight: 400; font-size: 0.82em; color: var(--muted); }

.slot.is-missed { box-shadow: inset 2px 0 0 color-mix(in srgb, #e5484d 65%, transparent); }
.slot.is-missed .slot__name { color: var(--muted); font-weight: 400; }

/* Hides the blanks so the list is only what has been named. A block with
   nothing named goes with them. */
.glist.is-named-only .slot:not(.is-found) { display: none; }
.glist.is-named-only .gblock:not(:has(.is-found)) { display: none; }

/* The end ---------------------------------------------------------------- */

.gresult {
  margin-top: var(--space-6);
  padding: var(--space-5) var(--space-5) var(--space-4);
  border: var(--rule) solid color-mix(in srgb, var(--accent) 50%, transparent);
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.gresult[hidden] { display: none; }
.gresult__title { font-size: var(--step-6); margin-bottom: var(--space-3); }
.gresult__line { font-size: var(--step-1); color: var(--muted); margin-bottom: var(--space-4); }
.gresult__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.gresult__copied { font: var(--step--2) / 1 var(--font-mono); color: var(--accent); }

.gsource,
.gnote {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.7;
  color: var(--muted);
  max-width: 68ch;
  margin-block: var(--space-6);
}

/* Narrow screens --------------------------------------------------------- */

@media (max-width: 44rem) {
  .gbar__top { grid-template-columns: minmax(0, 1fr) auto; }
  .gtime { grid-column: 2; grid-row: 1; font-size: var(--step-0); }
  .gscore { grid-column: 1 / -1; grid-row: 2; }
  .gscore__n { font-size: var(--step-3); }
  .ginput { font-size: var(--step-1); padding: 0.6rem 0.8rem; }

  /* This bar is on screen the whole time, so it has to be short. The four
     buttons share one row and stretch to fill it, which also makes each a
     decent thumb target. */
  .gbar__bottom { margin-top: var(--space-2); gap: var(--space-1) var(--space-3); }
  .gstatus { min-height: 1.2em; }
  .gtools { width: 100%; margin-left: 0; gap: 0.35rem; }
  .gbtn { flex: 1 1 auto; padding: 0.6rem 0.5rem; letter-spacing: 0.08em; text-align: center; }
}

/* The sticky bar takes a lot of a short landscape phone. */
@media (max-height: 30rem) {
  .gbar { position: static; }
}

/* Modes ------------------------------------------------------------------- */

.gmodes {
  border: 0;
  margin: var(--space-5) 0 var(--space-4);
  padding: 0;
  min-width: 0;
}

.gmodes__legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font: 500 var(--step--2) / 1 var(--font-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.gmodes__row { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* The radio is real and covers the whole label, invisible, so it keeps its
   keyboard behaviour and its focus; the label draws the segment. */
.gmode {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 5.6rem;
  padding: 0.65rem 0.9rem;
  border: var(--rule) solid var(--rule-colour);
  border-radius: 2px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
}

.gmode input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

.gmode__name { font: 600 var(--step-0) / 1.1 var(--font-display); }
.gmode__best { min-height: 1em; font: 400 var(--step--2) / 1 var(--font-mono); color: var(--muted); }

.gmode:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.gmode:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}
.gmode:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Locked once the run starts: the chosen one stays lit, the rest recede. */
.gmodes.is-locked .gmode { cursor: default; }
.gmodes.is-locked .gmode:hover { background: none; }
.gmodes.is-locked .gmode:not(:has(input:checked)) { opacity: 0.4; }
.gmodes.is-locked .gmode:has(input:checked):hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

.gmodes__note {
  margin: var(--space-3) 0 0;
  max-width: 68ch;
  font: var(--step--2) / 1.7 var(--font-mono);
  color: var(--muted);
}

/* The last thirty seconds of a timed run. */
.gtime.is-low { color: color-mix(in srgb, #ff5a4d 78%, var(--ink)); }

/* Submitting a score ------------------------------------------------------ */

.gsubmit { margin: var(--space-4) 0 var(--space-5); max-width: 40rem; }
.gsubmit[hidden] { display: none; }
.gsubmit__lede { font-size: var(--step-0); margin-bottom: var(--space-3); }
.gsubmit__row { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.gsubmit__input {
  flex: 1 1 12rem;
  min-width: 0;
  font: 600 var(--step-0) / 1.1 var(--font-display);
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  border: var(--rule) solid var(--rule-colour);
  border-radius: 3px;
  padding: 0.65rem 0.85rem;
}

.gsubmit__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gsubmit__input::placeholder { color: var(--muted); font-weight: 400; }

.gsubmit__note,
.grecords__note,
.grecords__lede {
  font: var(--step--2) / 1.7 var(--font-mono);
  color: var(--muted);
  max-width: 68ch;
}

.gsubmit__note { margin: var(--space-3) 0 0; }
.gsubmit__status { min-height: 1.4em; margin: var(--space-2) 0 0; font: var(--step--1) / 1.4 var(--font-mono); color: var(--accent); }

/* The boards -------------------------------------------------------------- */

.grecords { margin-top: var(--space-6); padding-top: var(--space-5); border-top: var(--rule) solid var(--rule-colour); }
.grecords__title { font-size: var(--step-3); margin-bottom: var(--space-3); }
.grecords__lede { margin: 0 0 var(--space-4); }
.grecords__note { margin: var(--space-3) 0 0; }
.grecords__status { min-height: 1.4em; margin: var(--space-2) 0 0; font: var(--step--1) / 1.4 var(--font-mono); color: var(--muted); }

.grecords__boards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: var(--space-6) var(--space-5);
  margin-top: var(--space-4);
}

.gboard__title { font-size: var(--step-1); margin-bottom: var(--space-2); }

.gboard table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
.gboard th,
.gboard td { text-align: left; padding: 0.4rem 0.3rem; border-bottom: 1px solid color-mix(in srgb, var(--ink) 9%, transparent); }
.gboard th { font: 500 var(--step--2) / 1 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.gboard td:first-child,
.gboard th:first-child { width: 2.6rem; font-family: var(--font-mono); color: var(--muted); }
.gboard td:nth-child(2) { font-weight: 600; overflow-wrap: anywhere; }
.gboard td:nth-child(3),
.gboard th:nth-child(3) { text-align: right; font-family: var(--font-mono); }
/* Your own row. Colour alone was too faint on the default palette, where the
   accent is nearly the same grey as the text. */
.gboard tr.is-you td {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.gboard tr.is-you td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.gboard__empty { font: var(--step--1) / 1.5 var(--font-mono); color: var(--muted); margin: 0; }

@media (max-width: 44rem) {
  .gmode { min-width: 4.6rem; padding: 0.55rem 0.7rem; }
  .gsubmit__row .gbtn { flex: 1 1 100%; }
}

/* The notice before the Game opens ---------------------------------------- */

.ggate {
  width: min(34rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  overflow: auto;
  padding: var(--space-6);
  color: var(--ink);
  background: color-mix(in srgb, var(--field) 96%, var(--ink));
  border: var(--rule) solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 4px;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.55);
  animation: gate-in 0.5s var(--ease) both;
}

.ggate:focus { outline: none; }
.ggate:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The page behind is blurred, and dimmed enough that the blur reads even over
   a busy list. It fades in with the box. The blur is painted once: the page
   cannot scroll while this is open, and when it closes the cost goes with it. */
.ggate::backdrop {
  background: color-mix(in srgb, var(--field) 58%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  animation: gate-fade 0.5s ease both;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ggate::backdrop { background: color-mix(in srgb, var(--field) 93%, transparent); }
}

html:has(.ggate[open]) { overflow: hidden; }

@keyframes gate-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes gate-in {
  from { opacity: 0; transform: translateY(0.9rem) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

.ggate__title { font-size: var(--step-3); margin-bottom: var(--space-4); }
.ggate__body p { font-size: var(--step-0); line-height: 1.6; margin-bottom: var(--space-3); }
.ggate__body a { text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
.ggate__body strong { color: var(--ink); }
.ggate__body .ggate__fine { font: var(--step--2) / 1.7 var(--font-mono); color: var(--muted); }

.ggate__again {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: var(--space-4) 0 var(--space-4);
  font: var(--step--1) / 1.4 var(--font-mono);
  cursor: pointer;
}

.ggate__again input { width: 1.1rem; height: 1.1rem; accent-color: var(--accent); cursor: pointer; }

.ggate__denied {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  font: var(--step--1) / 1.6 var(--font-mono);
  color: var(--ink);
  background: color-mix(in srgb, #ff5a4d 12%, transparent);
  border-left: 3px solid color-mix(in srgb, #ff5a4d 75%, transparent);
}

.ggate__denied[hidden] { display: none; }
.ggate__denied:focus { outline: none; }
.ggate__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

@media (max-width: 44rem) {
  .ggate { padding: var(--space-5); }
  .ggate__actions .gbtn { flex: 1 1 8rem; padding: 0.85rem 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ggate,
  .ggate::backdrop { animation: none; }
}
