/* Pixel font converted from the bitmap atlas (npm run fonts). One font pixel
   is 1/10em, so keep sizes at multiples of 10px for crisp edges:
   20px = 2px pixels, 40px = 4px pixels (Pixi fontSize / 3.2). */
@font-face {
  font-family: "PixelFont";
  src: url("../assets/console/fonts/PixelFont.ttf") format("truetype");
  font-display: block;
}

/* mirrors src/constants/Palette.ts */
:root {
  --lavender: #A7A4E0;
  --purple: #514689;
  --light: #B2B4B2;
  --dark: #54585A;
  --mid: #707372;
  --white: #FCFCFC;

  /* Resurrect 64, the shared art palette (R64 in Palette.ts) */
  --r64-ink: #2E222F;
  --r64-shadow: #3E3546;
  --r64-slate: #625565;
  --r64-dusk: #966C6C;
  --r64-sand: #AB947A;
  --r64-plum-grey: #694F62;
  --r64-mauve-grey: #7F708A;
  --r64-steel: #9BABB2;
  --r64-mist: #C7DCD0;
  --r64-white: #FFFFFF;
  --r64-maroon: #6E2727;
  --r64-brick: #B33831;
  --r64-vermilion: #EA4F36;
  --r64-coral: #F57D4A;
  --r64-crimson: #AE2334;
  --r64-red: #E83B3B;
  --r64-orange: #FB6B1D;
  --r64-amber: #F79617;
  --r64-gold: #F9C22B;
  --r64-wine: #7A3045;
  --r64-rust: #9E4539;
  --r64-copper: #CD683D;
  --r64-tan: #E6904E;
  --r64-butter: #FBB954;
  --r64-mud: #4C3E24;
  --r64-olive: #676633;
  --r64-moss: #A2A947;
  --r64-lime: #D5E04B;
  --r64-lemon: #FBFF86;
  --r64-pine: #165A4C;
  --r64-forest: #239063;
  --r64-emerald: #1EBC73;
  --r64-leaf: #91DB69;
  --r64-pear: #CDDF6C;
  --r64-charcoal: #313638;
  --r64-spruce: #374E4A;
  --r64-fern: #547E64;
  --r64-sage: #92A984;
  --r64-celery: #B2BA90;
  --r64-deep-teal: #0B5E65;
  --r64-teal: #0B8A8F;
  --r64-jade: #0EAF9B;
  --r64-mint: #30E1B9;
  --r64-aqua: #8FF8E2;
  --r64-navy: #323353;
  --r64-indigo: #484A77;
  --r64-cobalt: #4D65B4;
  --r64-blue: #4D9BE6;
  --r64-sky: #8FD3FF;
  --r64-aubergine: #45293F;
  --r64-grape: #6B3E75;
  --r64-violet: #905EA9;
  --r64-lavender: #A884F3;
  --r64-lilac: #EAADED;
  --r64-mulberry: #753C54;
  --r64-berry: #A24B6F;
  --r64-rose: #CF657F;
  --r64-pink: #ED8099;
  --r64-raspberry: #831C5D;
  --r64-cerise: #C32454;
  --r64-hot-pink: #F04F78;
  --r64-salmon: #F68181;
  /* each player's colour (Palette PLAYER_COLORS): P1 blue, P2 red, P3 green, P4 purple */
  --p1: var(--r64-blue);
  --p1-light: var(--r64-sky);
  --p2: var(--r64-red);
  --p2-light: var(--r64-salmon);
  --p3: var(--r64-emerald);
  --p3-light: var(--r64-leaf);
  --p4: var(--r64-lavender);
  --p4-light: var(--r64-lilac);
  --r64-peach: #FCA790;
  --r64-blush: #FDCBB0;

  --text-xs: 10px;
  --text-sm: 20px;
  --text-md: 30px;
  --text-lg: 40px;

  /* glyphs are 9 font pixels tall (7 cap + 2 descender), so this line-height
     is exactly the glyph box - unitless so it scales with each font-size */
  --line-tight: 0.9;
  /* 1 font pixel of breathing room above and below */
  --line: 1.1;
}

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

html,
body {
  height: 100%;
}

body {
  padding: 0;
  margin: 0;
  background-color: var(--light);
  overflow: hidden;
  position: relative;
  font-family: "PixelFont", monospace;
  font-size: var(--text-sm);
  line-height: var(--line);
  color: var(--dark);
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
}

img {
  image-rendering: pixelated;
}

h1,
h2,
h3,
p {
  margin: 0;
  font: inherit;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

button,
input {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* press feel shared by the hub's text buttons */
.press:hover {
  transform: translateY(1px);
}

.press:active {
  transform: translateY(2px);
}

/* purple text button - Create Room +, < Back, < Leave */
.link-button {
  padding: 4px;
  color: var(--purple);
  line-height: var(--line-tight);
}

.link-button:disabled {
  opacity: 0.3;
  cursor: default;
  transform: none;
}

/* stand-in thumbnail for a room with no game picked yet */
.thumb-empty {
  display: grid;
  place-items: center;
  background: var(--mid);
  color: var(--light);
  font-size: var(--text-lg);
  line-height: 1;
}

/* stepped pixel corners for the console's plastic parts (the TV, the
   controller ports' strip): --corner is each step, three steps a corner */
.pixel-corners,
.tv,
.player-slots {
  --c: var(--corner, 4px);
  clip-path: polygon(
    0 calc(var(--c) * 2), var(--c) calc(var(--c) * 2), var(--c) var(--c), calc(var(--c) * 2) var(--c), calc(var(--c) * 2) 0,
    calc(100% - var(--c) * 2) 0, calc(100% - var(--c) * 2) var(--c), calc(100% - var(--c)) var(--c), calc(100% - var(--c)) calc(var(--c) * 2), 100% calc(var(--c) * 2),
    100% calc(100% - var(--c) * 2), calc(100% - var(--c)) calc(100% - var(--c) * 2), calc(100% - var(--c)) calc(100% - var(--c)), calc(100% - var(--c) * 2) calc(100% - var(--c)), calc(100% - var(--c) * 2) 100%,
    calc(var(--c) * 2) 100%, calc(var(--c) * 2) calc(100% - var(--c)), var(--c) calc(100% - var(--c)), var(--c) calc(100% - var(--c) * 2), 0 calc(100% - var(--c) * 2)
  );
}

/* 9-slice frame from panel-borderless.png (8px slices drawn at 2x) - painted
   over the padding box, so padding sets the content inset */
.panel {
  border: 0 solid transparent;
  border-image: url("../assets/console/images/panel-borderless.png") 8 fill / 16px repeat;
  image-rendering: pixelated;
}

/* keyboard Tab focus, and arrow-key/gamepad navigation (HubController adds
   .nav-focus; the mouse removes it) */
:focus-visible,
.nav-focus :focus {
  outline: 3px solid var(--purple);
  outline-offset: 2px;
}

/* where the Pixi canvas is parked when no game is running - a room's game
   moves it into the game window (App.attachCanvas) */
#viewport {
  display: none;
}

/* Preact hub UI */
#ui {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

#ui > * {
  pointer-events: auto;
}

/* === Loading (boot + game) === */

.loading {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

.loading-bar {
  width: 40vw;
  height: 60px;
  background: var(--dark);
}

.loading-bar-fill {
  height: 100%;
  background: var(--lavender);
}

/* === Title === */

/* the title is the TV switching on: dark glass with faint scanlines, and
   the picture opening out from a bright line across the middle (two black
   halves drawing back from it) */
.title {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.22) 0 2px, transparent 2px 4px),
    radial-gradient(ellipse at center, var(--dark), var(--r64-charcoal) 55%, #000 100%);
}

.title::before,
.title::after {
  content: "";
  position: absolute;
  z-index: 10;
  left: 0;
  right: 0;
  height: 50%;
  background: #000;
  pointer-events: none;
}

.title::before {
  top: 0;
  transform-origin: top;
  border-bottom: 2px solid var(--white);
  animation: crt-open 450ms 200ms steps(9) both;
}

.title::after {
  bottom: 0;
  transform-origin: bottom;
  border-top: 2px solid var(--white);
  animation: crt-open 450ms 200ms steps(9) both;
}

@keyframes crt-open {
  from {
    transform: scaleY(1);
  }

  to {
    transform: scaleY(0);
    visibility: hidden;
  }
}

/* a full-width band of the console's dark trim (as the title bar), the
   name raised on it at 12px font pixels */
