/* Matchmaking overlay — a persistent bitmap status bar (over the radar) that opens a tabbed dark
   card. Layering: game < launcher z10 < modals z200 < toast z300 (alert z400 above all).

   Renderer theming: the module script stamps <body data-renderer="classic|modern"> before any wasm
   loads. Everything below is the classic look; the modern renderer gets its own pass later — the
   hook is the (empty) [data-renderer="modern"] block at the bottom. */

/* --- Launcher (the bitmap status bar), docked bottom-right over the radar -------------------
   Logged-in players only. JS renders two bitmap lines into it (matchmaking status + party). The
   vertical offset clears the classic radar; nudge `bottom` to line up with the live HUD. */
#mm-toggle {
  position: fixed;
  right: 12px;                 /* right/bottom are set by matchmaking.js to anchor over the radar */
  bottom: 12px;
  z-index: 10;
  display: none;               /* flex for logged-in players (set by matchmaking.js) */
  flex-direction: column;
  align-items: center;
  gap: 0;
  width: auto;
  margin: 0;
  padding: 4px 8px;
  background: none;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  overflow: visible;
  outline: none;               /* no focus ring — it's chrome, never a keyboard tab stop */
}
/* Not a workaround any more — index.html's `span {}` rule is scoped to #game-settings now. This
   stays because it is load-bearing on its own: #mm-toggle is a flex container, so its span is a
   flex item and would blockify to `block` by default; `inline-flex` blockifies to `flex`, which is
   what .mm-launch inside it expects. */
#mm-toggle span { display: inline-flex; width: auto; }
#mm-toggle * { overflow: visible; }                           /* let the bitmap drop-shadows paint */
.mm-launch { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.mm-lrow { display: flex; align-items: center; }
/* background:transparent overrides the page-global `canvas { background-color: black }` rule (meant
   for the game canvas) so the color-keyed glyphs sit on the HUD, not on a black box behind each one. */
.mm-bmp { display: inline-block; vertical-align: top; image-rendering: pixelated; background: transparent;
  filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, 0.9)); }
/* The "Find match" chevrons animate in on hover (matchmaking.js drives the staggered reveal from the
   bitmap glyphs themselves); their 3-glyph space is always reserved so the label never shifts. */
/* Plain-text stand-in while the bitmap font loads / if the fetch fails. */
.mm-launch-fallback { font-family: 'Electrolize', 'Arial Black', sans-serif; color: #b5b5ff;
  text-shadow: 1px 2px 0 rgba(0, 0, 0, 0.9); font-size: 15px; letter-spacing: 0.02em; }
.mm-launch-fallback .mm-lfaint { color: #f5c542; font-size: 13px; }

/* --- Toast: the "HUD readout" ----------------------------------------------------------------
   Not a card. A notice reads as one of the ship's own instruments: the message sits directly on
   the game, bracketed by four reticle corner ticks, with no panel or border at all. A soft radial
   scrim (not a box) does the contrast work, so it stays legible over a bomb flash while never
   reading as app chrome. Notices stack — newest at the bottom, three at most — and the stack
   closes its gaps with a FLIP transform (see `toast()` in matchmaking.js).

   #mm-toast is the always-present stack host; each notice is a .mm-tslot wrapping a .mm-t. The
   slot exists so the FLIP has a node to transform that isn't the toast itself — a running CSS
   animation outranks an inline style, so a FLIP on .mm-t would be silently dropped mid-exit.

   index.html's page-global `* { overflow: hidden }` fights this (it would clip the text glow and
   the scrim) and is neutralised below. Its `span { display: flex; width: 260px }` used to fight it
   too — that is why the ticks are <i> and not <span>, same as the block meter further down — but
   that rule is scoped to #game-settings now, so the element choice is history, not a constraint. */
#mm-toast {
  position: fixed;
  top: 38px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 300;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: min(560px, 90vw);
  overflow: visible;
  pointer-events: none;
}
#mm-toast * { overflow: visible; }
.mm-tslot { width: 100%; }              /* the FLIP transforms this — never .mm-t */

