/* THE ARCADE BAND AND ITS POP-UP
   The band sits under the Starter Pack; the pop-up sits over everything.
   Kept in its own file so a change to the games can never disturb the site. */

/* ============ the band ============ */
.arcade {
  position: relative;
  /* clears the NEUON disc hanging out of the top bar, as every .slide does */
  padding: calc(var(--nav-disc) + 1.6rem) 20px clamp(56px, 9vw, 110px);
  background:
    radial-gradient(120% 90% at 50% 0%, #0d1c33 0%, #070d18 55%, #05080f 100%);
  color: #eaf6ff;
  overflow: hidden;
}
.arcade::before {                       /* a faint scanline, like the games */
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(180deg,
    rgba(255,255,255,.03) 0 1px, transparent 1px 3px);
  pointer-events: none;
}
.arcade__wrap { position: relative; max-width: 1080px; margin: 0 auto; text-align: center; }
.arcade .kicker { color: #3fe0ff; letter-spacing: .18em; }
.arcade__h {
  margin: 8px 0 12px;
  font-size: clamp(28px, 5vw, 52px);
  line-height: 1.05;
  letter-spacing: -.02em;
}
.arcade__h em { font-style: normal; color: #3fe0ff; }
.arcade__lead {
  max-width: 62ch; margin: 0 auto clamp(24px, 4vw, 40px);
  color: rgba(234,246,255,.66);
  line-height: 1.6;
}

/* =========================================================================
   THE GAMES, AS A TURNING DECK
   The eight games used to be a grid of buttons under the starter pack's deck
   of cards, which made the bottom of the page read as two different things
   bolted together. They are cards on the same ring now — orbit.js drives any
   .orbit it finds, so this needed no new machinery, only a card to put on it.
   ========================================================================= */
/* tall enough to hold the whole ring: the cards are positioned out of the
   flow, so anything the stage does not reserve room for lands on top of
   whatever comes next — which is how the hint ended up behind a card */
.arcade__stage {
  position: relative; display: grid; place-items: center;
  min-height: clamp(26rem, 44vw, 33rem);
}
.arcade__pickhint {
  text-align: center; font-size: 0.82rem; letter-spacing: 0.03em;
  color: rgba(234, 246, 255, 0.5); margin-top: 0.2rem;
}
/* A TIGHTER RING. It was inheriting the base orbit's 440px radius, which is
   built for four big cards on a slide of their own. Eight small ones spread
   over that read as scattered rather than as a set — the outermost were most
   of a screen apart and the last one ran off the right edge. 300 brings them
   into a cluster, and a higher minimum scale stops the ones at the back
   shrinking away to nothing now that they are nearer. */
.orbit--game {
  cursor: grab;
  --orbit-rx: 300; --orbit-ry: 118; --orbit-min-scale: 0.52;
}
.orbit--game:active { cursor: grabbing; }
@media (max-width: 820px) { .orbit--game { --orbit-rx: 128; --orbit-ry: 58; --orbit-min-scale: 0.46; } }
.orbit__node--game { width: clamp(7.2rem, 11vw, 9.4rem); }

/* one game card. Portrait, like a pack, and in its own chapter's colour so a
   ring of eight reads as the eight chapters before a word is read. */
.gcard {
  position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 0.3rem; width: 100%; aspect-ratio: 2 / 3;
  padding: 0.9rem 0.7rem 0.8rem;
  cursor: pointer; text-align: center; overflow: hidden;
  border-radius: 14px;
  color: #eaf6ff;
  background:
    radial-gradient(120% 80% at 30% 10%, color-mix(in srgb, var(--g) 34%, transparent), transparent 58%),
    linear-gradient(160deg, color-mix(in srgb, var(--g) 26%, #0a1424) 0%, #0a1424 62%, #070d18 100%);
  border: 1px solid color-mix(in srgb, var(--g) 45%, transparent);
  box-shadow: 0 22px 46px -20px rgba(0, 0, 0, 0.8),
              inset 0 0 0 1px rgba(255, 255, 255, 0.06);
  transition: transform 0.28s cubic-bezier(0.2, 1.2, 0.3, 1.1),
              box-shadow 0.22s ease, border-color 0.22s ease;
}
.gcard:hover, .gcard:focus-visible {
  transform: translateY(-6px);
  border-color: var(--g);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.85), 0 0 30px -6px var(--g),
              inset 0 0 0 1px color-mix(in srgb, var(--g) 40%, transparent);
}
.gcard:focus-visible { outline: 3px solid var(--g); outline-offset: 3px; }

.gcard__neu {
  font-size: 0.58rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--g);
}
.gcard__title { font-size: 0.94rem; line-height: 1.2; letter-spacing: -0.01em; }
.gcard__teaches {
  font-style: normal; font-size: 0.62rem; line-height: 1.3;
  color: rgba(234, 246, 255, 0.55);
}
.gcard__go {
  margin-top: auto; font-size: 0.68rem; font-weight: 700; color: #05080f;
  background: var(--g); border-radius: 999px; padding: 0.22rem 0.8rem;
}

/* THE NEUON MARK, IN THE CHAPTER'S COLOUR
   Eight dots in a diamond — one, three, three, one — which is what the mark
   actually is. The first version here was four dots in a square with three
   different opacities: not the logo, just a pattern. Every dot carries the
   same weight, as on the real artwork. */
.gcard__art {
  display: grid;
  grid-template-columns: repeat(3, 0.32rem);
  grid-template-rows: repeat(4, 0.32rem);
  gap: 0.11rem;
  margin: 0.25rem 0 0.2rem;
}
.gcard__pip {
  width: 0.32rem; height: 0.32rem; border-radius: 50%;
  background: color-mix(in srgb, var(--g) 70%, #ffffff);
}
/* the diamond, in reading order: the lone top dot, the two rows of three,
   then the lone bottom dot */
.gcard__pip:nth-child(1) { grid-area: 1 / 2; }
.gcard__pip:nth-child(2) { grid-area: 2 / 1; }
.gcard__pip:nth-child(3) { grid-area: 2 / 2; }
.gcard__pip:nth-child(4) { grid-area: 2 / 3; }
.gcard__pip:nth-child(5) { grid-area: 3 / 1; }
.gcard__pip:nth-child(6) { grid-area: 3 / 2; }
.gcard__pip:nth-child(7) { grid-area: 3 / 3; }
.gcard__pip:nth-child(8) { grid-area: 4 / 2; }

/* the sheen every pack has, so a game card catches the light the same way */
.gcard__shine {
  position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(74deg, transparent 42%, rgba(255,255,255,0.16) 50%, transparent 58%);
  background-size: 260% 100%; background-repeat: no-repeat;
  background-position: 170% 0;
  animation: gcard-shine 6.5s linear infinite;
}
@keyframes gcard-shine {
  0%  { background-position: 170% 0; }
  16% { background-position: -70% 0; }
  100%{ background-position: -70% 0; }
}

/* on a chapter page, that chapter's own game is the lit one */
.orbit__node--game.is-mine .gcard {
  border-color: var(--g);
  box-shadow: 0 26px 54px -18px rgba(0, 0, 0, 0.85), 0 0 26px -4px var(--g),
              inset 0 0 0 1px color-mix(in srgb, var(--g) 50%, transparent);
}
.orbit__node--game.is-mine .gcard::after {
  content: 'YOURS';
  position: absolute; top: 0.5rem; right: -1.7rem;
  transform: rotate(38deg);
  background: var(--g); color: #05080f;
  font-size: 0.5rem; font-weight: 800; letter-spacing: 0.12em;
  padding: 0.12rem 1.7rem;
}

@media (prefers-reduced-motion: reduce) {
  .gcard, .gcard__shine { transition: none; animation: none; }
}

/* ============ the pop-up ============ */
.gmodal {
  position: fixed; inset: 0;
  z-index: 9000;
  display: grid; place-items: center;
  padding: clamp(8px, 2vw, 28px);
}
.gmodal[hidden] { display: none; }

.gmodal__scrim {
  position: absolute; inset: 0;
  background: rgba(2, 5, 12, .86);
  backdrop-filter: blur(6px);
  animation: gfade .22s ease both;
}
@keyframes gfade { from { opacity: 0 } to { opacity: 1 } }

.gmodal__box {
  position: relative;
  width: min(1100px, 100%);
  height: min(92vh, 900px);
  display: flex; flex-direction: column;
  animation: grise .26s cubic-bezier(.2,.9,.25,1) both;
}
@keyframes grise { from { opacity: 0; transform: translateY(14px) scale(.985) } to { opacity: 1; transform: none } }

.gmodal__frame {
  flex: 1;
  min-height: 0;
  border-radius: 18px;
  overflow: hidden;
  background: #04060c;
  border: 1px solid rgba(63, 224, 255, .28);
  box-shadow: 0 40px 120px -40px rgba(0,0,0,.9), 0 0 0 1px rgba(0,0,0,.6);
}
.gmodal__iframe { width: 100%; height: 100%; border: 0; display: block; }

/* The X. Big, always in the same corner, and outside the frame so the game
   can never draw over it. */
.gmodal__x {
  position: absolute;
  top: -6px; right: -6px;
  z-index: 2;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  font-size: 30px; line-height: 1;
  color: #fff;
  background: #c0293c;
  border: 2px solid #04060c;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 8px 24px -8px rgba(0,0,0,.9);
  transition: transform .15s ease, background .15s ease;
}
.gmodal__x:hover, .gmodal__x:focus-visible { background: #e8394f; transform: scale(1.08); }

.gmodal__hint {
  margin: 10px 0 0;
  text-align: center;
  font-size: 12px;
  color: rgba(234,246,255,.42);
}
.gmodal__hint kbd {
  font: inherit;
  padding: 1px 6px;
  border: 1px solid rgba(255,255,255,.2);
  border-radius: 5px;
}

/* on a phone the pop-up is the whole screen — a 90% modal wastes the only
   space the game has */
@media (max-width: 640px) {
  .gmodal { padding: 0; }
  .gmodal__box { width: 100%; height: 100%; }
  .gmodal__frame { border-radius: 0; border: 0; }
  .gmodal__x { top: max(8px, env(safe-area-inset-top)); right: 8px; }
  .gmodal__hint { display: none; }
}

/* the page must not scroll behind the pop-up */
body.gmodal-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .gmodal__scrim, .gmodal__box { animation: none; }
  .arcade__play, .arcade__tile { transition: none; }
}