.title-logo {
  position: absolute;
  top: calc(100vh / 3 - 40px);
  left: 0;
  right: 0;
  padding: 28px 0 32px;
  display: flex;
  justify-content: center;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.14) 0 4px, transparent 4px),
    linear-gradient(to top, rgba(0, 0, 0, 0.3) 0 8px, transparent 8px),
    var(--dark);
  box-shadow: 0 8px 0 rgba(0, 0, 0, 0.4);
  font-size: 120px;
  font-weight: normal;
  line-height: var(--line-tight);
  animation: logo-drop 500ms 650ms steps(6) both;
}

/* the logo band drops in once the picture's on */
@keyframes logo-drop {
  from {
    transform: translateY(-40vh);
  }

  to {
    transform: none;
  }
}

/* The console's name (shared/Logo), moulded into the plastic: a
   light-grey CONSOLE and a lavender 8, raised by a shadow one font pixel
   deep (0.1em) and lit along its top. Sized by its font-size. */
.logo {
  display: inline-flex;
  align-items: flex-start;
  line-height: var(--line-tight);
  text-shadow: 0 0.1em 0 var(--r64-ink), 0 -0.05em 0 rgba(255, 255, 255, 0.18);
}

.logo-name {
  color: var(--light);
}

.logo-number {
  margin-right: -0.1em; /* each letter ends with a font pixel of spacing: not counted for centring */
  color: var(--lavender);
}

.title-panel {
  position: absolute;
  top: calc(200vh / 3);
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
}

.title-status {
  margin-top: -9px;
  color: var(--light);
  line-height: var(--line-tight);
}

.title-buttons {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.title-button {
  position: relative;
  padding: 6px 32px;
  color: var(--white);
  font-size: var(--text-lg);
  line-height: var(--line-tight);
}

/* a pixel hand points at the button you're on */
.title-button:hover::before,
.title-button:focus-visible::before,
.nav-focus .title-button:focus::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 20px;
  height: 20px;
  background: var(--white);
  clip-path: polygon(0 4px, 10px 4px, 10px 0, 14px 0, 14px 4px, 20px 4px, 20px 16px, 16px 16px, 16px 20px, 6px 20px, 6px 16px, 10px 16px, 10px 10px, 0 10px);
  animation: hand-nudge 500ms steps(1) infinite;
}

@keyframes hand-nudge {
  50% {
    transform: translateX(3px);
  }
}

/* the email form sits higher, just under the logo, to fit */
.title-panel.has-form {
  top: calc(100vh / 3 + 200px);
}

.title-error {
  max-width: 560px;
  color: var(--r64-crimson);
  text-align: center;
  line-height: var(--line-tight);
}

.title-form {
  width: 560px;
  padding: 20px 28px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  color: var(--light);
}

.title-form .title-error,
.dialog .title-error {
  color: var(--r64-salmon);
}

.title-form-tabs {
  display: flex;
  gap: 20px;
}

.title-form .link-button,
.dialog .link-button {
  color: var(--mid);
  outline-color: var(--lavender);
}

.title-form .link-button.is-current {
  color: var(--lavender);
}

.title-field {
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-field span {
  flex: none;
  width: 120px;
}

.title-field input {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  border: none;
  outline: 2px solid var(--r64-shadow);
  background: var(--r64-ink);
  color: var(--white);
  line-height: var(--line-tight);
}

.title-field input:focus {
  outline-color: var(--lavender);
}

.title-form-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.title-check {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--lavender);
  cursor: pointer;
}

.title-form-buttons {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.title-version {
  position: absolute;
  left: 15px;
  bottom: 10px;
  color: var(--mid);
  line-height: var(--line-tight);
}

/* === Console === */

.console {
  position: absolute;
  inset: 0;
}

/* the console's front edge: darker grey trim, a highlight along its top and
   a shadow along its bottom */
.titlebar {
  position: relative;
  height: 52px;
  padding: 0 0 0 16px;
  display: flex;
  align-items: center;
  gap: 16px;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.14) 0 2px, transparent 2px),
    linear-gradient(to top, rgba(0, 0, 0, 0.3) 0 4px, transparent 4px),
    var(--dark);
  font-size: var(--text-lg);
  line-height: var(--line-tight);
  transition: transform 200ms;
}

/* the power light (TitleBar PowerLed): lit while connected */
.power {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.power-led {
  width: 12px;
  height: 6px;
  background: var(--r64-maroon);
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.3);
}

.power-led.on {
  background: var(--r64-red);
  box-shadow: 0 0 6px 2px rgba(232, 59, 59, 0.55);
}

.power-led.blinking {
  animation: led-blink 600ms steps(1) infinite;
}

@keyframes led-blink {
  50% {
    background: var(--r64-red);
  }
}

.power-label {
  font-size: var(--text-xs);
  line-height: var(--line-tight);
  color: var(--light);
}

/* the console's name in the bar, at 4px font pixels (2px low, to sit in
   the middle of the bar) */
.titlebar-logo {
  position: relative;
  top: 2px;
  flex: none;
  font-size: 40px;
}

/* a box over the whole console, e.g. a guest saving their account (console/SaveAccount) */
.dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  background: rgba(46, 34, 47, 0.6);
}

.dialog {
  width: 600px;
  padding: 24px 28px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  color: var(--light);
}

.dialog-title {
  font-size: var(--text-md);
  color: var(--white);
}

.dialog-text {
  color: var(--lavender);
}

/* Google's own button (ui/shared/GoogleButton) - its look is Google's */
.google-button {
  min-height: 40px;
  display: flex;
  justify-content: center;
}

.dialog-alt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--lavender);
}

.dialog .title-button:disabled {
  opacity: 0.5;
  cursor: default;
  transform: none;
}

/* the Friends button: friends online, and a badge for requests and invites waiting */
.titlebar .titlebar-friends {
  position: relative;
  top: -2px;
  display: flex;
  align-items: center;
  color: var(--white);
  outline-color: var(--white);
}

.titlebar .titlebar-friends.is-open {
  color: var(--lavender);
}

/* the Supporter button (a heart), between Friends and Settings: gold while you're one */
.titlebar .titlebar-supporter {
  position: relative;
  top: -2px;
  display: flex;
  align-items: center;
  color: var(--white);
  outline-color: var(--white);
}

.titlebar .titlebar-supporter.is-supporter {
  color: var(--r64-gold);
}

.titlebar .titlebar-supporter.is-open {
  color: var(--lavender);
}

/* the settings button (a cog), at the far right */
.titlebar .titlebar-settings {
  position: relative;
  top: -2px;
  display: flex;
  align-items: center;
  color: var(--white);
  outline-color: var(--white);
}

.titlebar .titlebar-settings.is-open {
  color: var(--lavender);
}

.friends-badge {
  position: absolute;
  top: -8px;
  right: -14px;
  min-width: 18px;
  padding: 0 4px;
  background: var(--r64-red);
  color: var(--white);
  font-size: var(--text-xs);
  line-height: 18px;
  text-align: center;
}

/* nothing waiting: how many friends are on, in green */
.friends-badge.is-online {
  background: var(--r64-leaf);
  color: var(--r64-ink);
}

.friends-copy {
  display: flex;
  align-items: center;
}

/* a panel down the right of the console: friends (console/Friends) or settings (console/Settings) */
.side-panel {
  position: absolute;
  top: 60px;
  right: 12px;
  bottom: 12px;
  z-index: 15;
  width: 440px;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--light);
}

.side-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.side-panel-title {
  font-size: var(--text-md);
  color: var(--white);
}

/* the panel's settings, as icons beside the x: lit while on, dim while off */
.friends-settings {
  margin: 0 12px 0 auto;
  display: flex;
  align-items: center;
  gap: 4px;
}

.friends-setting {
  display: flex;
  color: var(--lavender);
  opacity: 0.35;
}

.friends-setting.is-on {
  color: var(--white);
  opacity: 1;
}

.side-panel-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  scrollbar-width: thin;
}

.side-panel-heading {
  margin: 0 0 4px;
  font-size: var(--text-sm);
  font-weight: normal;
  color: var(--lavender);
}