.mm-t {
  --acc: #7fb0ff;                       /* info */
  --glow: rgba(127, 176, 255, 0.45);
  position: relative;
  /* Shrink to the message. The ticks are a reticle around *the notice*, so a short one ("Weasal
     invited you to a party") must not leave them stranded at the edges of the 560px column — and
     stacked notices of differing widths must not line their ticks up into a ladder. */
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
  padding: 11px 26px 12px;
  text-align: center;
  pointer-events: none;
}
.mm-t[data-lvl="notable"] { --acc: #ffd54a; --glow: rgba(255, 213, 74, 0.45); }
.mm-t[data-lvl="warn"]    { --acc: #ff7a4a; --glow: rgba(255, 122, 74, 0.45); }

/* Contrast without a container: a scrim that has no visible edge of its own. */
.mm-t::before {
  content: "";
  position: absolute;
  inset: -6px 0;
  z-index: -1;
  background: radial-gradient(58% 120% at 50% 50%, rgba(0, 0, 0, 0.7), transparent 74%);
}

.mm-tick {
  position: absolute;
  width: 11px;
  height: 11px;
  border: 1px solid var(--acc);
  opacity: 0.8;
  animation: mm-tick-in 0.22s cubic-bezier(0.2, 0.9, 0.2, 1) backwards;
}
.mm-tick.tl { top: 0; left: 0; border-right: 0; border-bottom: 0; --tx: -7px; --ty: -7px; }
.mm-tick.tr { top: 0; right: 0; border-left: 0; border-bottom: 0; --tx: 7px; --ty: -7px; animation-delay: 0.03s; }
.mm-tick.bl { bottom: 0; left: 0; border-right: 0; border-top: 0; --tx: -7px; --ty: 7px; animation-delay: 0.06s; }
.mm-tick.br { bottom: 0; right: 0; border-left: 0; border-top: 0; --tx: 7px; --ty: 7px; animation-delay: 0.09s; }
@keyframes mm-tick-in { from { opacity: 0; transform: translate(var(--tx), var(--ty)); } }

/* The entry animation touches ONLY composited properties (opacity / filter / transform). An
   earlier pass tweened `letter-spacing` for a "focusing" feel and the message re-wrapped
   mid-flight — two lines collapsing to one — then jittered over the final subpixel steps. Never
   animate a layout property here: notice text comes from the server and its length is not ours
   to control. The same rule killed a caret that pushed the last word onto a second line. */
.mm-ttext {
  font-family: 'Electrolize', 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: 15.5px;
  letter-spacing: 0.015em;
  line-height: 1.35;
  color: #f4f8fc;
  text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000, 0 0 16px var(--glow);
  animation: mm-toast-in 0.3s cubic-bezier(0.2, 0.9, 0.2, 1);
}
@keyframes mm-toast-in {
  from { opacity: 0; filter: blur(3px); transform: translateY(-2px) scale(0.99); }
  to   { opacity: 1; filter: blur(0); transform: none; }
}

.mm-t.mm-tout { animation: mm-toast-out 0.22s ease-in forwards; }
@keyframes mm-toast-out { to { opacity: 0; } }
.mm-t.mm-tout .mm-tick { animation: mm-tick-out 0.22s ease-in forwards; }
@keyframes mm-tick-out { to { opacity: 0; transform: translate(var(--tx), var(--ty)); } }

/* --- Alert (must-dismiss modal for `critical` notices) ------------------------------------- */
#mm-alert {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: none;                 /* toggled flex/none by matchmaking.js; .mm-open drives the fade */
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.62);
  backdrop-filter: blur(0px);
  opacity: 0;
  transition: opacity 0.2s ease, backdrop-filter 0.2s ease;
}
#mm-alert.mm-open { opacity: 1; backdrop-filter: blur(2px); }
.mm-alert-card {
  max-width: min(460px, 90vw);
  margin: 20px;
  padding: 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: center;
  text-align: center;
  font-family: 'Segoe UI', system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  color: #ffe9b0;
  background: linear-gradient(180deg, rgba(40, 20, 12, 0.98), rgba(22, 12, 8, 0.98));
  border: 1px solid rgba(255, 140, 90, 0.55);
  border-radius: 12px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.7);
  transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1);   /* eases in with the backdrop */
  transform: scale(0.96);
}
#mm-alert.mm-open .mm-alert-card { transform: scale(1); }
.mm-alert-text { font-size: 15px; line-height: 1.5; }

