/* ===========================================================================
   Arcade floor.

   The frame is deliberately monochrome — a deep plum-black modelled on arcade
   carpet — because the three games have violently different palettes (cyan
   neon, warm amber, CRT magenta) and any house colour would fight at least two
   of them. Colour enters only through `--game`, set per cabinet, so each card
   is lit by the game it holds. The carpet's confetti shards use those same
   three colours, which is what ties the floor to the machines standing on it.
   =========================================================================== */

:root {
  --floor: #14101c;
  --floor-lift: #1b1626;
  --cabinet: #0a0810;
  --bezel: #040308;
  --chrome: #efecf6;
  --dim: #9a92ae;
  --rule: rgba(239, 236, 246, 0.11);
  --rule-strong: rgba(239, 236, 246, 0.2);

  /* Overridden on every .cabinet and on game pages. Neutral so anything that
     inherits it without meaning to stays monochrome instead of guessing. */
  --game: #efecf6;

  --shell: 1180px;
  --gutter: clamp(1.15rem, 4vw, 2.75rem);

  --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --body: 'Instrument Sans', system-ui, -apple-system, sans-serif;
  --mono: 'Martian Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--body);
  font-size: clamp(0.97rem, 0.9rem + 0.3vw, 1.06rem);
  line-height: 1.65;
  color: var(--chrome);
  background-color: var(--floor);
  /* Arcade carpet: scattered confetti shards in the three games' accents, kept
     near the threshold of visibility so it reads as texture, not pattern. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='340' height='340' viewBox='0 0 340 340'%3E%3Cg fill-opacity='.038'%3E%3Crect x='24' y='40' width='27' height='7' rx='1.5' fill='%2335e6ff' transform='rotate(-27 37 43)'/%3E%3Crect x='112' y='18' width='19' height='6' rx='1.5' fill='%23ff3b7f' transform='rotate(38 121 21)'/%3E%3Crect x='214' y='52' width='30' height='7' rx='1.5' fill='%23ff9427' transform='rotate(-12 229 55)'/%3E%3Crect x='292' y='104' width='21' height='6' rx='1.5' fill='%2335e6ff' transform='rotate(54 302 107)'/%3E%3Crect x='58' y='128' width='24' height='7' rx='1.5' fill='%23ff9427' transform='rotate(19 70 131)'/%3E%3Crect x='158' y='96' width='17' height='6' rx='1.5' fill='%2335e6ff' transform='rotate(-46 166 99)'/%3E%3Crect x='246' y='158' width='26' height='7' rx='1.5' fill='%23ff3b7f' transform='rotate(-33 259 161)'/%3E%3Crect x='14' y='206' width='22' height='6' rx='1.5' fill='%23ff3b7f' transform='rotate(11 25 209)'/%3E%3Crect x='104' y='188' width='31' height='7' rx='1.5' fill='%2335e6ff' transform='rotate(-58 119 191)'/%3E%3Crect x='196' y='232' width='18' height='6' rx='1.5' fill='%23ff9427' transform='rotate(42 205 235)'/%3E%3Crect x='300' y='214' width='25' height='7' rx='1.5' fill='%23ff3b7f' transform='rotate(-19 312 217)'/%3E%3Crect x='46' y='286' width='28' height='7' rx='1.5' fill='%2335e6ff' transform='rotate(31 60 289)'/%3E%3Crect x='140' y='300' width='20' height='6' rx='1.5' fill='%23ff9427' transform='rotate(-40 150 303)'/%3E%3Crect x='236' y='294' width='23' height='6' rx='1.5' fill='%2335e6ff' transform='rotate(16 247 297)'/%3E%3Crect x='318' y='262' width='16' height='6' rx='1.5' fill='%23ff9427' transform='rotate(-52 326 265)'/%3E%3Crect x='172' y='146' width='21' height='6' rx='1.5' fill='%23ff3b7f' transform='rotate(63 182 149)'/%3E%3C/g%3E%3C/svg%3E");
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--chrome);
  outline-offset: 3px;
  border-radius: 2px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.6rem;
  z-index: 20;
  padding: 0.5rem 0.9rem;
  background: var(--chrome);
  color: var(--floor);
  font-family: var(--mono);
  font-size: 0.7rem;
}

/* --- Top rail ----------------------------------------------------------- */

.rail {
  border-bottom: 1px solid var(--rule);
  background: rgba(10, 8, 16, 0.62);
  backdrop-filter: blur(6px);
  position: sticky;
  top: 0;
  z-index: 10;
}

.rail__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 60px;
}