.side-panel-scroll ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.friend-row {
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* on: a green dot; off: a grey one */
.friend-dot {
  flex: none;
  width: 8px;
  height: 8px;
  background: var(--mid);
}

.friend-row.is-online .friend-dot {
  background: var(--r64-leaf);
}

.friend-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.friend-name {
  color: var(--white);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.friend-where {
  color: var(--light);
  font-size: var(--text-xs);
  line-height: var(--line);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.friend-actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 4px;
}

.side-panel-head .link-button,
.friend-actions .link-button,
.friends-code .link-button,
.friends-add .link-button,
.friend-toast .link-button {
  color: var(--lavender);
}

.friends-empty {
  color: var(--light);
  line-height: var(--line);
}

.friends-add {
  display: flex;
  gap: 8px;
}

.friends-add input {
  flex: 1;
  min-width: 0;
  padding: 4px 8px;
  border: none;
  outline: none;
  background: var(--mid);
  color: var(--white);
  font: inherit;
  line-height: var(--line-tight);
}

.friends-code {
  margin: 8px 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* (pressed, it copies your friend link, like the copy icon) */
.friends-code .friends-code-value {
  padding: 0;
  color: var(--r64-gold);
}

/* a friend's invite, bottom right (with the panel shut) */
.friend-toasts {
  position: absolute;
  right: 20px;
  bottom: 32px;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.friend-toast {
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--light);
}

/* + Friend / Asked / Friend, on a room member's card */
.card-friend {
  flex: none;
  font-size: var(--text-xs);
  color: var(--light);
}

.link-button.card-friend {
  padding: 2px 4px;
  color: var(--lavender);
}

.card-friend.is-friend {
  color: var(--r64-leaf);
}

/* a friend's level, after their name in the panel */
.friend-name-line {
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.friend-level {
  flex: none;
  color: var(--lavender);
  font-size: var(--text-xs);
}

/* appearing offline: said at the top of the panel */
.friends-hidden {
  padding: 6px 8px;
  background: var(--mid);
  color: var(--white);
  line-height: var(--line);
}

/* the panel's settings, and the report dialog's choices: a checkbox or radio and its words */
.friends-toggle {
  min-height: 32px;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  line-height: var(--line-tight);
}

.friends-toggle input {
  flex: none;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--lavender);
  cursor: pointer;
}

/* a friend came on or started a game (bottom right, with invites) */
.friend-alert .friend-dot {
  background: var(--r64-leaf);
}

/* reporting a player (console/Friends ReportDialog) */
.report-reasons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}

.report-note {
  padding: 6px 8px;
  border: none;
  outline: none;
  resize: none;
  background: var(--mid);
  color: var(--white);
  font: inherit;
  line-height: var(--line);
}

/* the report flag on someone's card - faint until you point at it */
.link-button.card-report {
  flex: none;
  padding: 0 2px;
  line-height: 0;
  color: var(--lavender);
  opacity: 0.35;
}

.link-button.card-report:hover,
.link-button.card-report:focus-visible {
  opacity: 1;
  color: var(--r64-red);
}

/* the Supporter panel (console/Supporter), a side panel like the friends one */
/* its title takes two lines: the x stays where the other panels' is, by the first */
.supporter-panel .side-panel-head {
  align-items: flex-start;
}

.supporter-panel .side-panel-head > .link-button {
  margin-top: 3.5px;
}

.supporter-panel .side-panel-scroll {
  gap: 20px;
  line-height: var(--line-tight);
}

.supporter-panel .link-button {
  color: var(--lavender);
}

.supporter-hero {
  padding: 14px 16px;
  background: var(--r64-ink);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.supporter-hero-head {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--r64-salmon);
}

.supporter-hero-head .heart-icon {
  width: 28px;
  height: 28px;
}

.supporter-price {
  margin-left: auto;
  font-size: var(--text-md);
  color: var(--r64-gold);
}

.supporter-lead,
.supporter-text {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--line);
  color: var(--light);
}

.supporter-status {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.supporter-thanks {
  color: var(--r64-gold);
}

.supporter-until,
.supporter-note {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--line);
  color: var(--light);
}

.supporter-perks,
.supporter-facts {
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: var(--text-xs);
  line-height: var(--line);
}

.supporter-perks li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.supporter-perks b {
  font-weight: normal;
  color: var(--white);
}

/* each perk's mark, in a fixed column */
.supporter-perk-icon {
  flex: none;
  width: 24px;
  display: flex;
  justify-content: center;
  color: var(--r64-gold);
}

.supporter-perk-icon .heart-icon {
  color: var(--r64-salmon);
}

.supporter-facts li {
  padding-left: 14px;
  position: relative;
}

.supporter-facts li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  background: var(--lavender);
}

.supporter-preview-heading {
  margin-top: 14px;
}

/* your room card's top line, as a Supporter's looks (a room card's own classes) */
.player-card.supporter-preview {
  height: auto;
}

.supporter-preview .player-card-name {
  position: relative;
  top: 2px;
}

/* the settings panel (console/Settings), a side panel like the friends one */
.settings-panel .side-panel-scroll section {
  line-height: var(--line-tight);
}

.settings-panel .link-button {
  color: var(--lavender);
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 32px;
}

.settings-kind {
  color: var(--white);
}

.settings-hint {
  margin: 4px 0 0;
  font-size: var(--text-xs);
  line-height: var(--line);
  color: var(--light);
}

/* the music and sound effects volumes: a pixel track filled to the level, a square knob */
.settings-volume {
  display: grid;
  grid-template-columns: 1fr 52px;
  align-items: center;
  column-gap: 12px;
  row-gap: 6px;
  margin-bottom: 12px;
}

/* the first a little below the heading, like the name and account under theirs */
.settings-volume:first-of-type {
  padding-top: 5px;
}

.settings-volume-name {
  grid-column: 1 / -1;
  color: var(--white);
}

.settings-volume-value {
  text-align: right;
  color: var(--lavender);
}

.settings-volume input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 20px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

.settings-volume input[type=range]::-webkit-slider-runnable-track {
  height: 8px;
  border: 2px solid var(--r64-ink);
  background: linear-gradient(to right, var(--lavender) var(--level), var(--r64-shadow) var(--level));
}

.settings-volume input[type=range]::-moz-range-track {
  height: 4px;
  border: 2px solid var(--r64-ink);
  background: linear-gradient(to right, var(--lavender) var(--level), var(--r64-shadow) var(--level));
}

.settings-volume input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 16px;
  margin-top: -6px;
  border: 2px solid var(--r64-ink);
  border-radius: 0;
  background: var(--white);
  box-shadow: inset -2px -2px 0 var(--light);
}

.settings-volume input[type=range]::-moz-range-thumb {
  width: 8px;
  height: 12px;
  border: 2px solid var(--r64-ink);
  border-radius: 0;
  background: var(--white);
  box-shadow: inset -2px -2px 0 var(--light);
}

.settings-volume input[type=range]:focus {
  outline: none;
}

.settings-volume input[type=range]:focus-visible::-webkit-slider-thumb,
.nav-focus .settings-volume input[type=range]:focus::-webkit-slider-thumb {
  background: var(--lavender);
}

.settings-volume input[type=range]:focus-visible::-moz-range-thumb,
.nav-focus .settings-volume input[type=range]:focus::-moz-range-thumb {
  background: var(--lavender);
}

/* your name - press it to change it */
.settings-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-panel .settings-name {
  padding: 0;
  color: var(--white);
}

.settings-name .pencil-icon {
  opacity: 0.5;
}

.settings-name:hover .pencil-icon,
.settings-name:focus-visible .pencil-icon {
  opacity: 1;
}

.settings-name-input {
  width: 100%;
  padding: 2px 4px;
  border: none;
  border-bottom: 2px solid var(--lavender);
  outline: none;
  background: none;
  color: var(--white);
  font: inherit;
  line-height: var(--line-tight);
}

/* the staff button (a shield) in the title bar - staff only (console/Admin) */
.titlebar .titlebar-admin {
  position: relative;
  top: -2px;
  display: flex;
  align-items: center;
  color: var(--r64-gold);
  outline-color: var(--white);
}

.titlebar .titlebar-admin.is-open {
  color: var(--lavender);
}

/* the staff panel (console/Admin), a side panel like the friends one */
.admin-panel .link-button {
  color: var(--lavender);
}