/* --- Modal backdrop (click the game background to close) ------------------------------------ */
#mm-modal {
  display: none;                 /* toggled flex/none by matchmaking.js; .mm-open drives the fade */
  position: fixed;
  inset: 0;
  z-index: 200;
  /* Top-anchored; matchmaking.js (positionModal) sets padding-top so the card is vertically centred
     on the TALLEST tab. The 8vh here is only a pre-JS fallback. Anchoring the top (rather than
     align-items:center) keeps it stable across tab switches while still reading as centred. */
  align-items: flex-start;
  justify-content: center;
  padding: 8vh 16px 16px;
  box-sizing: border-box;
  background: rgba(4, 6, 10, 0.66);
  backdrop-filter: blur(0px);
  opacity: 0;
  transition: opacity 0.2s ease, backdrop-filter 0.2s ease;
}
#mm-modal.mm-open { opacity: 1; backdrop-filter: blur(3px); }
/* the card eases in with the backdrop */
.mmx-card { transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.3, 1); transform: scale(0.96); }
#mm-modal.mm-open .mmx-card { transform: scale(1); }
/* The `#mm-modal span { display: inline; width: auto }` reset that used to live here is gone:
   index.html's `span {}` rule is scoped to #game-settings now, so it restated the browser defaults
   and did nothing. The global `* { overflow:hidden }` is still a global and still applies — it
   gives the card + viewport the clipping we want, and only the lobby list overrides it (below). */

.mmx-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 480px;
  max-width: 92vw;
  max-height: 84vh;              /* fits under the 8vh top padding + bottom gap */
  overflow: hidden;
  font-family: 'Segoe UI', system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #e8eef6;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(127, 176, 255, 0.09), transparent 60%),
    linear-gradient(180deg, #14171d, #0d0f13);
  border: 1px solid rgba(127, 176, 255, 0.18);
  border-radius: 14px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.72), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

