:root {
  /* 5496: defaults mirror bootstrap/cdn-loading-theme.json; loader.js overwrites
     them with whatever that file actually says, so the phone and the page cannot
     drift apart. */
  --mu-text: #fff3d8;
  --mu-secondary: #d4e6f3;
  --mu-accent: #eac888;
  --mu-track: #527387;
  --mu-error: #ffd0b6;
}

@font-face {
  font-family: "MU UI";
  src: url("fonts/MU-UI.ttf") format("truetype");
  font-display: swap;
}
@font-face {
  font-family: "MU Brand";
  src: url("bootstrap/Marcellus.ttf") format("truetype");
  font-display: swap;
}
@font-face {
  font-family: "MU Body";
  src: url("bootstrap/Manrope-Medium.ttf") format("truetype");
  font-display: swap;
}

:root {
  color-scheme: dark;
  font-family: "MU UI", sans-serif;
  background: #050b14;
  color: #e9f6ff;
}

* { box-sizing: border-box; }
html, body, #app { width: 100%; height: 100%; margin: 0; overflow: hidden; }
body {
  background: radial-gradient(circle at 50% 28%, #163450 0, #081321 38%, #03070d 100%);
  cursor: url("bootstrap/mu_cursor.png") 2 2, auto;
}
#app { position: relative; }
#canvas { width: 100%; height: 100%; display: block; outline: 0; background: #03070d; cursor: none; }
/* The shell and canvas are game controls in BOTH presentations. A desktop
   presentation may still receive a physical finger on a convertible/override.
   Keep browser selection/callouts off the canvas and its non-text parent, while
   leaving actual editing, diagnostic copy and browser help as ordinary text. */
#app { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
#canvas {
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; -webkit-user-drag: none;
  -webkit-tap-highlight-color: transparent;
}
input, textarea, select, [contenteditable]:not([contenteditable="false"]),
pre, [data-mu-selectable], #startup, #startupLog, #browserHelp {
  -webkit-user-select: text; user-select: text; -webkit-touch-callout: default;
}
#app button, #app [role="button"], #app summary {
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.gateway {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 20;
  width: min(700px, calc(100vw - 32px));
  height: min(480px, calc(100vh - 32px));
  transform: translate(-50%, -50%);
  border: 0;
  border-radius: 15px;
  background: transparent;
  box-shadow: 0 24px 76px rgba(0, 0, 0, .52);
  transition: width .18s ease, height .18s ease;
}
.gateway[data-screen="server"], .gateway[data-screen="sub"] { width: min(620px, calc(100vw - 24px)); height: min(236px, calc(100vh - 32px)); }
.gateway[data-screen="server"] { height: min(212px, calc(100vh - 32px)); }
.gateway[data-directory-size="many"][data-screen="server"],
.gateway[data-directory-size="many"][data-screen="sub"] { height: min(420px, calc(100vh - 32px)); }
@media (max-width: 560px) {
  .gateway[data-screen="sub"] { height: min(284px, calc(100vh - 32px)); }
}
.gateway[data-screen="auth"] { width: min(620px, calc(100vw - 24px)); height: min(490px, calc(100vh - 24px)); box-shadow: none; }
.gateway[hidden] { display: none; }
/* Reserve a real row for Fullscreen while a gateway panel is visible. The
   iframe remains scrollable internally instead of sharing the toolbar's hit area. */
#gateway:not([hidden]) {
  --gateway-toolbar-top: max(12px, env(safe-area-inset-top));
  top: calc(50% + var(--gateway-toolbar-top) / 2 + 20px);
  max-height: calc(100vh - var(--gateway-toolbar-top) - 64px);
}