.admin-panel .link-button.is-on {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.admin-tabs {
  margin: 0 12px 0 auto;
  display: flex;
  gap: 12px;
}

.admin-bar {
  display: flex;
  align-items: center;
  gap: 12px;
}

.admin-refresh {
  margin-left: auto;
}

.admin-dim {
  color: var(--light);
}

.admin-line {
  margin: 0;
  line-height: var(--line);
}

.admin-report {
  border-bottom: 2px solid var(--mid);
}

.admin-panel .link-button.admin-report-head,
.admin-panel .link-button.admin-found {
  width: 100%;
  padding: 6px 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  color: var(--white);
}

.admin-panel .link-button.admin-found {
  flex-direction: row;
  align-items: center;
}

.admin-report-body {
  padding: 0 0 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.admin-note {
  margin: 0;
  color: var(--white);
  line-height: var(--line);
  overflow-wrap: anywhere;
}

.admin-chat {
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--mid);
  line-height: var(--line);
}

.admin-chat p {
  margin: 0;
}

.admin-chat-line {
  color: var(--white);
  overflow-wrap: anywhere;
}

.admin-actions {
  gap: 12px;
}

.admin-search {
  margin-bottom: 4px;
}

.admin-panel .link-button.admin-back {
  align-self: flex-start;
  padding: 0;
}

.admin-player section {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.admin-player-name {
  margin: 0;
  font-size: var(--text-md);
  font-weight: normal;
  color: var(--white);
}

.admin-staff,
.admin-on {
  color: var(--r64-leaf);
}

.admin-bad {
  color: var(--r64-red);
}

.admin-history {
  padding: 4px 0;
  display: flex;
  flex-direction: column;
}

/* the staff panel's Analytics tab (console/AdminStats, admins only): the
   panel widens for it */
.side-panel.admin-panel.is-wide {
  width: min(900px, calc(100vw - 24px));
}

.admin-bar .link-button {
  white-space: nowrap;
}

.stats section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.stats-note {
  margin: 0;
  color: var(--light);
  line-height: var(--line);
}

.stats-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px;
}

.stats-tile {
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: rgba(0, 0, 0, 0.25);
}

.stats-tile-label,
.stats-tile-sub {
  color: var(--light);
  line-height: var(--line);
}

.stats-tile-sub {
  font-size: var(--text-xs);
}

.stats-tile-value {
  font-size: var(--text-md);
  line-height: var(--line-tight);
  color: var(--white);
}

.stats-live {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.stats-charts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 6px;
}

.stats-chart {
  position: relative;
  margin: 0;
  padding: 6px 8px;
  background: rgba(0, 0, 0, 0.25);
}

.stats-chart-title {
  color: var(--light);
}

/* the bars: one hue (the hub's lavender), thin with a 2px gap, from a
   baseline; every column is a hover target */
.stats-chart-plot {
  position: relative;
  height: 90px;
  margin-top: 18px;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  border-bottom: 2px solid var(--mid);
}

.stats-chart-max {
  position: absolute;
  top: -18px;
  left: 0;
  font-size: var(--text-xs);
  color: var(--light);
}

.stats-bar-col {
  position: relative;
  flex: 1;
  height: 100%;
  display: flex;
  align-items: flex-end;
}

.stats-bar {
  width: 100%;
  max-width: 24px;
  margin: 0 auto;
  background: var(--lavender);
}

.stats-bar.is-zero {
  height: 0;
}

.stats-bar-col:hover .stats-bar {
  background: var(--white);
}

.stats-tip {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  z-index: 2;
  padding: 2px 6px;
  white-space: nowrap;
  background: var(--r64-ink);
  color: var(--white);
  pointer-events: none;
  visibility: hidden;
}

.stats-tip.is-left {
  left: auto;
  right: 0;
}

.stats-bar-col:hover .stats-tip {
  visibility: visible;
}

.stats-chart-axis {
  margin-top: 2px;
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--light);
}

.stats-chart-empty {
  position: absolute;
  inset: 40px 0 auto;
  text-align: center;
  color: var(--light);
}

.stats-table-wrap {
  overflow-x: auto;
  scrollbar-width: thin;
}

.stats-table {
  width: 100%;
  border-collapse: collapse;
}

.stats-table th,
.stats-table td {
  padding: 3px 8px;
  text-align: right;
  white-space: nowrap;
}

.stats-table th:first-child,
.stats-table td:first-child {
  text-align: left;
}

.stats-table th {
  font-weight: normal;
  color: var(--lavender);
  border-bottom: 2px solid var(--mid);
}

.stats-table tbody tr:nth-child(even) {
  background: rgba(0, 0, 0, 0.2);
}

/* what to do to a player (console/Admin AdminActionDialog) */
.admin-kinds,
.admin-lengths {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 0 16px;
}

.dialog .title-button.admin-danger {
  background: var(--r64-red);
}

/* the staff button on someone's card, beside the report flag */
.link-button.card-admin {
  flex: none;
  padding: 0 2px;
  line-height: 0;
  color: var(--r64-gold);
  opacity: 0.5;
}

.link-button.card-admin:hover,
.link-button.card-admin:focus-visible {
  opacity: 1;
}

/* friends in a room on the list: who, in green */
.room-item.has-friends {
  box-shadow: inset 4px 0 0 var(--r64-leaf);
}

.room-item-friends {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--r64-leaf);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.room-item-friends .friend-dot {
  background: var(--r64-leaf);
}

/* a narrow window: the title bar's right side tightens up so it clears the logo */
@media (max-width: 1100px) {
  .titlebar-progress {
    gap: 16px;
  }

  .titlebar .xp-bar {
    display: none;
  }
}

/* how many friends are on a game, top right of its tile */
.game-tile {
  position: relative;
}

.game-tile-friends {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 2px 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--r64-ink);
  color: var(--r64-leaf);
  line-height: var(--line-tight);
}

.game-tile-friends .friend-dot {
  background: var(--r64-leaf);
}

/* a game's page: friends on it now, your level in it, and the friends board */
.game-friends,
.game-board {
  margin-top: 32px;
  padding-left: 4px;
  color: var(--dark);
  line-height: var(--line-tight);
}

.game-section-title {
  margin: 0 0 8px;
  font-size: var(--text-sm);
  font-weight: normal;
  color: var(--dark);
}

.game-level {
  color: var(--purple);
}

.game-friends ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.game-friend {
  min-height: 36px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.game-friend .friend-dot {
  background: var(--r64-emerald);
}

.game-friend-where {
  color: var(--mid);
}

.game-friend .link-button {
  color: var(--purple);
}

.game-board-empty {
  color: var(--mid);
}

.game-board-table {
  border-collapse: collapse;
}

.game-board-table th,
.game-board-table td {
  padding: 4px 12px;
  text-align: right;
  font-weight: normal;
}

.game-board-table th {
  color: var(--mid);
}

.game-board-table .name {
  min-width: 200px;
  text-align: left;
}

.game-board-table tr.is-you td {
  color: var(--purple);
}

/* your level, XP bar and credits, at the right of the title bar */
.titlebar-progress {
  position: absolute;
  top: 18px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: var(--text-sm);
  color: var(--white);
}

/* the level and its XP bar, kept together */
.titlebar-xp {
  display: flex;
  align-items: center;
  gap: 10px;
}

.titlebar-level {
  color: var(--lavender);
}

.titlebar-credits {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--r64-gold);
}

.titlebar-credits-value {
  position: relative;
  top: 1px;
  left: 2px;
}

/* a level's XP so far (shared with the rewards panel) */
.xp-bar {
  display: block;
  width: 120px;
  height: 8px;
  padding: 2px;
  background: var(--r64-ink);
}

.xp-bar-fill {
  display: block;
  height: 100%;
  background: var(--r64-lavender);
}

/* a credit: a little gold coin */
.coin {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid var(--r64-amber);
  background: var(--r64-gold);
  box-shadow: inset -2px -2px 0 var(--r64-butter);
}

/* room list + content, centered as one block */
.console-body {
  position: absolute;
  top: 70px;
  bottom: 20px;
  left: max(0px, calc(50% - 576px));
  width: 1152px;
  padding-top: 10px;
  display: flex;
  gap: 28px;
}

/* header row shared by both columns - tabs, Create Room +, < Back, < Leave.
   Bottom-aligned; 20px text sits on the same baseline as the 40px tabs because
   .link-button's 4px bottom padding matches the size difference in descenders */
.console-header {
  flex: none;
  height: 36px;
  margin-bottom: 10px;
  display: flex;
  align-items: flex-end;
}

.rooms {
  flex: none;
  width: 300px;
  display: flex;
  flex-direction: column;
  transition: transform 200ms, opacity 200ms;
}

/* "Rooms" on the tabs' baseline, Create Room + at the right */
.rooms-header {
  justify-content: space-between;
  padding: 0 2px 0 8px;
}

.rooms-title {
  margin: 0;
  color: var(--dark);
  font-size: var(--text-lg);
  font-weight: normal;
  line-height: var(--line-tight);
}

/* vertical padding (cancelled by the margin) keeps focus outlines unclipped */
.rooms-list {
  flex: 1;
  min-height: 0;
  margin: -6px 0;
  padding: 6px 8px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  scrollbar-width: none;
}

.rooms-list::-webkit-scrollbar {
  display: none;
}

.room-item {
  width: 100%;
  height: 72px;
  padding: 8px;
  display: flex;
  gap: 12px;
  text-align: left;
}

.room-item-thumb {
  flex: none;
  width: 56px;
  height: 56px;
}

/* no rooms: a dotted outline where one would be, like an empty player slot */
.rooms-empty {
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: 2px dotted var(--mid);
  color: var(--dark);
  line-height: var(--line-tight);
}

.rooms-empty-hint {
  color: var(--mid);
  font-size: var(--text-xs);
}

.room-item-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: var(--line-tight);
}

.room-item-name {
  color: var(--light);
  overflow-wrap: anywhere;
}