.wordmark {
  font-family: var(--display);
  font-variation-settings: 'wdth' 125, 'wght' 800;
  font-size: clamp(0.95rem, 0.85rem + 0.4vw, 1.18rem);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.rail__note {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

@media (max-width: 560px) {
  .rail__note {
    display: none;
  }
}

/* --- Hero --------------------------------------------------------------- */

.hero {
  padding-block: clamp(3.2rem, 9vw, 6.5rem) clamp(2.4rem, 6vw, 4rem);
}

/* Double rules above and below the statement: cabinet marquee trim, which is
   where the whole visual system starts. */
.hero__band {
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule-strong);
  position: relative;
  padding-block: clamp(1.6rem, 4vw, 2.6rem);
}
.hero__band::before,
.hero__band::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
}
.hero__band::before {
  top: 4px;
}
.hero__band::after {
  bottom: 4px;
}

.hero h1 {
  font-family: var(--display);
  font-variation-settings: 'wdth' 125, 'wght' 900;
  font-size: clamp(2.4rem, 1.1rem + 6.4vw, 5.2rem);
  line-height: 0.94;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  margin: 0;
}

.hero__lede {
  margin: 1.5rem 0 0;
  max-width: 46ch;
  color: var(--dim);
}

.hero__meta {
  margin-top: 1.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

/* --- Cabinet grid ------------------------------------------------------- */

.floor {
  padding-bottom: clamp(3.5rem, 8vw, 6rem);
}

.floor__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: clamp(1.1rem, 2.5vw, 1.75rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

.cabinet {
  background: var(--cabinet);
  border: 1px solid var(--rule);
  border-radius: 5px;
  overflow: hidden;
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1), border-color 0.28s ease,
    box-shadow 0.28s ease;
}

.cabinet__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
  color: inherit;
}
.cabinet__link:focus-visible {
  outline-offset: -3px;
}

/* The signature: an illuminated marquee in the game's own colour. Dark and
   even at rest, lit from within on hover or keyboard focus. */
.marquee {
  padding: 0.9rem 1.05rem 0.85rem;
  background: color-mix(in srgb, var(--game) 11%, var(--cabinet));
  border-bottom: 1px solid color-mix(in srgb, var(--game) 26%, transparent);
  color: color-mix(in srgb, var(--game) 72%, #ffffff);
  transition: background 0.28s ease, color 0.28s ease, box-shadow 0.28s ease,
    border-color 0.28s ease;
}

.marquee__title {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: 'wdth' 112, 'wght' 800;
  font-size: clamp(0.98rem, 0.9rem + 0.35vw, 1.16rem);
  line-height: 1.15;
  letter-spacing: 0.055em;
  text-transform: uppercase;
}

/* Reserved for two lines so every marquee in a row is the same height and the
   screens below them line up. A one-line blurb would otherwise pull its
   cabinet's screen up out of the row. */
.marquee__blurb {
  margin: 0.3rem 0 0;
  font-family: var(--body);
  font-size: 0.83rem;
  line-height: 1.45;
  min-height: calc(2 * 1.45 * 0.83rem);
  color: color-mix(in srgb, var(--game) 34%, var(--dim));
}

.cabinet:hover,
.cabinet:focus-within {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--game) 34%, transparent);
  box-shadow: 0 16px 44px -22px color-mix(in srgb, var(--game) 62%, transparent);
}

.cabinet:hover .marquee,
.cabinet:focus-within .marquee {
  background: color-mix(in srgb, var(--game) 22%, var(--cabinet));
  color: color-mix(in srgb, var(--game) 30%, #ffffff);
  border-bottom-color: color-mix(in srgb, var(--game) 48%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--game) 55%, transparent),
    0 10px 26px -18px color-mix(in srgb, var(--game) 85%, transparent);
}

/* The screen. Scanlines are era-correct for a cabinet, and they do real work
   here: they give texture to frames that are otherwise mostly flat dark. */
.screen {
  position: relative;
  background: var(--bezel);
  aspect-ratio: 16 / 10;
  overflow: hidden;
}

.screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.screen::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.22) 0 1px,
      rgba(0, 0, 0, 0) 1px 3px
    ),
    radial-gradient(120% 90% at 50% 44%, transparent 52%, rgba(4, 3, 8, 0.55) 100%);
}

.cabinet:hover .screen img,
.cabinet:focus-within .screen img {
  transform: scale(1.035);
}

/* Control panel: the strip of facts you'd read off the front of the machine. */
.panel {
  margin-top: auto;
  padding: 0.8rem 1.05rem 0.95rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}

.panel__genre {
  color: color-mix(in srgb, var(--game) 58%, var(--chrome));
}

.panel__play {
  margin-left: auto;
  color: var(--chrome);
}

/* --- Game page ---------------------------------------------------------- */

.game {
  padding-block: clamp(1.6rem, 4vw, 2.6rem) clamp(3rem, 7vw, 5rem);
}

.crumb {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  text-decoration: none;
  display: inline-block;
  margin-bottom: 1.2rem;
}
.crumb:hover {
  color: var(--chrome);
}

/* Portrait games get a narrower machine. Hyper Olympic renders a tall, narrow
   column, and at full shell width its frame becomes a 1300px tower with black
   wings either side. */
.machine {
  max-width: var(--stage-max, 100%);
  margin-inline: auto;
}