/* Tabs + sliding indicator */
.mmx-tabs { position: relative; display: flex; border-bottom: 1px solid rgba(127, 176, 255, 0.14); flex: none; }
.mmx-tab {
  flex: 1; width: auto; margin: 0; padding: 13px 8px;
  text-align: center;
  font-family: 'Electrolize', 'Arial Black', sans-serif;
  font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: #8b95a3; background: transparent; border: none; cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease;
}
.mmx-tab:hover { color: #cfe0f5; }
.mmx-tab.on { color: #ffe07a; background: rgba(255, 200, 70, 0.05); }
.mmx-ind {
  position: absolute; bottom: -1px; left: 0; width: 0; height: 2px;
  background: #ffd54a; box-shadow: 0 0 9px rgba(255, 205, 80, 0.6);
  transition: left 0.32s cubic-bezier(0.4, 0, 0.2, 1), width 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Pending party-invite count — a glowing gold pill sitting inline just to the right of the "Party"
   label (the label + badge stay centred as a group). Hidden at 0. The #mm-modal prefix used to be
   there to outrank the span reset above; that reset is gone, and the prefix is kept only because
   the badge is meaningless outside the modal. */
#mm-modal .mmx-tab-badge {
  width: auto; box-sizing: border-box;
  min-width: 15px; height: 15px; padding: 0 4px; margin-left: 7px;
  /* "Party" is all-caps: vertical-align:middle centres on the x-height midline, which sits low
     relative to the caps — nudge up ~1px so the badge reads as centred against the CAP height. */
  vertical-align: middle; position: relative; top: -2px;
  display: none; align-items: center; justify-content: center;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: 10px; font-weight: 800; line-height: 1; letter-spacing: 0;
  color: #221a08; background: #ffd54a; border-radius: 999px;
  box-shadow: 0 0 9px rgba(255, 205, 80, 0.7);
}
#mm-modal .mmx-tab-badge.on { display: inline-flex; }

.mmx-viewport { position: relative; overflow: hidden; transition: height 0.32s cubic-bezier(0.4, 0, 0.2, 1); }
.mmx-panel { transition: opacity 0.22s ease; }
.mmx-body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 13px; }
/* Per-tab footer: Private Match's create control, or the party roster. */
.mmx-foot { padding: 11px 18px; border-top: 1px solid rgba(127, 176, 255, 0.12); flex: none; }
.mmx-footrow { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; justify-content: space-between; }
.mmx-footrow .mmx-members { flex: 1 1 auto; }

.mmx-head { font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase; color: #7fa4d9;
  border-bottom: 1px solid rgba(127, 176, 255, 0.14); padding-bottom: 5px; }
.mmx-note { color: #6b7480; font-size: 12.5px; font-style: italic; }
.mmx-meta { color: #8b95a3; font-size: 12.5px; white-space: nowrap; }
.mmx-penalty { padding: 9px 12px; font-size: 13px; color: #ffcf8a; border-radius: 8px;
  background: rgba(255, 176, 60, 0.1); border: 1px solid rgba(255, 176, 60, 0.5); }
.mmx-err { padding: 7px 10px; font-size: 13px; color: #ff9d85; border-radius: 7px;
  background: rgba(255, 120, 90, 0.08); border: 1px solid rgba(255, 120, 90, 0.35); }

/* Rows (queues, lobbies, requests, invites) */
.mmx-row { display: flex; align-items: center; gap: 11px; padding: 9px 12px;
  background: rgba(127, 176, 255, 0.045); border: 1px solid rgba(127, 176, 255, 0.1); border-radius: 9px;
  cursor: pointer; transition: border-color 0.12s, background 0.12s; }
.mmx-row:hover { border-color: rgba(127, 176, 255, 0.32); background: rgba(127, 176, 255, 0.08); }
.mmx-row.on { border-color: rgba(255, 200, 70, 0.5); background: rgba(255, 200, 70, 0.08); }
.mmx-row.gated { opacity: 0.55; cursor: default; }
.mmx-row.gated:hover { border-color: rgba(127, 176, 255, 0.1); background: rgba(127, 176, 255, 0.045); }
.mmx-check { width: 19px; height: 19px; flex: none; border-radius: 5px; border: 1.5px solid rgba(127, 176, 255, 0.45);
  display: grid; place-items: center; color: #0e1116; font-size: 13px; font-weight: 800; transition: 0.12s; }
.mmx-row.on .mmx-check { background: #ffd54a; border-color: #ffd54a; }
.mmx-label { flex: 1 1 auto; min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Queue row: name + optional description line underneath. */
.mmx-qcol { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mmx-qname { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mmx-desc { font-size: 11.5px; color: #8b95a3; line-height: 1.35; }

/* Block fullness meter: one narrow bar per capacity slot, filled from the right edge */
.mmx-blocks { display: inline-flex; gap: 3px; align-items: center; justify-content: flex-end; }
.mmx-blk { display: inline-block; width: 3px; height: 9px; border-radius: 1px; background: rgba(127, 176, 255, 0.14); }
.mmx-blk.on { background: #8fb4ec; box-shadow: 0 0 4px rgba(143, 180, 236, 0.5); }

/* Class beats the page's universal `* { overflow:hidden }`, so this list actually scrolls.
   padding-right reserves a gutter so the scrollbar never overlaps the rows; the matching negative
   margin pulls that gutter back into the body's own right padding, so the rows stay symmetric with
   the left edge instead of looking inset on the right when the list isn't tall enough to scroll. */
.mmx-scroll { display: flex; flex-direction: column; gap: 8px; max-height: 174px; overflow-y: auto; overflow-x: hidden; padding-right: 5px; margin-right: -5px; }
/* Queue rows carry a description line, so give their list more room before it starts scrolling. */
.mmx-qscroll { max-height: 320px; }
.mmx-scroll::-webkit-scrollbar { width: 8px; }
.mmx-scroll::-webkit-scrollbar-thumb { background: rgba(127, 176, 255, 0.25); border-radius: 4px; }
.mmx-scroll::-webkit-scrollbar-track { background: transparent; }

/* Buttons. One typographic treatment across every variant — Electrolize, uppercase, matching the
   tabs/heads — so casing stays consistent; variants differ only by colour/fill, never by font or
   case. No outer glow on any of them: the card and body clip on `overflow:hidden`, so a glow would
   just get sheared off at the edge. Emphasis comes from the fill, not a halo. */
.mmx-btn { width: auto; margin: 0; padding: 7px 15px;
  font-family: 'Electrolize', 'Arial Black', sans-serif; font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: #ffe07a; background: rgba(255, 200, 70, 0.08); border: 1px solid rgba(255, 200, 70, 0.5); border-radius: 7px; cursor: pointer;
  white-space: nowrap; transition: background 0.12s, color 0.12s; }
.mmx-btn:hover { background: rgba(255, 200, 70, 0.18); color: #fff6d8; }
.mmx-btn:disabled { opacity: 0.45; cursor: default; }
.mmx-btn.primary { padding: 8px 18px; background: rgba(255, 200, 70, 0.15); }
.mmx-btn.primary:hover { background: rgba(255, 200, 70, 0.24); color: #fff6d8; }
.mmx-btn.quiet { color: #aeb8c6; border-color: rgba(127, 176, 255, 0.3); background: rgba(127, 176, 255, 0.06); }
.mmx-btn.quiet:hover { color: #e8eef6; background: rgba(127, 176, 255, 0.14); }
.mmx-btn.danger { color: #ff9d85; border-color: rgba(255, 120, 90, 0.5); background: rgba(255, 120, 90, 0.08); }
.mmx-btn.danger:hover { background: rgba(255, 120, 90, 0.16); color: #ffc4b5; }
.mmx-btn.sm { padding: 4px 11px; font-size: 11.5px; }

select.mmx-select {
  width: auto; margin: 0; padding: 7px 30px 7px 11px; font-family: inherit; font-size: 13px; color: #e8eef6;
  background: #191d24 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%237fa4d9'/%3E%3C/svg%3E") no-repeat right 11px center;
  border: 1px solid rgba(127, 176, 255, 0.3); border-radius: 7px; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
select.mmx-select:focus { outline: none; border-color: rgba(255, 200, 70, 0.6); }

.mmx-input { flex: 1 1 auto; min-width: 0; width: auto; margin: 0; padding: 7px 10px; font-family: inherit; font-size: 13px;
  color: #e8eef6; background: #191d24; border: 1px solid rgba(127, 176, 255, 0.3); border-radius: 7px; }
.mmx-input:focus { outline: none; border-color: rgba(255, 200, 70, 0.7); }
.mmx-input::placeholder { color: #5c6675; }

.mmx-inline { display: flex; align-items: center; gap: 9px; }
.mmx-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* An incoming party invite: a gently glowing row so it reads as actionable. */
.mmx-invite { padding: 8px 10px; border: 1px solid rgba(255, 200, 70, 0.35); border-radius: 7px;
  background: rgba(255, 200, 70, 0.05); }
/* Accept/Decline are a matched pair: same box regardless of the primary/quiet skin. */
.mmx-invite .mmx-btn { padding: 7px 0; min-width: 78px; line-height: 16px; text-align: center; }
/* Invite-box autocomplete: a themed suggestion list under the input. It flows in the layout
   (the card grows to fit) because the tab viewport's overflow:hidden would clip an absolutely
   positioned popover. */
.mmx-inline.mmx-top { align-items: flex-start; }
.mmx-suggest-wrap { flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mmx-suggest { display: none; background: #131a26; border: 1px solid rgba(127, 176, 255, 0.4);
  border-radius: 7px; overflow: hidden; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55); }
.mmx-sitem { padding: 7px 10px; font-size: 13px; color: #cfd8e3; cursor: pointer; }
.mmx-sitem:hover, .mmx-sitem.hot { background: rgba(255, 200, 70, 0.12); color: #ffe07a; }
.mmx-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

.mmx-pill { padding: 2px 10px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; border-radius: 999px;
  border: 1px solid rgba(127, 176, 255, 0.35); color: #9fc1ef; }
.mmx-pill.hot { border-color: rgba(255, 200, 70, 0.6); color: #ffe07a; }

/* Party / lobby chips + team slots */
.mmx-members { display: flex; flex-wrap: wrap; gap: 7px; }
.mmx-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px; font-size: 13px;
  background: rgba(127, 176, 255, 0.07); border: 1px solid rgba(127, 176, 255, 0.22); border-radius: 999px; }
.mmx-chip.leader { border-color: rgba(255, 200, 70, 0.55); color: #ffe07a; background: rgba(255, 200, 70, 0.06); }
.mmx-chip.click { cursor: pointer; }
.mmx-chip.click:hover { border-color: rgba(255, 200, 70, 0.7); }
.mmx-chip.sel { border-color: rgba(255, 200, 70, 0.95); color: #ffe07a; box-shadow: 0 0 10px rgba(255, 200, 70, 0.35); }
.mmx-chip.off { opacity: 0.5; }
.mmx-chip .kick { cursor: pointer; color: #ff9d85; font-weight: 700; opacity: 0.7; }
.mmx-chip .kick:hover { opacity: 1; }

.mmx-teams { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mmx-team-name { font-size: 12px; color: #7fa4d9; text-align: center; margin-bottom: 6px; }
.mmx-slot { padding: 8px 10px; text-align: center; font-size: 13px; margin-bottom: 6px;
  border: 1px dashed rgba(127, 176, 255, 0.28); border-radius: 8px; background: rgba(127, 176, 255, 0.05); }
.mmx-slot.filled { border-style: solid; background: rgba(127, 176, 255, 0.1); }
.mmx-slot.click { cursor: pointer; }
.mmx-slot.click:hover { border-color: rgba(255, 200, 70, 0.7); }
.mmx-slot .you { color: #ffe07a; }
/* A member whose overlay socket dropped: dimmed until the service's disconnect grace evicts them. */
.mmx-slot.away { opacity: 0.55; }
.mmx-slot .kick { cursor: pointer; color: #ff9d85; font-weight: 700; opacity: 0.7; margin-left: 7px; font-style: normal; }
.mmx-slot .kick:hover { opacity: 1; }
/* The lobby invite code — the one string players read aloud, so it's selectable and set large. */
.mmx-code { font-family: 'Electrolize', 'Arial Black', sans-serif; font-size: 19px; letter-spacing: 0.22em;
  color: #ffe07a; user-select: text; -webkit-user-select: text; white-space: nowrap;
  text-shadow: 0 0 12px rgba(255, 205, 80, 0.35); }

@media (prefers-reduced-motion: reduce) {
  .mmx-viewport, .mmx-ind, .mmx-panel, .mmx-tab, #mm-modal, .mmx-card, #mm-alert, .mm-alert-card { transition: none !important; }
  .mmx-card, .mm-alert-card { transform: none; }
  /* Notices appear and leave outright; toast() skips the FLIP on its own. */
  .mm-t, .mm-ttext, .mm-tick { animation: none !important; }
  .mm-t.mm-tout { opacity: 0; }
}

/* --- Modern-renderer overrides ------------------------------------------------------------------
   The modern front-end gets its own visual pass later; adjust the launcher + card here to blend
   with it. Empty on purpose — the classic look above is the current shared default. */
body[data-renderer="modern"] #mm-toggle {}
body[data-renderer="modern"] .mmx-card {}