.room-item-players {
  color: var(--lavender);
}

.console-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  transition: transform 200ms, opacity 200ms;
}

/* padding (cancelled by the margin) keeps focus outlines unclipped */
.console-scroll {
  flex: 1;
  min-height: 0;
  margin: -6px;
  padding: 6px;
  overflow-y: auto;
  scrollbar-width: none;
}

.console-scroll::-webkit-scrollbar {
  display: none;
}

.tabs {
  gap: 28px; /* + each word's trailing 4px letter spacing */
  padding-left: 6px;
}

.tab {
  color: var(--dark);
  font-size: var(--text-lg);
  line-height: var(--line-tight);
  opacity: 0.3;
}

.tab.active {
  opacity: 1;
}

/* 4 across, spread to the column's edges */
.games-grid {
  margin: 0;
  padding: 0 0 8px 4px;
  display: grid;
  grid-template-columns: repeat(4, 196px);
  justify-content: space-between;
  row-gap: 28px;
  list-style: none;
}

.game-tile {
  width: 196px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  color: var(--dark);
  line-height: var(--line-tight);
  text-align: left;
  white-space: nowrap;
}

.game-tile-modes {
  color: var(--mid);
  font-size: var(--text-xs);
}

/* A game as a cartridge (console/Cartridge): a grey shell with stepped,
   angled shoulders and grooves along its top, its thumbnail the label, and
   a hard pixel shadow that a press sinks into. The shadow's on .cart, as the
   shell is clipped to its shape. */
.cart {
  --shoulder: 4px; /* each of the shoulder's three steps */
  display: block;
  flex: none;
  margin-bottom: 8px;
  filter: drop-shadow(4px 4px 0 rgba(46, 34, 47, 0.35));
}

.game-tile:hover .cart {
  filter: drop-shadow(3px 3px 0 rgba(46, 34, 47, 0.35));
}

.game-tile:active .cart {
  filter: drop-shadow(2px 2px 0 rgba(46, 34, 47, 0.35));
}

.cart-shell {
  --s: var(--shoulder);
  position: relative;
  display: block;
  padding: 18px 12px 12px;
  background: var(--mid);
  box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.18), inset -2px -2px 0 rgba(0, 0, 0, 0.25);
  clip-path: polygon(
    0 calc(var(--s) * 3), var(--s) calc(var(--s) * 3), var(--s) calc(var(--s) * 2), calc(var(--s) * 2) calc(var(--s) * 2), calc(var(--s) * 2) var(--s), calc(var(--s) * 3) var(--s), calc(var(--s) * 3) 0,
    calc(100% - var(--s) * 3) 0, calc(100% - var(--s) * 3) var(--s), calc(100% - var(--s) * 2) var(--s), calc(100% - var(--s) * 2) calc(var(--s) * 2), calc(100% - var(--s)) calc(var(--s) * 2), calc(100% - var(--s)) calc(var(--s) * 3), 100% calc(var(--s) * 3),
    100% 100%, 0 100%
  );
}

/* grooves to grip it by, across its top */
.cart-grip {
  position: absolute;
  top: 4px;
  left: 20px;
  right: 20px;
  height: 10px;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.3) 0 2px, transparent 2px 4px);
}

/* the label, framed in ink */
.cart-label {
  display: block;
  width: 172px;
  height: 140px;
  box-shadow: 0 0 0 2px var(--r64-ink);
  image-rendering: pixelated;
}

/* a game's page: twice the size */
.cart-big {
  --shoulder: 8px;
}

.cart-big .cart-shell {
  padding: 32px 20px 20px;
}

.cart-big .cart-grip {
  top: 8px;
  left: 36px;
  right: 36px;
  height: 18px;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.3) 0 3px, transparent 3px 6px);
}

.cart-big .cart-label {
  width: 344px;
  height: 280px;
}

/* a game's page: its thumbnail at 2x, then what it is and Create Room */
.game-info {
  padding-left: 4px;
  display: flex;
  align-items: flex-start;
  gap: 28px;
}

.game-info-thumb {
  display: block;
  flex: none;
  width: 344px;
  height: 280px;
  box-shadow: 4px 4px 0 var(--mid);
  image-rendering: pixelated;
}

.game-info-text {
  min-height: 332px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: var(--dark);
  line-height: var(--line-tight);
}

.game-info-name {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: normal;
}

.game-info-modes {
  margin: 8px 0 0;
  color: var(--purple);
}

.game-info-players {
  margin: 20px 0 0;
}

.game-info-rooms {
  margin: 8px 0 0;
  color: var(--mid);
}

/* the page's main action, at the bottom of the text beside the thumbnail */
.game-info-create {
  margin-top: auto;
  padding: 12px 20px;
  color: var(--white);
  font-size: var(--text-md);
  line-height: var(--line-tight);
  outline-color: var(--purple);
}

/* the game page's way to its controls, above Create Room */
.game-info-controls {
  margin-top: auto;
  margin-bottom: 12px;
  color: var(--purple);
}

.game-info-controls + .game-info-create {
  margin-top: 0;
}

/* a game's controls (console/Controls): two keyboard keys and a controller button per action */
.controls-header {
  align-items: baseline;
  gap: 24px;
}

.controls-header .link-button {
  color: var(--purple);
}

.controls-title {
  margin: 0;
  font-size: var(--text-md);
  font-weight: normal;
  color: var(--dark);
}

.controls-table {
  border-collapse: separate;
  border-spacing: 8px 6px;
  color: var(--dark);
  line-height: var(--line-tight);
}

.controls-table thead th {
  padding-bottom: 4px;
  font-size: var(--text-sm);
  font-weight: normal;
  text-align: left;
  color: var(--purple);
}

.controls-table tbody th {
  padding-right: 16px;
  font-weight: normal;
  text-align: left;
  white-space: nowrap;
}

/* changed from the game's defaults */
.controls-table tr.is-changed th {
  color: var(--purple);
}

.controls-table .link-button {
  color: var(--purple);
  font-size: var(--text-xs);
}