.startup {
  position: absolute;
  inset: 0;
  z-index: 10;
  overflow: hidden;
  background: #071520;
  transition: opacity .35s ease, visibility .35s ease;
}
.startup.ready { opacity: 0; visibility: hidden; pointer-events: none; }
.startup-bg {
  position: absolute;
  inset: -2%;
  background: center / cover no-repeat;
  animation: startup-drift 18s ease-in-out infinite alternate;
}
.startup-veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(3, 13, 22, .76), rgba(4, 17, 28, .14) 54%, rgba(3, 13, 22, .38)),
    linear-gradient(0deg, rgba(2, 10, 17, .86), transparent 54%, rgba(4, 16, 25, .26));
}
.startup-brand {
  position: absolute;
  top: max(7vh, 36px);
  left: max(7.5vw, 42px);
  text-shadow: 0 3px 18px rgba(0, 0, 0, .65);
}
/* Title first, then the kicker, then the rule (Tony 2026-09-18; mobile matches). */
.startup-kicker { display: block; color: var(--mu-secondary); font: 500 12px/1 "MU Body", sans-serif; letter-spacing: .34em; }
.startup h1 {
  margin: 9px 0 8px;
  color: var(--mu-text);
  font: 400 clamp(38px, 5vw, 82px)/.95 "MU Brand", serif;
  letter-spacing: .065em;
  text-shadow: 0 2px 0 rgba(25, 52, 70, .75), 0 0 28px rgba(234, 200, 136, .18);
}
.startup h1 span {
  color: var(--mu-accent);
  text-shadow: 0 2px 0 rgba(45, 28, 10, .72), 0 0 26px rgba(234, 200, 136, .25);
}
.startup-rule { display: block; width: 116px; height: 1px; margin-top: 12px; background: linear-gradient(90deg, var(--mu-accent), transparent); }
.startup-status {
  position: absolute;
  left: max(7.5vw, 42px);
  right: max(7.5vw, 42px);
  bottom: max(6vh, 34px);
  color: var(--mu-text);
}
/* Loading runner (Tony 2026-10-20): the chibi stands on the bar and runs to the right as data loads,
   6 frames at 6 fps from one strip (cell = sprite height, feet at 96 %). One class per page load
   (shell.html #startupRunner); each class brings its backdrop, sprite and bar accent. */
