/* ============================================================
   Mirio Games — shared game UI system
   ------------------------------------------------------------
   One stylesheet every game page can include to get the house
   look: soft pastel surfaces, rounded cards, layered shadows,
   Fredoka/Nunito type, real touch targets and dark mode.

   Design language is lifted from the Lineup (connect-3) refresh
   so the whole catalog reads as one product.

   Usage (in each game's <head>, AFTER the game's own CSS so the
   tokens land, and BEFORE nothing in particular):

     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
     <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet">
     <link rel="stylesheet" href="/assets/css/game-ui.css">

   Everything here is namespaced `mg-` except a small,
   deliberate set of global normalizations (type, focus rings,
   tap highlight, safe-area) that are safe to apply site-wide.
   ============================================================ */

/* ---- tokens ---------------------------------------------- */
:root {
  /* surfaces */
  --mg-bg-1: oklch(0.985 0.012 90);
  --mg-bg-2: oklch(0.955 0.025 70);
  --mg-card: oklch(0.995 0.004 95);
  --mg-card-2: oklch(0.975 0.008 90);
  --mg-card-3: oklch(0.955 0.012 88);

  /* ink */
  --mg-ink: oklch(0.34 0.035 265);
  --mg-ink-soft: oklch(0.56 0.03 265);
  --mg-ink-faint: oklch(0.72 0.02 265);
  --mg-line: oklch(0.91 0.012 265);

  /* accents */
  --mg-accent: oklch(0.62 0.17 265);
  --mg-accent-deep: oklch(0.53 0.18 265);
  --mg-accent-soft: oklch(0.94 0.045 265);
  --mg-good: oklch(0.68 0.15 150);
  --mg-good-soft: oklch(0.94 0.05 150);
  --mg-warn: oklch(0.80 0.14 80);
  --mg-danger: oklch(0.64 0.18 25);
  --mg-danger-soft: oklch(0.94 0.05 28);

  /* shape */
  --mg-radius: 22px;
  --mg-radius-sm: 14px;
  --mg-radius-lg: 30px;
  --mg-shadow-sm: 0 2px 8px oklch(0.5 0.05 265 / 0.10);
  --mg-shadow-md: 0 12px 30px oklch(0.45 0.06 265 / 0.13);
  --mg-shadow-lg: 0 26px 60px oklch(0.4 0.07 265 / 0.18);

  /* type */
  --mg-font-display: 'Fredoka', ui-rounded, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mg-font-body: 'Nunito', ui-rounded, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* metrics */
  --mg-tap: 44px;          /* minimum comfortable touch target */
  --mg-gap: 10px;
  --mg-safe-t: env(safe-area-inset-top, 0px);
  --mg-safe-b: env(safe-area-inset-bottom, 0px);
  --mg-safe-l: env(safe-area-inset-left, 0px);
  --mg-safe-r: env(safe-area-inset-right, 0px);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-mg-theme="light"]) {
    --mg-bg-1: oklch(0.22 0.02 265);
    --mg-bg-2: oklch(0.17 0.025 270);
    --mg-card: oklch(0.27 0.022 265);
    --mg-card-2: oklch(0.31 0.022 265);
    --mg-card-3: oklch(0.35 0.022 265);

    --mg-ink: oklch(0.95 0.012 265);
    --mg-ink-soft: oklch(0.80 0.02 265);
    --mg-ink-faint: oklch(0.64 0.02 265);
    --mg-line: oklch(0.40 0.02 265);

    --mg-accent: oklch(0.72 0.15 265);
    --mg-accent-deep: oklch(0.64 0.16 265);
    --mg-accent-soft: oklch(0.34 0.06 265);
    --mg-good-soft: oklch(0.33 0.06 150);
    --mg-danger-soft: oklch(0.34 0.07 25);

    --mg-shadow-sm: 0 2px 8px oklch(0 0 0 / 0.35);
    --mg-shadow-md: 0 12px 30px oklch(0 0 0 / 0.45);
    --mg-shadow-lg: 0 26px 60px oklch(0 0 0 / 0.55);
  }
}