/* a box to press: what's bound there, or "PRESS A KEY" while it waits */
.binding-box {
  width: 150px;
  height: 36px;
  padding: 0 8px;
  border: 2px solid var(--mid);
  background: var(--r64-ink);
  color: var(--white);
  font: inherit;
  font-size: var(--text-sm);
  line-height: var(--line-tight);
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.binding-box:hover,
.binding-box:focus-visible {
  border-color: var(--lavender);
  outline: none;
}

.binding-box.is-waiting {
  border-color: var(--r64-gold);
}

.binding-wait {
  color: var(--r64-gold);
  font-size: var(--text-xs);
  animation: binding-blink 800ms steps(1) infinite;
}

@keyframes binding-blink {
  50% {
    opacity: 0.3;
  }
}

.binding-none {
  color: var(--mid);
}

/* a key: a keycap */
.binding-key {
  min-width: 22px;
  padding: 0 6px;
  background: var(--r64-mist);
  color: var(--r64-ink);
  box-shadow: inset 0 -3px 0 var(--r64-steel), 0 0 0 2px var(--r64-ink);
  text-align: center;
}

/* a gamepad's other buttons and sticks: a pill */
.binding-pill {
  padding: 0 8px;
  background: var(--r64-slate);
  color: var(--white);
  border-radius: 9px;
}

/* a face button: the diamond with it lit in its colour, and its place */
.binding-face {
  display: flex;
  align-items: center;
  gap: 8px;
}

.face-off {
  fill: var(--r64-slate);
}

.face-lit.face-0 { fill: var(--p1); } /* bottom */
.face-lit.face-1 { fill: var(--p4); } /* right */
.face-lit.face-2 { fill: var(--p2); } /* left */
.face-lit.face-3 { fill: var(--p3); } /* top */

.controls-note {
  max-width: 640px;
  margin: 12px 8px 0;
  font-size: var(--text-xs);
  line-height: var(--line);
  color: var(--dark);
}

/* server messages like "That room is full" (ui/state notice) */
.notice {
  position: absolute;
  z-index: 16; /* over the friends panel */
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  padding: 8px 16px;
  background: var(--purple);
  color: var(--white);
  line-height: var(--line-tight);
}

.room-header {
  gap: 12px;
}

.room-name {
  padding: 4px 0;
  color: var(--dark);
  line-height: var(--line-tight);
}

/* host's click-to-edit name: pencil + dotted underline on hover */
.room-name-editable {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  text-align: left;
}

.room-name-editable .pencil-icon {
  color: var(--mid);
}

.room-name-editable:hover .room-name-text,
.room-name-editable:focus-visible .room-name-text {
  text-decoration: underline dotted;
  text-underline-offset: 4px;
}

.room-name-editable:hover .pencil-icon,
.room-name-editable:focus-visible .pencil-icon {
  color: var(--purple);
}

.room-name-input {
  width: 300px;
  padding: 2px 4px;
  border: none;
  border-bottom: 2px solid var(--purple);
  outline: none;
  background: none;
  color: var(--dark);
  line-height: var(--line-tight);
}

.room-body {
  flex: 1;
  min-height: 0;
  margin-bottom: 28px;
  display: flex;
  align-items: flex-start;
  gap: 24px;
}

/* the rest of the body beside the TV: 1152 - 796 - 24 */
.room-chat {
  flex: none;
  width: 332px;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* newest line at the bottom, older lines stack upward above it */
.room-chat-output {
  flex: 1;
  min-height: 100px;
  padding: 8px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--light);
  line-height: var(--line-tight);
  scrollbar-width: none;
}

.room-chat-output::-webkit-scrollbar {
  display: none;
}

.room-chat-line {
  overflow-wrap: anywhere;
}

.room-chat-line:first-child {
  margin-top: auto;
}

.room-chat-input {
  flex: none;
  height: 44px;
  padding: 0 16px;
  display: flex;
  align-items: center;
}

.room-chat-input input {
  width: 100%;
  padding: 0;
  border: none;
  outline: none;
  background: none;
  color: var(--light);
  line-height: var(--line-tight);
}

.room-chat-input input::placeholder {
  color: var(--mid);
}

/* full height of the room body, so the player cards below the window scroll */
.room-side {
  flex: none;
  align-self: stretch;
  width: 796px;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* the game window: exactly the game screen (384x216 at 2x). On the dark panel,
   so labels and buttons use lavender instead of purple. */
.game-window {
  position: relative;
  flex: none;
  width: 768px;
  height: 432px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
  color: var(--light);
  line-height: var(--line-tight);
}

/* picking a game (room/GameWindow CartInsert): a cartridge slot in the
   middle of the screen, the game's cartridge coming down into it (the well
   clips it where it goes in) with a thunk and the slot's light coming on,
   then the screen fades out to the game's settings */
.insert {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--dark);
  pointer-events: none;
  animation: insert-out 350ms 1250ms both;
}

@keyframes insert-out {
  to {
    opacity: 0;
    visibility: hidden;
  }
}

/* the cartridge between the slot's two pieces (tools/render-console.js,
   drawn at 1x, shown at 2x): the back (its opening from y 8), the cartridge,
   then the front (from y 24 of the back) hiding the part that's gone in */
.insert-back,
.insert-front {
  position: absolute;
  left: 50%;
  width: 280px;
  margin-left: -140px;
  background: 0 0 / 100% 100% no-repeat;
  image-rendering: pixelated;
}

.insert-back {
  z-index: 0;
  top: 240px;
  height: 28px;
  background-image: url("../assets/console/images/cart-slot-back.png");
}

.insert-front {
  z-index: 2;
  top: 264px;
  height: 100px;
  background-image: url("../assets/console/images/cart-slot-front.png");
}

/* the front's light, over the one drawn off in its PNG (x 115, y 28 at 1x) */
.insert-front::after {
  content: "";
  position: absolute;
  top: 56px;
  left: 230px;
  width: 20px;
  height: 4px;
  animation: slot-light 1ms 860ms both;
}

@keyframes slot-light {
  to {
    background: var(--r64-red);
    box-shadow: 0 0 6px 2px rgba(232, 59, 59, 0.55);
  }
}

/* comes down until its bottom is 56px into the front (hidden), with a bounce */
.insert-cart {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 50%;
  margin-left: -98px;
  animation: cart-down 700ms 200ms cubic-bezier(0.55, 0, 1, 1) both;
}

.insert-cart .cart {
  margin: 0;
}

@keyframes cart-down {
  0% {
    transform: translateY(-190px);
  }

  78% {
    transform: translateY(150px);
  }

  88% {
    transform: translateY(142px);
  }

  100% {
    transform: translateY(150px);
  }
}

.insert-name {
  position: absolute;
  top: 380px;
  left: 0;
  right: 0;
  color: var(--white);
  text-align: center;
}

/* the TV the game window is the screen of (room/GameWindow): a dark bezel,
   and along the bottom the maker's name, vents and a light that's on while
   a game's playing */
.tv {
  --corner: 4px;
  flex: none;
  width: 796px;
  padding: 14px 14px 0;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.12) 0 2px, transparent 2px),
    var(--r64-charcoal);
}

.tv-chin {
  height: 28px;
  padding: 0 6px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.tv-brand {
  color: var(--mid);
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.6);
  line-height: var(--line-tight);
}

.tv-vents {
  flex: 1;
  height: 8px;
  background: repeating-linear-gradient(to right, rgba(0, 0, 0, 0.45) 0 2px, transparent 2px 6px);
}

.tv-led {
  flex: none;
  width: 10px;
  height: 4px;
  background: var(--r64-pine);
}

.tv-led.on {
  background: var(--r64-emerald);
  box-shadow: 0 0 6px 2px rgba(30, 188, 115, 0.5);
}

/* what a match paid (room/RewardsPanel), over the game window once it's back on its screen */
.rewards-backdrop {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  background: rgba(46, 34, 47, 0.6);
}

.rewards {
  min-width: 400px;
  padding: 24px 32px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--white);
}

.rewards-title {
  margin-bottom: 6px;
  font-size: var(--text-lg);
  color: var(--r64-gold);
}

.rewards-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-md);
}

.rewards-note {
  color: var(--lavender);
}

.rewards-credits {
  color: var(--r64-gold);
}

.rewards-level {
  font-size: var(--text-md);
  color: var(--r64-leaf);
}

.rewards-progress {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--light);
}

.rewards .start-button {
  margin: 6px 0 0;
}

.game-window .link-button {
  color: var(--lavender);
  outline-color: var(--lavender);
}

.game-window .room-row-label {
  color: var(--lavender);
}

.game-window-hint {
  flex: none;
  color: var(--lavender);
}

/* every game as a cartridge, three across (scrolling down to the rest).
   Padding (cancelled by the margin) keeps focus outlines unclipped. */
.game-picker {
  flex: 1;
  min-height: 0;
  margin: -6px;
  padding: 6px;
  display: grid;
  grid-template-columns: repeat(3, 196px);
  justify-content: center;
  align-content: start;
  gap: 16px 32px;
  overflow-y: auto;
  scrollbar-width: none;
}

.game-picker::-webkit-scrollbar {
  display: none;
}

.game-pick {
  display: block;
}

.game-pick:hover .cart {
  filter: drop-shadow(3px 3px 0 rgba(46, 34, 47, 0.35));
}

.game-pick:active .cart {
  filter: drop-shadow(2px 2px 0 rgba(46, 34, 47, 0.35));
}

span.game-pick {
  opacity: 0.6;
}

.game-window-top {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 12px;
}

.game-window-title {
  position: relative;
  top: 1px;
  padding: 4px 0;
  font-size: var(--text-md);
  color: var(--white);
}

/* thumbnail at 2x on the left (centred in the space under the title),
   settings with START right under them on the right */
.game-settings {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  gap: 24px;
}

/* the chosen game's cartridge, at 2x */
.game-settings-thumb {
  display: block;
  flex: none;
  margin-left: 16px;
}

.game-settings-side {
  flex: 1;
  align-self: stretch;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-end;
  gap: 16px;
}

/* a game's own preview (Food Fight's lineup) is centred in the whole area,
   with the settings and START in the bottom right corner of the same cell -
   the side only takes its own height, so it never covers the preview */
.game-settings.has-preview {
  display: grid;
}

.game-settings.has-preview > * {
  grid-area: 1 / 1;
}

.game-settings.has-preview .game-settings-side {
  align-self: end;
  justify-self: end;
}

/* Food Fight's players as a lineup of bombers: one spot per slot, each the
   bomber (or just its shadow) with < > to change your skin, and your bomb
   style below it */
.ff-lineup {
  place-self: center;
  /* centred, then 32px higher */
  position: relative;
  top: -32px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 4px;
}

.ff-spot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.ff-spot-tag {
  color: var(--mid);
}

.ff-spot.filled .ff-spot-tag {
  color: var(--lavender);
}

.ff-picker {
  display: flex;
  align-items: center;
}

.ff-arrow {
  padding: 4px;
}

/* the shadow and the bomber stacked in one 64px box */
.ff-avatar {
  position: relative;
  width: 64px;
  height: 64px;
}

.ff-avatar .pixel-art {
  position: absolute;
  inset: 0;
}

/* Legendbound: naming your signature move, over the game screen */
.rpg-name-prompt {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 20px;
  min-width: 360px;
  color: var(--light);
}

.rpg-name-prompt-title {
  color: var(--lavender);
}