.startup-lane { --runner-size: clamp(64px, 19vmin, 128px); position: relative; height: calc(var(--runner-size) * .96); }
.startup-runner {
  position: absolute;
  bottom: calc(var(--runner-size) * -.04);
  left: clamp(calc(var(--runner-size) / 2), calc(var(--mu-progress, 0) * 100%), calc(100% - var(--runner-size) / 2));
  width: var(--runner-size);
  height: var(--runner-size);
  transform: translateX(-50%);
  background: no-repeat 0 0 / 600% 100%;
  animation: startup-run 1s steps(6) infinite;
  transition: left .6s ease-out;
  pointer-events: none;
}
.startup[data-runner="dk"] { --mu-runner: #fb635f; }
.startup[data-runner="dw"] { --mu-runner: #70c7ff; }
.startup[data-runner="elf"] { --mu-runner: #c4daa1; }
.startup[data-runner="mg"] { --mu-runner: #a6a6ef; }
.startup[data-runner="dl"] { --mu-runner: #d6c18e; }
.startup[data-runner="sum"] { --mu-runner: #c39bfb; }
.startup[data-runner="rf"] { --mu-runner: #ff9c64; }
.startup[data-runner="dk"] .startup-bg { background-image: url("bootstrap/loading-bg-dk.webp"); }
.startup[data-runner="dw"] .startup-bg { background-image: url("bootstrap/loading-bg-dw.webp"); }
.startup[data-runner="elf"] .startup-bg { background-image: url("bootstrap/loading-bg-elf.webp"); }
.startup[data-runner="mg"] .startup-bg { background-image: url("bootstrap/loading-bg-mg.webp"); }
.startup[data-runner="dl"] .startup-bg { background-image: url("bootstrap/loading-bg-dl.webp"); }
.startup[data-runner="sum"] .startup-bg { background-image: url("bootstrap/loading-bg-sum.webp"); }
.startup[data-runner="rf"] .startup-bg { background-image: url("bootstrap/loading-bg-rf.webp"); }
.startup[data-runner="dk"] .startup-runner { background-image: url("bootstrap/loading-runner-dk.webp"); }
.startup[data-runner="dw"] .startup-runner { background-image: url("bootstrap/loading-runner-dw.webp"); }
.startup[data-runner="elf"] .startup-runner { background-image: url("bootstrap/loading-runner-elf.webp"); }
.startup[data-runner="mg"] .startup-runner { background-image: url("bootstrap/loading-runner-mg.webp"); }
.startup[data-runner="dl"] .startup-runner { background-image: url("bootstrap/loading-runner-dl.webp"); }
.startup[data-runner="sum"] .startup-runner { background-image: url("bootstrap/loading-runner-sum.webp"); }
.startup[data-runner="rf"] .startup-runner { background-image: url("bootstrap/loading-runner-rf.webp"); }
.progress { position: relative; width: 100%; height: 7px; border-radius: 9px; background: rgba(255,255,255,.12); }
.progress span { display: block; width: 0; height: 100%; border-radius: 9px; background: var(--mu-runner, var(--mu-accent)); box-shadow: 0 0 16px var(--mu-runner, var(--mu-accent)); transition: width .6s ease-out; }
.startup-copy { display: flex; align-items: flex-start; justify-content: space-between; gap: 13px; margin: 12px 0 13px; }
.startup-copy > div { min-width: 0; }
.startup-copy p { margin: 0; color: var(--mu-text); font: 500 17px/1.25 "MU Body", sans-serif; letter-spacing: .025em; }
.startup-copy small { display: block; margin-top: 4px; color: var(--mu-secondary); font: 500 12px/1.3 "MU Body", sans-serif; opacity: .84; }
.startup-percent { flex: 0 0 auto; color: var(--mu-runner, var(--mu-accent)); font: 700 17px/1.25 "MU Body", sans-serif; font-variant-numeric: tabular-nums; }
.startup-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.startup-actions button[hidden] { display: none; }
#startupLog { max-height: 36vh; overflow: auto; margin: 10px 0 0; padding: 8px 10px; border-radius: 6px; background: rgba(0,0,0,.58); color: #cfe3ff; font: 11px/1.35 ui-monospace, Consolas, monospace; white-space: pre-wrap; word-break: break-all; user-select: text; }
/* Recovery is actionable content, including on a short phone viewport. Do not
   inherit the compact loading screen's hidden hint or clip long translations. */
.startup[data-state="recovery"] { z-index: 40; }
.startup[data-state="recovery"] .startup-brand { display: none; }
.startup[data-state="recovery"] .startup-status {
  max-height: calc(100dvh - max(72px, env(safe-area-inset-top)) - max(22px, env(safe-area-inset-bottom)));
  overflow-y: auto; overscroll-behavior: contain;
}
.startup[data-state="recovery"] .startup-copy small {
  display: block; font: 400 18px/1.35 "MU UI", sans-serif; overflow-wrap: anywhere;
}
.startup[data-state="recovery"] .startup-actions button {
  min-height: 44px; font: 700 18px/1.25 "MU UI", sans-serif;
}
/* Failure: the runner stands still on its first frame; the percent is not a live value any more. */
.startup[data-state="recovery"] .startup-runner { animation: none; background-position: 0 0; }
.startup[data-state="recovery"] .startup-percent { display: none; }
@keyframes startup-drift { to { transform: scale(1.035) translate3d(-.7%, .35%, 0); } }
@keyframes startup-run { to { background-position: 120% 0; } }
button { border: 1px solid rgba(104, 215, 255, .65); border-radius: 6px; background: rgba(8, 30, 49, .88); color: #e8f8ff; padding: 9px 16px; cursor: url("bootstrap/mu_cursor.png") 2 2, pointer; }
button:hover { border-color: #f0c46c; color: #ffe1a2; }
.toolbar { position: absolute; z-index: 30; top: max(12px, env(safe-area-inset-top)); right: max(12px, env(safe-area-inset-right)); opacity: .72; }
.toolbar:hover { opacity: 1; }
.toolbar #fullscreen { min-height: 44px; box-sizing: border-box; }
/* Visibility is owned by the browser adapter: entry screens, or one actually
   painted mobile Menu cell. Never float a control above arbitrary game UI. */
.toolbar[hidden] { display: none; }
.toolbar { display: flex; gap: 8px; }
.toolbar button { font: 700 18px/1.2 "MU UI", sans-serif; }
.toolbar button[hidden] { display: none; }
#browserLauncher { display: none; }
.toolbar.in-game-menu { position: fixed; right: auto; opacity: 1; gap: 0; -webkit-text-size-adjust: none; text-size-adjust: none; }
.toolbar.in-game-menu > button { display: none; }
.toolbar.in-game-menu #browserLauncher {
  display: flex; flex-direction: column; align-items: center; justify-content: start;
  width: 100%; height: 100%; min-height: 0; padding: 4% 0 0; border: 0;
  background: transparent; font-size: inherit; line-height: 1; border-radius: 0;
}
#browserLauncher img { width: 53%; height: 53%; object-fit: contain; margin-bottom: 9%; }
#browserLauncher span {
  width: 100%; overflow-wrap: anywhere; overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
#browserLauncher:active img { transform: scale(.95); }
#browserHelp {
  width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 24px);
  padding: 16px; color: #e9eef1; background: #18242b; border: 1px solid #89989e;
  border-radius: 10px; font: 400 18px/1.4 "MU UI", sans-serif; overflow-y: auto;
}
#browserHelp::backdrop { background: #0009; }
#browserHelp header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
#browserHelp h2 { margin: 0; font-size: 20px; text-transform: uppercase; }
#browserHelp button { min-height: 44px; font: 700 18px/1.2 "MU UI", sans-serif; }
#browserHelp [hidden] { display: none; }
#browserMessage { color: #ffe1a2; }
.browser-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.rotate-hint {
  position: absolute; top: max(72px, env(safe-area-inset-top)); left: 20px; right: 20px;
  margin: 0; text-align: center; font: 400 18px/1.4 "MU UI", sans-serif;
  color: #f4ead8; pointer-events: none;
}
.rotate-hint[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .startup-bg { animation-duration: 2.6s; }
  .startup-runner { animation: none; transition: none; }
  .progress span { transition: none; }
}
@media (max-width: 760px), (max-height: 520px) {
  .startup-brand { top: max(24px, 6vh); left: max(24px, 5vw); }
  .startup-status { left: max(24px, 5vw); right: max(24px, 5vw); bottom: max(22px, 5vh); }
  .startup h1 { font-size: clamp(32px, 8vw, 54px); }
  .startup-copy small { display: none; }
  /* Short screens: recovery text and controls need the room more than the runner. */
  .startup[data-state="recovery"] .startup-lane { display: none; }
}

/* Same mobile layout on iOS/Android browsers. Portrait keeps a landscape
   game surface without stretching controls; rotation resets pointer ownership. */
.mu-touch-client body { cursor: auto; overscroll-behavior: none; }
/* iOS applies rubber-band scrolling and pull-to-refresh at the root element. */
html.mu-touch-client { overscroll-behavior: none; }
/* The canvas is not the whole page: in portrait the area above/below it, the
   loading screen and the toolbar are page too. A pinch or double tap there
   zoomed the whole game. Only the scrollable help/recovery/log panels pan. */
html.mu-touch-client, .mu-touch-client body, .mu-touch-client #app { touch-action: none; }
.mu-touch-client #browserHelp,
.mu-touch-client .startup[data-state="recovery"] .startup-status,
.mu-touch-client #startupLog { touch-action: pan-y; }
/* Give the native mobile gateway its viewport, not a stretched desktop panel.
   Its own shell supplies content sizing and the native density-aware scale.
   Reserve browser tools and cutouts outside it; desktop remains unchanged. */
.mu-touch-client #app { height: 100dvh; }
.mu-touch-client .toolbar:not(.in-game-menu) {
  top: max(6px, env(safe-area-inset-top)); left: max(8px, env(safe-area-inset-left));
  right: max(8px, env(safe-area-inset-right)); justify-content: center; opacity: 1; flex-wrap: wrap;
}
.mu-touch-client .toolbar:not(.in-game-menu) button { padding: 6px 12px; min-height: 44px; }
/* Full-bleed canvas, safe browser controls. Use the browser's current insets,
   never guessed phone dimensions or a whole-canvas notch margin. */
.mu-touch-client #browserHelp {
  --help-top: max(8px, env(safe-area-inset-top));
  --help-right: max(8px, env(safe-area-inset-right));
  --help-bottom: max(8px, env(safe-area-inset-bottom));
  --help-left: max(8px, env(safe-area-inset-left));
  inset: var(--help-top) var(--help-right) var(--help-bottom) var(--help-left);
  margin: auto;
  width: min(560px, calc(100% - var(--help-left) - var(--help-right)));
  max-width: calc(100% - var(--help-left) - var(--help-right));
  max-height: calc(100dvh - var(--help-top) - var(--help-bottom));
  overscroll-behavior: contain; overflow-wrap: anywhere;
}
.mu-touch-client #browserHelp header {
  position: sticky; top: -16px; z-index: 1; background: #18242b;
  padding-block: 8px; margin-top: -8px; align-items: flex-start;
}
.mu-touch-client #closeBrowserHelp { flex: 0 0 auto; }
.mu-touch-client #browserDisplayHelp summary { cursor: pointer; min-height: 44px; padding-block: 9px; }
.mu-touch-client .rotate-hint {
  left: max(20px, env(safe-area-inset-left)); right: max(20px, env(safe-area-inset-right));
}
.mu-touch-client #gateway:not([hidden]) {
  --entry-top: max(58px, var(--mu-entry-toolbar-bottom, 58px), calc(env(safe-area-inset-top) + 52px));
  --entry-bottom: max(8px, env(safe-area-inset-bottom));
  /* Keep media queries in the real phone viewport. Native .safe handles the
     horizontal inset; subtracting it from iframe width changes breakpoints. */
  width: 100vw;
  left: 50%;
  top: calc((100% + var(--entry-top) - var(--entry-bottom)) / 2);
  height: calc(100% - var(--entry-top) - var(--entry-bottom));
  max-height: calc(100% - var(--entry-top) - var(--entry-bottom));
  box-shadow: none;
  transition: none;
}
@media (orientation: portrait) {
  .mu-touch-client #canvas { position: absolute; top: 50%; height: 56.25vw; transform: translateY(-50%); }
}