:root[data-mg-theme="dark"] {
  --mg-bg-1: oklch(0.22 0.02 265);
  --mg-bg-2: oklch(0.17 0.025 270);
  --mg-card: oklch(0.27 0.022 265);
  --mg-card-2: oklch(0.31 0.022 265);
  --mg-card-3: oklch(0.35 0.022 265);

  --mg-ink: oklch(0.95 0.012 265);
  --mg-ink-soft: oklch(0.80 0.02 265);
  --mg-ink-faint: oklch(0.64 0.02 265);
  --mg-line: oklch(0.40 0.02 265);

  --mg-accent: oklch(0.72 0.15 265);
  --mg-accent-deep: oklch(0.64 0.16 265);
  --mg-accent-soft: oklch(0.34 0.06 265);
  --mg-good-soft: oklch(0.33 0.06 150);
  --mg-danger-soft: oklch(0.34 0.07 25);

  --mg-shadow-sm: 0 2px 8px oklch(0 0 0 / 0.35);
  --mg-shadow-md: 0 12px 30px oklch(0 0 0 / 0.45);
  --mg-shadow-lg: 0 26px 60px oklch(0 0 0 / 0.55);
}

/* ---- safe global normalisation ---------------------------- */
body.mg {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Type. This is the single biggest visual upgrade: it retires
   Comic Sans / Arial / Courier across the catalog.
   Applied only when `mg-type` is on the body, so games with
   deliberate art direction (Surf Champ's pixel face, Six
   Digits' handwritten notebook) keep their own identity via
   <body data-mg-type="off">. */
body.mg-type {
  font-family: var(--mg-font-body);
}

body.mg-type h1,
body.mg-type h2,
body.mg-type h3,
body.mg-type h4,
body.mg .mg-display {
  font-family: var(--mg-font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

/* Kill the blue flash on tap without killing focus visibility. */
body.mg * {
  -webkit-tap-highlight-color: transparent;
}

/* A real, visible keyboard focus ring (many of these games had none). */
body.mg :focus-visible {
  outline: 3px solid var(--mg-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Respect notches and home indicators. */
body.mg {
  padding-left: var(--mg-safe-l);
  padding-right: var(--mg-safe-r);
}

@media (prefers-reduced-motion: reduce) {
  body.mg *,
  body.mg *::before,
  body.mg *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- app shell -------------------------------------------- */
.mg-shell {
  background:
    radial-gradient(1200px 800px at 18% -10%, var(--mg-accent-soft), transparent 60%),
    radial-gradient(1100px 760px at 88% 0%, var(--mg-good-soft), transparent 55%),
    linear-gradient(165deg, var(--mg-bg-1), var(--mg-bg-2));
  background-attachment: fixed;
  color: var(--mg-ink);
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---- top bar ---------------------------------------------- */
.mg-topbar {
  display: flex;
  align-items: center;
  gap: var(--mg-gap);
  flex-wrap: wrap;
  padding: calc(var(--mg-safe-t) + 10px) 14px 10px;
}

.mg-topbar .mg-spacer { flex: 1 1 auto; }

.mg-title {
  font-family: var(--mg-font-display);
  font-size: clamp(1.05rem, 3.4vw, 1.4rem);
  font-weight: 600;
  color: var(--mg-ink);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- buttons ---------------------------------------------- */
.mg-btn {
  --_bg: var(--mg-card);
  --_fg: var(--mg-ink);
  --_bd: var(--mg-line);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;

  min-height: var(--mg-tap);
  min-width: var(--mg-tap);
  padding: 0 16px;

  font-family: var(--mg-font-body);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1;
  color: var(--_fg);
  text-decoration: none;
  white-space: nowrap;

  background: var(--_bg);
  border: 1.5px solid var(--_bd);
  border-radius: 999px;
  box-shadow: var(--mg-shadow-sm);

  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  transition: transform 0.12s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.mg-btn:hover { box-shadow: var(--mg-shadow-md); }
.mg-btn:active { transform: translateY(1px) scale(0.985); }
.mg-btn[disabled],
.mg-btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}

.mg-btn--primary {
  --_bg: linear-gradient(170deg, var(--mg-accent), var(--mg-accent-deep));
  --_fg: #fff;
  --_bd: transparent;
}

.mg-btn--good {
  --_bg: linear-gradient(170deg, var(--mg-good), oklch(0.58 0.15 150));
  --_fg: #fff;
  --_bd: transparent;
}

.mg-btn--danger {
  --_bg: linear-gradient(170deg, var(--mg-danger), oklch(0.55 0.19 25));
  --_fg: #fff;
  --_bd: transparent;
}

.mg-btn--ghost {
  --_bg: transparent;
  --_bd: var(--mg-line);
  box-shadow: none;
}

.mg-btn--icon {
  padding: 0;
  width: var(--mg-tap);
  height: var(--mg-tap);
  border-radius: 50%;
}

/* Square, chunky control-pad button (D-pads, note keys, operators). */
.mg-btn--pad {
  min-width: 56px;
  min-height: 56px;
  border-radius: var(--mg-radius-sm);
  font-size: 1.05rem;
}

/* ---- icons ------------------------------------------------ */
.mg-icon {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  display: inline-block;
  vertical-align: -0.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mg-icon--solid { fill: currentColor; stroke: none; }
.mg-icon--lg { width: 1.5em; height: 1.5em; }

/* ---- cards & panels --------------------------------------- */
.mg-card {
  background: var(--mg-card);
  border: 1.5px solid var(--mg-line);
  border-radius: var(--mg-radius);
  box-shadow: var(--mg-shadow-md);
  padding: 18px;
  color: var(--mg-ink);
}

.mg-card--flush { padding: 0; overflow: hidden; }
.mg-card--quiet { box-shadow: var(--mg-shadow-sm); background: var(--mg-card-2); }

/* ---- score pills ------------------------------------------ */
.mg-stat {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  min-height: 38px;
  background: var(--mg-card);
  border: 1.5px solid var(--mg-line);
  border-radius: 999px;
  box-shadow: var(--mg-shadow-sm);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--mg-ink-soft);
  white-space: nowrap;
}

.mg-stat b,
.mg-stat .mg-stat-value {
  font-family: var(--mg-font-display);
  font-size: 1.05rem;
  color: var(--mg-ink);
  font-weight: 600;
}

/* ---- chips / tags ----------------------------------------- */
.mg-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--mg-accent-soft);
  color: var(--mg-accent-deep);
  border: 1px solid transparent;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* ---- modal ------------------------------------------------ */
.mg-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(16px, var(--mg-safe-t)) 16px max(16px, var(--mg-safe-b));

  background: oklch(0.2 0.03 265 / 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);

  opacity: 0;
  visibility: hidden;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}

.mg-modal.is-open { opacity: 1; visibility: visible; }

.mg-modal__card {
  width: min(100%, 460px);
  max-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;

  background: var(--mg-card);
  color: var(--mg-ink);
  border-radius: var(--mg-radius-lg);
  box-shadow: var(--mg-shadow-lg);
  padding: 24px;

  transform: translateY(14px) scale(0.97);
  transition: transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1);
}

.mg-modal.is-open .mg-modal__card { transform: none; }

.mg-modal__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.mg-modal__title {
  font-family: var(--mg-font-display);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
  flex: 1 1 auto;
}

/* ---- tables (leaderboards) --------------------------------- */
.mg-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.mg-table th,
.mg-table td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--mg-line);
}

.mg-table th {
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mg-ink-faint);
}

.mg-table tr:last-child td { border-bottom: 0; }
.mg-table td:last-child,
.mg-table th:last-child { text-align: right; font-variant-numeric: tabular-nums; }

/* ---- scroll affordance ------------------------------------ */
/* For strips that scroll sideways on phones (bowling scoreboard,
   circuit-builder inventory) so it's obvious there's more. */
.mg-scroller {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
  mask-image: linear-gradient(to right, transparent 0, #000 12px, #000 calc(100% - 12px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 12px, #000 calc(100% - 12px), transparent 100%);
}

/* ---- touch-target floor ----------------------------------- */
/* game-ui.js measures controls and tags the undersized ones.
   It needs !important because several games set a sub-44px
   min-height inside their own phone media queries, which would
   otherwise win over an inline style set before those apply. */
body.mg .mg-tap-fix {
  min-width: 44px !important;
  min-height: 44px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  touch-action: manipulation;
}

/* ---- retire decorative emoji ------------------------------ */
/* Several of the older games sprinkle free-floating emoji
   (stars, puzzle pieces, rockets, a fox "mascot") around the
   frame. They read as clip-art and fight the game itself, so
   the shell hides them rather than restyling them. Games that
   genuinely need one can opt out with data-mg-keep. */
body.mg .floating-emoji,
body.mg .floating-shapes,
body.mg .emoji-decoration,
body.mg .mascot {
  display: none !important;
}

body.mg [data-mg-keep].floating-emoji,
body.mg [data-mg-keep].mascot {
  display: revert !important;
}

/* ---- helpers ---------------------------------------------- */
.mg-visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.mg-row { display: flex; align-items: center; gap: var(--mg-gap); flex-wrap: wrap; }
.mg-stack { display: flex; flex-direction: column; gap: var(--mg-gap); }