.rpg-name-prompt input {
  font: inherit;
  font-size: 20px;
  padding: 4px 8px;
  text-transform: uppercase;
}

.rpg-name-prompt-hint {
  color: var(--mid);
  font-size: 10px;
}

/* Legendbound's lineup: spread out across the middle, above the run slots
   (bottom left) and Length and START (bottom right) */
.ff-lineup.rpg-lineup {
  place-self: start center;
  top: 0;
  margin-top: 40px;
  gap: 56px;
}

/* Legendbound's runs: in the window's bottom left, each with the host's X
   (delete) to its left */
.quest-slots.rpg-runs {
  position: absolute;
  left: 16px;
  bottom: 16px;
}

.rpg-run {
  display: flex;
  align-items: center;
  gap: 4px;
}

.rpg-run .quest-slot {
  flex: 1;
  min-width: 0;
}

.rpg-run-delete {
  padding: 4px 6px;
  color: var(--mid);
}

.rpg-run-delete.is-confirming {
  color: var(--r64-red);
}

/* each spot a fixed width, so a longer job name never moves the hero or its
   arrows - the name stays centred and may spill past the spot's edges */
.rpg-lineup .ff-spot {
  width: 96px;
}

.rpg-job-name,
.rpg-level {
  white-space: nowrap;
}

.rpg-lineup .ff-avatar {
  width: 48px;
  height: 48px;
}

/* Legendbound: each seat's job under its hero */
.rpg-picker {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.rpg-job-name {
  color: var(--light);
  min-height: 1em;
}

.rpg-job-name.auto {
  color: var(--mid);
}

/* Legendbound: each seat's hero's level, under its job */
.rpg-level {
  color: var(--lavender);
  min-height: 1em;
}

.ff-bomb {
  width: 48px;
  height: 48px;
}

.pixel-art {
  display: block;
  image-rendering: pixelated;
}

/* a room's game, covering the game window (canvas at exactly 2x) */
.game-screen {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  background: #000;
}

.game-screen .loading-bar {
  width: 60%;
}

/* a fullscreen game's chat (GameChat): new messages slide up at the bottom
   left and fade; open (Enter), a see-through backing and a box to type in */
.game-chat {
  position: absolute;
  left: 24px;
  bottom: 24px;
  width: min(640px, 45%);
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

.game-chat.is-open {
  background: rgba(16, 16, 20, 0.6);
  pointer-events: auto;
}

.game-chat-lines {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.game-chat-line {
  color: var(--white);
  line-height: var(--line);
  overflow-wrap: anywhere;
  text-shadow: 2px 2px 0 #000;
  padding: 2px 8px;
  background: rgba(16, 16, 20, 0.45); /* readable over bright ground */
  animation: game-chat-in 200ms ease-out, game-chat-out 800ms ease-in 5200ms forwards;
}

/* open, every line stays put on the one backing */
.game-chat.is-open .game-chat-line {
  animation: none;
  background: none;
}

.game-chat-name {
  color: var(--lavender);
}

@keyframes game-chat-in {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

@keyframes game-chat-out {
  to { opacity: 0; }
}

.game-chat-input input {
  width: 100%;
  padding: 6px 8px;
  border: none;
  outline: none;
  background: rgba(0, 0, 0, 0.5);
  color: var(--white);
  font: inherit;
  line-height: var(--line-tight);
}

.game-chat-input input::placeholder {
  color: var(--mid);
}

/* Private, Invite and End Game, at the right of the room header */
.room-header-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 16px;
}

/* Private (a padlock, shut while it's private) and Invite (a link). The
   padlock is dim while open, so it's plain at a glance which it is */
.room-icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 30px;
  padding: 4px;
  color: var(--purple);
}

button.room-icon-button[aria-pressed="false"] {
  color: var(--mid);
}

button.room-icon-button[aria-pressed="false"]:hover,
button.room-icon-button[aria-pressed="false"]:focus-visible {
  color: var(--purple);
}

/* opened from an invite link, before signing in */
.title-invite {
  position: absolute;
  top: calc(100vh / 3 + 180px);
  left: 0;
  right: 0;
  color: var(--purple);
  text-align: center;
}

.room-item-playing {
  color: var(--white);
}

/* under the settings, bottom right of the game screen; greyed out until
   every slot is filled */
/* the controller's START: a dark pill */
.start-button {
  padding: 9px 22px 7px;
  border-radius: 20px;
  background: var(--r64-charcoal);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.12), inset 0 -3px 0 rgba(0, 0, 0, 0.45), 0 2px 0 rgba(0, 0, 0, 0.35);
  color: var(--white);
  font-size: var(--text-md);
  line-height: var(--line-tight);
  outline-color: var(--lavender);
}

.start-button:not(:disabled):active {
  box-shadow: inset 0 3px 0 rgba(0, 0, 0, 0.45);
}

.start-button:disabled {
  color: var(--light);
  opacity: 0.3;
  cursor: default;
  transform: none;
}

.game-settings-list {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Shard Quest's saved quests: a button per slot, the chosen one framed */
.quest-slots {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 340px;
}

.quest-slot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 4px 8px;
  border: 2px solid transparent;
  text-align: left;
  color: var(--light);
}

.quest-slot.is-chosen {
  border-color: var(--lavender);
  background: var(--mid);
  color: var(--white);
}

.quest-slot:disabled {
  cursor: default;
  transform: none;
}

.quest-slot-name {
  color: var(--lavender);
  line-height: var(--line-tight);
}

/* "Difficulty" is longer than the other labels */
.quest-settings .room-row-label {
  width: 130px;
}

.quest-slot-line {
  line-height: var(--line);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: 100%;
}

.quest-delete {
  align-self: flex-end;
}

/* an open game's "everyone plays" line */
.game-settings-note {
  color: var(--lavender);
  line-height: var(--line);
}

.room-row {
  min-height: 26px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.room-row-label {
  flex: none;
  width: 110px;
  color: var(--purple);
}

/* fixed width between the host's < > arrows so they line up row to row */
.room-row .link-button + .room-row-value {
  min-width: 140px;
  text-align: center;
}

/* under the game window, on the light background */
.room-info {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--dark);
  line-height: var(--line-tight);
}

/* the chosen game's player slots - one per player its settings allow, empty
   for now, the same size as a player card */
.player-slots {
  --corner: 4px;
  position: relative;
  flex: none;
  padding: 24px 10px 10px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.14) 0 2px, transparent 2px),
    var(--mid);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.25);
}

/* what's printed on it: one or two ports, or the four of a multitap */
.player-slots::before {
  content: "CONTROLLERS";
  position: absolute;
  top: 8px;
  left: 12px;
  font-size: var(--text-xs);
  line-height: var(--line-tight);
  color: var(--light);
}

.player-slots.multitap::before {
  content: "MULTITAP";
}