.game__marquee {
  border: 1px solid color-mix(in srgb, var(--game) 30%, transparent);
  border-radius: 5px 5px 0 0;
  border-bottom: none;
  background: color-mix(in srgb, var(--game) 14%, var(--cabinet));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--game) 45%, transparent);
  padding: 1rem 1.2rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1.2rem;
}

.game__title {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: 'wdth' 118, 'wght' 900;
  font-size: clamp(1.2rem, 0.85rem + 1.4vw, 1.8rem);
  line-height: 1.05;
  letter-spacing: 0.035em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--game) 34%, #ffffff);
}

.game__genre {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--game) 56%, var(--dim));
}

.stage {
  border: 1px solid color-mix(in srgb, var(--game) 30%, transparent);
  border-radius: 0 0 5px 5px;
  background: var(--bezel);
  padding: 10px;
}

.stage__frame {
  width: 100%;
  aspect-ratio: var(--aspect, 16 / 10);
  border: 0;
  display: block;
  background: #000;
  border-radius: 2px;
}

.stage__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.65rem 0.2rem 0.15rem;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}

.stage__btn {
  margin-left: auto;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--chrome);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  padding: 0.4rem 0.75rem;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.stage__btn:hover {
  border-color: color-mix(in srgb, var(--game) 55%, transparent);
  background: color-mix(in srgb, var(--game) 10%, transparent);
}

.game__body {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3rem);
  margin-top: clamp(2rem, 5vw, 3rem);
}

@media (max-width: 760px) {
  .game__body {
    grid-template-columns: minmax(0, 1fr);
  }
}

.game__body p {
  margin: 0 0 1rem;
  max-width: 62ch;
  color: color-mix(in srgb, var(--chrome) 82%, var(--dim));
}

.sidebar h2,
.game__body h2 {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 0.9rem;
}

.sidebar section + section {
  margin-top: 2rem;
}

.keys {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 1rem;
  font-size: 0.9rem;
}
.keys dt {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--chrome);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 0.18rem 0.45rem;
  align-self: start;
  justify-self: start;
  white-space: nowrap;
}
.keys dd {
  margin: 0;
  color: var(--dim);
  align-self: center;
}

.tags {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.tags li {
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 0.28rem 0.55rem;
}

/* --- More games / footer ------------------------------------------------ */

.more {
  padding-bottom: clamp(3rem, 7vw, 5rem);
}

.more > h2 {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 1.1rem;
}

.foot {
  border-top: 1px solid var(--rule);
  padding-block: 1.6rem 2.4rem;
}

.foot__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}
.foot a {
  color: var(--dim);
  text-decoration: none;
  border-bottom: 1px solid var(--rule-strong);
  /* An address is a literal string — uppercasing it misrepresents what to type. */
  text-transform: none;
  letter-spacing: 0.05em;
}
.foot a:hover {
  color: var(--chrome);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  .cabinet:hover,
  .cabinet:focus-within {
    transform: none;
  }
  .cabinet:hover .screen img,
  .cabinet:focus-within .screen img {
    transform: none;
  }
}

/* `hidden` must actually hide. Both `.stage__frame` and `.launch` set
   `display`, and a class selector beats the UA stylesheet's `[hidden]` rule on
   source order — leaving the hidden one still occupying its full box. On a
   phone that put an empty black panel above the launch card; on desktop it put
   the card below the game. The attribute selectors below outrank both. */
.stage__frame[hidden],
.stage__bar[hidden],
.launch[hidden] {
  display: none;
}

/* ------------------------------------------------------------ launch card */
/* Shown instead of the embedded game on phones. A 16:10 iframe on a 390px
   screen is ~240px tall — unplayable — and an embedded game cannot offer an
   install prompt, so the phone path opens the game on its own instead. */

.launch {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: 4px;
  text-decoration: none;
  color: inherit;
  min-height: 13rem;
  background: #000;
}

.launch__art {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0.45;
  /* The captures are dark and busy; blurring stops the type fighting them. */
  filter: blur(1px);
}

.launch__body {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.35rem;
  min-height: 13rem;
  padding: 1.5rem 1rem;
  text-align: center;
  background: linear-gradient(180deg, rgba(10, 8, 16, 0.35), rgba(10, 8, 16, 0.82));
}

.launch__play {
  display: grid;
  place-items: center;
  width: 3.4rem;
  height: 3.4rem;
  margin-bottom: 0.35rem;
  border-radius: 50%;
  background: var(--game, #35e6ff);
  color: #0a0810;
  font-size: 1.2rem;
  padding-left: 0.2rem;
  box-shadow: 0 0 26px color-mix(in srgb, var(--game, #35e6ff) 55%, transparent);
}

.launch__title {
  font-family: var(--display, inherit);
  font-size: 1.15rem;
  letter-spacing: 0.01em;
}

.launch__note {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}

.launch:hover .launch__play,
.launch:focus-visible .launch__play {
  transform: scale(1.06);
}

.launch__play {
  transition: transform 0.18s ease;
}