/* a controller port: a socket with its number, lit once something's plugged in */
.port {
  flex: none;
  width: 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.port-socket {
  width: 20px;
  height: 14px;
  background:
    repeating-linear-gradient(to right, transparent 0 4px, var(--dark) 4px 6px) 3px 5px / 14px 4px no-repeat,
    var(--r64-ink);
  clip-path: polygon(0 0, 100% 0, 100% 9px, 15px 100%, 5px 100%, 0 9px);
}

/* each port lights in its player's colour */
.port.p1 { --port: var(--p1); --port-light: var(--p1-light); }
.port.p2 { --port: var(--p2); --port-light: var(--p2-light); }
.port.p3 { --port: var(--p3); --port-light: var(--p3-light); }
.port.p4 { --port: var(--p4); --port-light: var(--p4-light); }

.port.plugged .port-socket {
  background:
    repeating-linear-gradient(to right, transparent 0 4px, var(--r64-ink) 4px 6px) 3px 5px / 14px 4px no-repeat,
    var(--port, var(--lavender));
}

.port.plugged .port-number {
  color: var(--port-light, var(--white));
}

.port-number {
  color: var(--white);
  font-size: var(--text-sm);
  line-height: var(--line-tight);
}

.player-slot.filled .port {
  margin-right: 8px;
}

.player-slot {
  height: 62px;
  padding: 0 10px 0 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 2px dotted var(--white);
}

.player-slot.filled {
  padding: 0 0 0 6px;
  border: 2px solid transparent;
}

/* "Player 1" etc. in an empty slot, with "Waiting for player..." below in
   small text */
.player-slot-empty {
  margin: 0 auto 0 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.player-slot-label {
  color: var(--white);
  line-height: var(--line-tight);
}

.player-slot-waiting {
  font-size: var(--text-xs);
  line-height: var(--line-tight);
  color: var(--white);
}

/* the bot button stays on the right even when it's the only thing there */
.slot-bot-button {
  margin-left: auto;
}

.player-slot > .player-card {
  flex: 1;
}

/* host's "fill with a bot" button, right side of an empty slot */
.slot-bot-button {
  padding: 6px;
  line-height: 0;
  color: var(--purple);
}

.player-card.bot .bot-icon {
  flex: none;
  color: var(--white);
}

.player-card.bot.removable {
  cursor: pointer;
}

/* where a dragged card would land */
.player-slot.drop-over,
.player-cards.drop-over {
  outline: 2px solid var(--purple);
  outline-offset: 2px;
  background: rgba(81, 70, 137, 0.15);
}

.player-slot.drop-over {
  border-color: var(--purple);
}

/* the host drags cards between the slots and the room list */
.player-card.arrangeable {
  cursor: grab;
}

.player-card.arrangeable:active {
  cursor: grabbing;
}

/* two cards per row, each half the game window's width. Always at least a
   card tall so there's somewhere to drop a card taken out of the game. */
.player-cards {
  flex: 1;
  min-height: 62px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-content: start;
  gap: 8px;
  overflow-y: auto;
  scrollbar-width: none;
}

.player-cards::-webkit-scrollbar {
  display: none;
}

.player-card {
  min-width: 0;
  height: 62px;
  /* 2px more above than below: the text sits visually centred */
  padding: 12px 12px 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--light);
}

.player-card-top {
  display: flex;
  align-items: center;
  gap: 8px;
}

.crown-icon {
  flex: none;
  color: var(--white);
}

/* cut off with "..." so a long name never runs into the level */
.player-card-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-card.is-you .player-card-name {
  color: var(--white);
}

.player-card-level {
  flex: none;
  color: var(--light);
}

/* the host's < Easy / Normal / Hard > on a bot's card, where a player's
   level goes - the arrows' negative margin keeps the card the same height,
   and the value has a fixed width so the arrows don't jump */
.bot-level {
  flex: none;
  display: flex;
  align-items: center;
  color: var(--light);
}

.bot-level-arrow {
  margin: -4px 0;
  color: var(--lavender);
}

.bot-level-value {
  min-width: 60px;
  text-align: center;
}

.player-card-bottom {
  display: flex;
  align-items: center;
  gap: 8px;
}

.player-card-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--lavender);
}

/* which slot the card is in - P1, P2... - in its player's colour */
.player-card-slot {
  flex: none;
  color: var(--white);
}

.player-card-slot.p1 { color: var(--p1-light); }
.player-card-slot.p2 { color: var(--p2-light); }
.player-card-slot.p3 { color: var(--p3-light); }
.player-card-slot.p4 { color: var(--p4-light); }


/* achievements (console/Achievements): the home screen's ACHIEVEMENTS tab, and a game's on its page */
.achievements {
  padding: 8px 4px 16px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  color: var(--dark);
  line-height: var(--line-tight);
}

.achievement-group {
  margin-top: 0;
}

.game-info ~ .achievement-group {
  margin-top: 32px;
  padding-left: 4px;
}


.achievement-none {
  margin: 0;
  color: var(--dark);
  line-height: var(--line);
}

.achievement-tally {
  margin-left: 8px;
  color: var(--purple);
}

.achievement-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.achievement {
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--dark);
}

/* a trophy: faint until it's earned, then gold on a dark tile */
.achievement > .trophy-icon {
  flex: none;
  box-sizing: content-box;
  padding: 8px;
  background: var(--mid);
  color: var(--light);
}

.achievement.is-done > .trophy-icon {
  background: var(--r64-ink);
  color: var(--r64-gold);
}

.achievement-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.achievement-name {
  color: var(--r64-ink);
}

.achievement:not(.is-done) .achievement-name {
  color: var(--dark);
}

.achievement-what,
.achievement-rewards {
  font-size: var(--text-xs);
  line-height: var(--line);
}

.achievement-rewards {
  color: var(--purple);
}

.achievement-progress {
  flex: none;
  width: 150px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  font-size: var(--text-xs);
}

.achievement-date {
  color: var(--purple);
}

/* the titles you can wear: the one worn is lit */
.achievement-title-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.title-choice {
  padding: 4px 10px;
  border: none;
  background: var(--light);
  color: var(--dark);
  font: inherit;
  line-height: var(--line-tight);
  cursor: pointer;
}

.title-choice.is-on {
  background: var(--purple);
  color: var(--white);
}

/* just earned, bottom middle for a few seconds (above where notices show) */
.achievement-toasts {
  position: absolute;
  left: 50%;
  bottom: 84px;
  transform: translateX(-50%);
  z-index: 16;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.achievement-toast {
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--light);
}

.achievement-toast > .trophy-icon {
  flex: none;
  color: var(--r64-gold);
}

.achievement-toast-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: var(--line-tight);
}

.achievement-toast-head {
  font-size: var(--text-xs);
  color: var(--lavender);
}

.achievement-toast-name {
  color: var(--white);
}

.achievement-toast-rewards {
  font-size: var(--text-xs);
  color: var(--r64-gold);
}

.achievement-toast .link-button {
  color: var(--lavender);
}

/* a member's room card: a star badge and a gold name */
.player-card-member {
  flex: none;
  display: flex;
  color: var(--r64-gold);
}

.player-card .player-card-name.is-member {
  color: var(--r64-gold);
}

/* a game in early access (members only, for now) */
.game-tile-early,
.game-info-early {
  color: var(--purple);
  font-size: var(--text-xs);
}

.game-info-early {
  margin: 8px 0 0;
}

.game-info-create:disabled {
  opacity: 0.5;
  cursor: default;
}

/* the home screen's SHOP tab (console/Shop) */
.shop {
  padding: 8px 4px 16px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  color: var(--dark);
  line-height: var(--line-tight);
}

.shop-member {
  padding: 16px 20px;
  background: var(--r64-ink);
  color: var(--light);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.shop-member-head {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--r64-gold);
}

.shop-member .shop-name {
  font-size: var(--text-md);
  color: var(--white);
}

.shop-member .shop-price {
  margin-left: auto;
  color: var(--r64-gold);
}

.shop-text {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--line);
}

.shop-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.shop-member .link-button {
  color: var(--lavender);
}

.shop-buy {
  padding: 4px 12px;
  border: none;
  background: var(--purple);
  color: var(--white);
  font: inherit;
  line-height: var(--line-tight);
  cursor: pointer;
}

.shop-owned {
  color: var(--r64-gold);
}

.shop-item .shop-owned {
  color: var(--purple);
}

.shop-items {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.shop-item {
  display: flex;
  align-items: center;
  gap: 16px;
}

.shop-item-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.shop-item .shop-name {
  color: var(--r64-ink);
}

.shop-item .shop-price {
  color: var(--purple);
}

.shop-note {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--line);
  color: var(--dark);
}

/* in a controller port the port's number says which player - no P1 tag */
.player-slot .player-card-slot {
  display: none;
}

/* === Narrow windows === */

/* below the hub's full width: the body spans the window with a margin, the
   games wrap to fit, and a room (which needs the full width) scrolls across */
@media (max-width: 1180px) {
  .console-body {
    left: 0;
    width: 100%;
    padding: 10px 16px 0;
    overflow-x: auto;
  }

  .games-grid {
    grid-template-columns: repeat(auto-fill, 196px);
    justify-content: start;
    column-gap: 20px;
  }
}

/* a phone: one column that scrolls - the rooms, then the games */
@media (max-width: 860px) {
  .console-body {
    bottom: 0;
    flex-direction: column;
    gap: 20px;
    overflow-y: auto;
  }

  .rooms,
  .console-content {
    width: auto;
    flex: none;
  }

  .rooms-list,
  .console-scroll {
    overflow: visible;
  }

  .tabs {
    gap: 16px;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .tab {
    font-size: var(--text-md);
  }

  .games-grid {
    justify-content: center;
  }

  .game-info {
    flex-direction: column;
  }

  .game-info-text {
    min-height: 0;
  }

  .game-info-create {
    margin-top: 20px;
  }

  .cart-big {
    --shoulder: 4px;
  }

  .cart-big .cart-shell {
    padding: 18px 12px 12px;
  }

  .cart-big .cart-grip {
    top: 4px;
    left: 20px;
    right: 20px;
    height: 10px;
  }

  .cart-big .cart-label {
    width: 172px;
    height: 140px;
  }

  .title-logo {
    font-size: 80px;
  }
}

@media (max-width: 600px) {
  .title-logo {
    font-size: 60px;
  }

  .titlebar {
    gap: 10px;
    padding-left: 10px;
  }

  .titlebar-logo {
    font-size: 30px;
  }

  .power-label,
  .titlebar-level {
    display: none;
  }
}
