:root {
  --bg0: #0b101f;
  --bg1: #101d39;
  --text: #f8fbff;
  --muted: #bdd4ff;
  --primary: #5f89ff;
  --primary-2: #7fd5ff;
  --accent: #ff7b7b;
  --success: #59d5a8;
  --info: #6ab9ff;
  --warn: #ffbe62;
  --danger: #ff7e92;
  --panel: rgba(12, 20, 40, 0.66);
  --panel-border: rgba(150, 190, 255, 0.32);
  --badge: rgba(22, 38, 70, 0.76);
  --bg-image: none;
  --side-image-width-percent: 10;
  --top-image-height-px: 0;
  --map-top-clearance-px: 0;
  --map-safe-left-vw: 0;
  --map-safe-right-vw: 0;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --shadow-soft: 0 8px 24px rgba(8, 12, 30, 0.35);
  --shadow-pop: 0 12px 34px rgba(6, 10, 24, 0.52);
}


[data-theme="warm"] {
  --bg0: #1d0f12;
  --bg1: #2f1a1d;
  --text: #fff4ef;
  --muted: #ffd8cb;
  --primary: #ff7f7f;
  --primary-2: #ffb37d;
  --accent: #ff5d7a;
  --panel: rgba(48, 20, 20, 0.64);
  --panel-border: rgba(255, 184, 158, 0.36);
  --badge: rgba(72, 34, 26, 0.74);
}

[data-theme="emerald"] {
  --bg0: #081d1a;
  --bg1: #10352d;
  --text: #edfff8;
  --muted: #b8f5df;
  --primary: #2ed8a3;
  --primary-2: #6decbf;
  --accent: #68ffd1;
  --panel: rgba(11, 40, 33, 0.66);
  --panel-border: rgba(110, 236, 191, 0.36);
  --badge: rgba(15, 62, 50, 0.74);
}

[data-theme="violet"] {
  --bg0: #120f26;
  --bg1: #251947;
  --text: #f3efff;
  --muted: #d4c8ff;
  --primary: #9a7bff;
  --primary-2: #be8cff;
  --accent: #7b8fff;
  --panel: rgba(29, 20, 56, 0.66);
  --panel-border: rgba(183, 155, 255, 0.38);
  --badge: rgba(42, 30, 78, 0.74);
}

[data-theme="sunset"] {
  --bg0: #231108;
  --bg1: #3d1d0e;
  --text: #fff4ec;
  --muted: #ffd8bf;
  --primary: #ff9a54;
  --primary-2: #ffd26f;
  --accent: #ff7a7a;
  --panel: rgba(58, 30, 18, 0.66);
  --panel-border: rgba(255, 191, 133, 0.38);
  --badge: rgba(79, 43, 24, 0.74);
}

[data-theme="ocean"] {
  --bg0: #061925;
  --bg1: #0b2d44;
  --text: #ebf9ff;
  --muted: #b8e9ff;
  --primary: #3eb8ff;
  --primary-2: #64e5ff;
  --accent: #56d7ff;
  --panel: rgba(8, 36, 56, 0.66);
  --panel-border: rgba(128, 218, 255, 0.36);
  --badge: rgba(16, 61, 87, 0.74);
}

[data-theme="rose"] {
  --bg0: #260f1a;
  --bg1: #45182b;
  --text: #fff0f7;
  --muted: #ffd0e6;
  --primary: #ff6fa6;
  --primary-2: #ff9dc2;
  --accent: #ff7db0;
  --panel: rgba(61, 20, 40, 0.66);
  --panel-border: rgba(255, 165, 207, 0.38);
  --badge: rgba(86, 34, 61, 0.74);
}

[data-theme="graphite"] {
  --bg0: #0c0f14;
  --bg1: #1a212b;
  --text: #eef2f7;
  --muted: #c9d3df;
  --primary: #8ea3bb;
  --primary-2: #c4d0df;
  --accent: #9ab0c6;
  --panel: rgba(25, 31, 40, 0.66);
  --panel-border: rgba(166, 181, 199, 0.36);
  --badge: rgba(39, 49, 63, 0.74);
}


* {

  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: var(--text);
  font-family: "Microsoft YaHei", "PingFang SC", "Segoe UI", system-ui, sans-serif;
  background:
    var(--bg-image),
    radial-gradient(circle at 14% 10%, color-mix(in srgb, var(--primary) 42%, transparent) 0%, transparent 36%),
    radial-gradient(circle at 88% 78%, color-mix(in srgb, var(--primary-2) 34%, transparent) 0%, transparent 42%),
    linear-gradient(140deg, var(--bg0), var(--bg1));
  background-size: cover, auto, auto, auto;
  background-position: center center, center, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
}

body,
.map-wrap,
.tips,
.status,
.control-btn,
.speed-controls,
.runtime-badge,
.loading-card {
  transition: background-color 0.35s ease, border-color 0.35s ease, color 0.35s ease, box-shadow 0.35s ease;
}

html.theme-switching .bg-aurora,
html.theme-switching .bg-glow {
  animation-duration: 12s;
}

.app {
  --cam-x: 0px;
  --cam-y: 0px;
  position: relative;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  isolation: isolate;
}

.app::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 18;
  background:
    radial-gradient(circle at 50% 50%, rgba(226, 240, 255, 0.52), rgba(226, 240, 255, 0.08) 30%, transparent 64%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.16), transparent 46%);
}

.app.beat-flash::after {
  animation: beatFlash 240ms ease-out;
}


.app.cinematic-active .map-wrap {
  animation: introCameraPush 1.65s cubic-bezier(0.2, 0.76, 0.2, 1) both;
  filter: saturate(1.18) blur(1px);
}



.bg-grid,
.bg-glow,
.bg-aurora {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.bg-grid {
  background-image:
    linear-gradient(rgba(180, 210, 255, 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(180, 210, 255, 0.08) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(circle at 50% 50%, black 45%, transparent 90%);
  opacity: 0.22;
}

.bg-glow {
  background:
    radial-gradient(circle at 45% 50%, color-mix(in srgb, var(--primary) 30%, transparent), transparent 56%),
    radial-gradient(circle at 55% 58%, color-mix(in srgb, var(--primary-2) 25%, transparent), transparent 62%);
  filter: blur(6px);
}

.bg-aurora {
  background:
    radial-gradient(circle at 20% 20%, color-mix(in srgb, var(--primary) 24%, transparent), transparent 38%),
    radial-gradient(circle at 78% 68%, color-mix(in srgb, var(--primary-2) 20%, transparent), transparent 42%),
    radial-gradient(circle at 58% 26%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 34%);
  mix-blend-mode: screen;
  opacity: 0.45;
  animation: auroraShift 20s ease-in-out infinite alternate;
}

.map-wrap {
  --map-base-padding: clamp(10px, 1.2vw, 16px);
  position: relative;
  width: 100%;
  height: 100%;
  padding-top: calc(var(--map-base-padding) + var(--map-top-clearance-px) * 1px);
  padding-right: calc(var(--map-base-padding) + var(--map-safe-right-vw) * 1vw);
  padding-bottom: var(--map-base-padding);
  padding-left: calc(var(--map-base-padding) + var(--map-safe-left-vw) * 1vw);
  background: linear-gradient(156deg, rgba(7, 14, 28, 0.62), rgba(10, 12, 24, 0.76));
  transform-origin: 50% 52%;
  transition: transform 1s cubic-bezier(0.2, 0.75, 0.2, 1), filter 1s ease, padding 220ms ease;
}

.app.city-focus .map-wrap {
  transform: translate3d(var(--cam-x), var(--cam-y), 0) scale(1.022);
  filter: saturate(1.14);
  transition-duration: 340ms;
}

.map-wrap.camera-damped {
  transition-timing-function: cubic-bezier(0.16, 1.18, 0.3, 1);
}



.map-title {
  position: absolute;
  top: clamp(8px, 1.2vw, 14px);
  left: clamp(12px, 2vw, 22px);
  z-index: 4;
  font-size: clamp(14px, 1.8vw, 20px);
  font-weight: 700;
  text-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}

.tips {
  position: absolute;
  right: clamp(10px, 2vw, 20px);
  top: clamp(8px, 1.2vw, 14px);
  z-index: 4;
  text-align: right;
  line-height: 1.45;
  color: var(--muted);
  font-size: clamp(12px, 1.2vw, 14px);
  max-width: min(52%, 480px);
  user-select: none;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  padding: 8px 12px;
}

.runtime-badges {
  position: absolute;
  left: clamp(12px, 2vw, 22px);
  top: clamp(56px, 6.4vw, 86px);
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.map-title,
.tips,
.runtime-badges,
.status,
.progress-container {
  display: none !important;
}

.runtime-badge {
  width: fit-content;
  background: var(--badge);
  border: 1px solid var(--panel-border);
  color: #e7f0ff;
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 12px;
  letter-spacing: 0.2px;
  backdrop-filter: blur(6px);
}

.map-chart {
  width: 100%;
  height: 100%;
}

.status {
  position: absolute;
  left: 50%;
  bottom: clamp(8px, 1.2vw, 14px);
  transform: translateX(-50%);
  z-index: 4;
  white-space: nowrap;
  font-size: clamp(12px, 1.2vw, 15px);
  color: #ecf3ff;
  background: rgba(25, 42, 78, 0.72);
  border: 1px solid rgba(152, 190, 255, 0.42);
  border-radius: 999px;
  padding: 8px 16px;
  backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(8, 12, 30, 0.35);
}

.status.highlight {
  background: color-mix(in srgb, var(--primary) 42%, rgba(25, 42, 78, 0.72));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 56%, transparent), 0 0 20px color-mix(in srgb, var(--primary) 45%, transparent);
}

.progress-container {
  position: absolute;
  bottom: 52px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  width: min(86vw, 440px);
  height: 10px;
  border-radius: 99px;
  overflow: hidden;
  background: rgba(16, 32, 62, 0.66);
  border: 1px solid rgba(136, 180, 255, 0.35);
}

.progress-fill {
  position: relative;
  height: 100%;
  width: 0%;
  border-radius: 99px;
  transition: width 0.2s ease;
  background: linear-gradient(90deg, var(--primary), var(--primary-2));
}

.progress-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, 0.4) 45%, transparent 80%);
  animation: shine 1.6s linear infinite;
}

.control-fab {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 120;
  border: 1px solid rgba(150, 192, 255, 0.5);
  background: rgba(24, 42, 76, 0.86);
  color: #e8f1ff;
  border-radius: 999px;
  padding: 10px 16px;
  font-size: 13px;
  cursor: pointer;
  backdrop-filter: blur(8px);
}

.control-panel {
  position: fixed;
  right: 16px;
  bottom: 64px;
  z-index: 120;
  width: min(94vw, 388px);
  max-height: min(80vh, 780px);
  overflow: auto;
  padding: 12px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--panel) 95%, transparent);
  border: 1px solid var(--panel-border);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-pop);
  display: grid;
  gap: 10px;
}

.control-panel[hidden] {
  display: none !important;
}

.control-panel.panel-locked details,
.control-panel.panel-locked .panel-actions,
.control-panel.panel-locked .panel-actions-2 {
  pointer-events: none;
  opacity: 0.45;
}

.panel-lock-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 8px;
}

.panel-inline-hint {
  color: var(--muted);
  font-size: 12px;
  border: 1px dashed color-mix(in srgb, var(--panel-border) 84%, transparent);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
}

.panel-progress {
  width: 100%;
  height: 10px;
  border: 1px solid color-mix(in srgb, var(--panel-border) 84%, transparent);
  border-radius: 999px;
  background: rgba(16, 32, 62, 0.66);
  overflow: hidden;
}

.panel-progress::-webkit-progress-bar {
  background: rgba(16, 32, 62, 0.66);
}

.panel-progress::-webkit-progress-value {
  background: linear-gradient(90deg, var(--primary), var(--primary-2));
}

.panel-progress::-moz-progress-bar {
  background: linear-gradient(90deg, var(--primary), var(--primary-2));
}

.panel-group {
  border: 1px solid color-mix(in srgb, var(--panel-border) 80%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--panel) 85%, transparent);
}

.panel-group > summary {
  list-style: none;
  cursor: pointer;
  padding: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

.panel-group > summary::-webkit-details-marker {
  display: none;
}

.panel-group-content {
  border-top: 1px solid color-mix(in srgb, var(--panel-border) 62%, transparent);
  padding: 10px;
  display: grid;
  gap: 10px;
}

.panel-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.panel-actions-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.theme-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.theme-chip {
  border: 1px solid rgba(150, 192, 255, 0.42);
  background: rgba(24, 42, 76, 0.55);
  color: #dbeaff;
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  font-size: 12px;
  cursor: pointer;
}

.theme-chip:hover {
  background: color-mix(in srgb, var(--primary) 26%, rgba(24, 42, 76, 0.55));
}

.theme-chip.active,
.theme-chip[aria-pressed="true"] {
  border-color: color-mix(in srgb, var(--primary) 78%, #ffffff);
  background: color-mix(in srgb, var(--primary) 36%, rgba(24, 42, 76, 0.78));
  color: #ffffff;
  box-shadow: 0 0 12px color-mix(in srgb, var(--primary) 40%, transparent);
}

.control-btn {
  border: 1px solid rgba(150, 192, 255, 0.48);
  background: rgba(24, 42, 76, 0.76);
  color: #e8f1ff;
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 12px;
  cursor: pointer;
  backdrop-filter: blur(8px);
}

.control-btn-primary {
  background: linear-gradient(90deg, color-mix(in srgb, var(--primary) 72%, rgba(24, 42, 76, 0.86)), color-mix(in srgb, var(--primary-2) 70%, rgba(24, 42, 76, 0.86)));
  border-color: color-mix(in srgb, var(--primary) 80%, #fff);
  color: #fff;
  font-weight: 700;
}

.control-btn:hover:not(:disabled),
.control-fab:hover {
  transform: translateY(-1px) scale(1.02);
  background: color-mix(in srgb, var(--primary) 30%, rgba(24, 42, 76, 0.76));
  box-shadow: 0 0 14px color-mix(in srgb, var(--primary) 45%, transparent);
}

.control-btn:disabled {
  opacity: 0.56;
  cursor: not-allowed;
}

.panel-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #dceaff;
  font-size: 12px;
}

.speed-range {
  width: 100%;
  accent-color: var(--primary);
}

.panel-text-row {
  display: grid;
  grid-template-columns: 1fr 88px;
  gap: 8px;
}

.panel-color-input {
  border: 1px solid rgba(150, 192, 255, 0.34);
  border-radius: 9px;
  height: 36px;
  padding: 2px;
  background: rgba(10, 18, 34, 0.78);
}

.panel-bg-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
}

.panel-input {
  min-width: 0;
  border: 1px solid rgba(150, 192, 255, 0.34);
  border-radius: 9px;
  padding: 7px 9px;
  background: rgba(10, 18, 34, 0.78);
  color: #e8f1ff;
  outline: none;
}

.panel-select {
  appearance: none;
}

#openControlPageBtn {
  width: 100%;
}

.panel-input::placeholder {
  color: rgba(216, 230, 255, 0.5);
}

.toast-container {
  position: fixed;
  right: 14px;
  top: 14px;
  z-index: 190;
  display: grid;
  gap: 8px;
  pointer-events: none;
}

.toast {
  min-width: min(86vw, 340px);
  max-width: min(92vw, 420px);
  background: color-mix(in srgb, var(--panel) 95%, transparent);
  border: 1px solid var(--panel-border);
  border-left: 4px solid var(--info);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  color: var(--text);
  font-size: 12px;
  box-shadow: var(--shadow-soft);
  opacity: 0;
  transform: translateY(-6px);
  animation: toastIn 180ms ease forwards;
}

.toast.success { border-left-color: var(--success); }
.toast.warn { border-left-color: var(--warn); }
.toast.error { border-left-color: var(--danger); }

.toast.hide {
  animation: toastOut 200ms ease forwards;
}


.cinematic-intro {
  --intro-welcome-delay-ms: 90ms;
  --intro-welcome-duration-ms: 900ms;
  --intro-title-delay-ms: 320ms;
  --intro-title-duration-ms: 1200ms;
  --intro-subtitle-delay-ms: 560ms;
  --intro-subtitle-duration-ms: 820ms;
  --intro-glow-delay-ms: 1320ms;
  --intro-sweep-delay-ms: 1400ms;
  --intro-vignette-pulse-ms: 2200ms;
  --intro-vignette-breath-ms: 3200ms;
  --intro-grain-ms: 680ms;
  position: absolute;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
  opacity: 1;
  transition: opacity 620ms ease;
}


.cinematic-intro.done {
  opacity: 0;
}

.intro-particles,
.intro-vignette {
  position: absolute;
  inset: 0;
}

.intro-particles {
  width: 100%;
  height: 100%;
  z-index: 0;
}

.intro-vignette {
  z-index: 1;
  background:
    radial-gradient(circle at 50% 50%, transparent 20%, rgba(5, 10, 20, 0.78) 86%),
    linear-gradient(180deg, rgba(7, 9, 16, 0.9), rgba(8, 10, 18, 0.54) 30%, rgba(7, 9, 16, 0.88));
}

.cinematic-intro::before {
  content: "";
  position: absolute;
  inset: -30%;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: soft-light;
  background-image:
    radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.12) 0.55px, transparent 1.2px),
    radial-gradient(circle at 70% 70%, rgba(255, 255, 255, 0.09) 0.55px, transparent 1.1px);
  background-size: 2px 2px, 3px 3px;
}


.intro-title-wrap {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: grid;
  place-items: center;
  text-align: center;
}

.intro-welcome {
  margin-bottom: 18px;
  font-size: clamp(20px, 3.2vw, 44px);
  font-weight: 900;
  letter-spacing: 0.08em;
  background: linear-gradient(90deg, rgba(230,244,255,0.98), rgba(116,166,255,0.99), rgba(73,126,255,0.99));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 0 20px rgba(90,150,255,0.66);
  opacity: 0;
  animation: welcomeFadeIn 1s ease forwards;
}

.intro-title {
  font-size: clamp(34px, 7.8vw, 104px);
  font-weight: 900;
  letter-spacing: 0.06em;
  color: rgba(235, 245, 255, 0.96);
  text-shadow: 0 0 22px color-mix(in srgb, var(--primary) 55%, transparent);
  filter: blur(0.4px);
  opacity: 0;
  transform: translateY(10px) scale(0.98);
}

.cinematic-intro.solid-mode .intro-particles {
  display: none;
}

.cinematic-intro.solid-mode .intro-vignette {
  animation:
    introVignettePulse var(--intro-vignette-pulse-ms) ease-in-out infinite alternate,
    introVignetteBreath var(--intro-vignette-breath-ms) ease-in-out infinite;
}

.cinematic-intro.solid-mode::before {
  opacity: 0.48;
  animation: introFilmGrain var(--intro-grain-ms) steps(8, end) infinite;
}

.cinematic-intro.solid-mode .intro-welcome {
  opacity: 0;
  animation: introWelcomeFilmIn var(--intro-welcome-duration-ms) cubic-bezier(0.16, 0.86, 0.2, 1) var(--intro-welcome-delay-ms) forwards;
}

.cinematic-intro.solid-mode .intro-title {
  opacity: 0;
  background-image: linear-gradient(108deg, rgba(235, 245, 255, 0.92) 0%, rgba(235, 245, 255, 0.98) 42%, rgba(255, 255, 255, 1) 50%, rgba(235, 245, 255, 0.98) 58%, rgba(235, 245, 255, 0.92) 100%);
  background-size: 240% 100%;
  background-position: -140% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation:
    introTitleFilmIn var(--intro-title-duration-ms) cubic-bezier(0.12, 0.8, 0.2, 1) var(--intro-title-delay-ms) forwards,
    introTitleSolidGlow 1600ms ease-in-out var(--intro-glow-delay-ms) infinite alternate,
    introTitleSweep 3000ms linear var(--intro-sweep-delay-ms) infinite;
}


.cinematic-intro.solid-mode .intro-subtitle {
  opacity: 0;
  animation:
    introSubtitleSolidIn var(--intro-subtitle-duration-ms) cubic-bezier(0.2, 0.75, 0.2, 1) var(--intro-subtitle-delay-ms) forwards,
    introPulse 1.6s ease-in-out calc(var(--intro-subtitle-delay-ms) + var(--intro-subtitle-duration-ms) - 120ms) infinite;
}


.intro-subtitle {


  margin-top: 14px;
  font-size: clamp(12px, 1.55vw, 20px);
  letter-spacing: 0.34em;
  color: rgba(209, 229, 255, 0.85);
  text-transform: uppercase;
  animation: introPulse 1.4s ease-in-out infinite;
}

.loading-mask {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, rgba(8, 14, 30, 0.92), rgba(12, 18, 34, 0.84));
  opacity: 1;
  transition: opacity 280ms ease;
}

.loading-mask.hidden {
  opacity: 0;
  pointer-events: none;
}

.loading-card {
  width: min(86vw, 420px);
  border-radius: 16px;
  padding: 20px 18px;
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  border: 1px solid var(--panel-border);
  backdrop-filter: blur(10px);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.35);
}

.loading-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.loading-subtitle {
  margin-top: 8px;
  color: var(--muted);
  font-size: 13px;
}

.loading-bar {
  margin-top: 14px;
  width: 100%;
  height: 8px;
  border-radius: 99px;
  overflow: hidden;
  background: rgba(180, 210, 255, 0.16);
}

.loading-bar-fill {
  display: block;
  width: 42%;
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--primary), var(--primary-2));
  animation: loadSweep 1.4s ease-in-out infinite;
}

.top-image-slot {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  height: calc(var(--top-image-height-px) * 1px);
  pointer-events: none;
  z-index: 50;
  opacity: 0;
  transition: opacity 220ms ease;
}

.top-image-slot.has-image {
  opacity: 1;
}

.top-image {
  display: block;
  height: 100%;
  width: auto;
  max-width: none;
  object-fit: contain;
  object-position: center top;
}

.side-image-slot {
  position: fixed;
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  width: calc(var(--side-image-width-percent) * 1vw);
  height: auto;
  pointer-events: none;
  z-index: 16;
  opacity: 0;
  transition: opacity 220ms ease;
}


.side-image-slot.has-image {
  opacity: 1;
}

.side-image-left {
  left: 0;
}

.side-image-right {
  right: 0;
}

.side-image {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
  object-position: center;
}

.webgl-fx,
.fireworks {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease;
  mix-blend-mode: screen;
}

.webgl-fx {
  z-index: 19;
  filter: saturate(1.06) contrast(1.04);
}

.webgl-fx.active {
  opacity: 1;
}

.fireworks {
  z-index: 20;
  filter: saturate(1.08) contrast(1.06);
}


.fireworks.active {
  opacity: 1;
}

.celebrate-sticky-text {
  position: fixed;
  left: 50%;
  top: 52%;
  transform: translate(-50%, -50%);
  z-index: 1001;
  min-width: min(72vw, 960px);
  padding: 14px 24px;
  text-align: center;
  font-size: clamp(34px, 7.2vw, 112px);
  font-weight: 900;
  letter-spacing: 0.04em;
  color: #7da8ff;
  text-shadow: 0 0 20px rgba(125, 168, 255, 0.8);
  background: rgba(8, 16, 34, 0.34);
  border-radius: 14px;
  backdrop-filter: blur(3px);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 260ms ease;
}


.celebrate-sticky-text.active {
  opacity: 1;
  animation:
    celebrateStickyPop 420ms cubic-bezier(0.2, 0.75, 0.2, 1),
    celebrateStickyGlow 1500ms ease-in-out 380ms infinite alternate;
}

.bg-fullscreen-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
}


.bg-fullscreen-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

.bg-fullscreen-image {
  width: 100vw;
  height: 100vh;
  object-fit: cover;
  object-position: center;
  display: block;
}

@keyframes shine {

  from { transform: translateX(-110%); }
  to { transform: translateX(110%); }
}

@keyframes loadSweep {
  0% { transform: translateX(-120%); }
  50% { transform: translateX(120%); }
  100% { transform: translateX(120%); }
}

@keyframes auroraShift {
  0% { transform: translate3d(-2%, 0, 0) scale(1); }
  50% { transform: translate3d(2%, -1.2%, 0) scale(1.04); }
  100% { transform: translate3d(-1%, 2%, 0) scale(1.06); }
}

@keyframes introPulse {
  0%, 100% { opacity: 0.55; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-2px); }
}

@keyframes beatFlash {
  0% { opacity: 0; }
  18% { opacity: 0.85; }
  100% { opacity: 0; }
}

@keyframes introCameraPush {
  0% { transform: scale(1.2); filter: saturate(1.3) blur(2px); }
  60% { transform: scale(1.08); filter: saturate(1.22) blur(1.1px); }
  100% { transform: scale(1.02); filter: saturate(1.12) blur(0); }
}

@keyframes welcomeFadeIn {
  0% { opacity: 0; transform: translateY(14px) scale(0.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes introTitleSolidIn {
  0% { opacity: 0; transform: translateY(18px) scale(0.96); filter: blur(1.6px); letter-spacing: 0.11em; }
  68% { opacity: 1; transform: translateY(-2px) scale(1.018); filter: blur(0.2px); letter-spacing: 0.065em; }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0.2px); letter-spacing: 0.06em; }
}

@keyframes introWelcomeSolidIn {
  0% { opacity: 0; transform: translateY(16px) scale(0.96); filter: blur(1px); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}

@keyframes introWelcomeFilmIn {
  0% { opacity: 0; transform: translateY(18px) scale(1.08); filter: blur(1.8px); }
  64% { opacity: 1; transform: translateY(-1px) scale(1.01); filter: blur(0.3px); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}

@keyframes introTitleFilmIn {
  0% { opacity: 0; transform: translateY(24px) scale(1.1); filter: blur(2.2px); letter-spacing: 0.13em; }
  62% { opacity: 1; transform: translateY(-1px) scale(1.018); filter: blur(0.35px); letter-spacing: 0.068em; }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0.2px); letter-spacing: 0.06em; }
}

@keyframes introSubtitleSolidIn {
  0% { opacity: 0; transform: translateY(8px) scale(0.98); letter-spacing: 0.4em; }
  100% { opacity: 1; transform: translateY(0) scale(1); letter-spacing: 0.34em; }
}

@keyframes introTitleSolidGlow {
  0% { text-shadow: 0 0 18px color-mix(in srgb, var(--primary) 55%, transparent), 0 0 36px color-mix(in srgb, var(--primary-2) 28%, transparent); }
  100% { text-shadow: 0 0 30px color-mix(in srgb, var(--primary) 76%, transparent), 0 0 56px color-mix(in srgb, var(--primary-2) 46%, transparent); }
}

@keyframes introVignettePulse {
  0% { opacity: 0.78; }
  100% { opacity: 1; }
}

@keyframes introVignetteBreath {
  0% {
    filter: brightness(0.86) saturate(0.9);
    transform: scale(1);
  }
  100% {
    filter: brightness(1.12) saturate(1.14);
    transform: scale(1.02);
  }
}

@keyframes introFilmGrain {
  0% { transform: translate3d(0, 0, 0); }
  20% { transform: translate3d(-3.2%, 1.8%, 0); }
  40% { transform: translate3d(2.1%, -2.8%, 0); }
  60% { transform: translate3d(2.8%, 1.5%, 0); }
  80% { transform: translate3d(-1.9%, -2.2%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}


@keyframes introTitleSweep {
  0% { background-position: -140% 50%; }
  55% { background-position: -30% 50%; }
  100% { background-position: 140% 50%; }
}

@keyframes celebrateStickyPop {
  0% { opacity: 0; transform: translate(-50%, -52%) scale(0.88); filter: blur(1px); }
  65% { opacity: 1; transform: translate(-50%, -50%) scale(1.04); filter: blur(0); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); filter: blur(0); }
}

@keyframes celebrateStickyGlow {
  0% {
    text-shadow:
      0 0 20px color-mix(in srgb, currentColor 84%, transparent),
      0 0 36px color-mix(in srgb, currentColor 48%, transparent);
    box-shadow: 0 0 0 rgba(120, 170, 255, 0);
  }
  100% {
    text-shadow:
      0 0 30px color-mix(in srgb, currentColor 96%, transparent),
      0 0 56px color-mix(in srgb, currentColor 62%, transparent);
    box-shadow: 0 0 26px color-mix(in srgb, currentColor 34%, transparent);
  }
}

@keyframes toastIn {



  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes toastOut {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-4px); }
}

@media (max-width: 760px) {

  .tips {
    max-width: 62%;
    font-size: 11px;
  }

  .runtime-badges {
    top: 84px;
  }

  .control-fab {
    right: 10px;
    bottom: 10px;
    padding: 8px 12px;
  }

  .control-panel {
    right: 10px;
    bottom: 52px;
    width: min(94vw, 340px);
  }



  .panel-actions {
    grid-template-columns: 1fr;
  }

  .panel-text-row,
  .panel-bg-row {
    grid-template-columns: 1fr;
  }

  .theme-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }



  .progress-container {

    width: 90vw;
    bottom: 60px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .progress-fill::after,
  .loading-bar-fill,
  .bg-aurora,
  .intro-subtitle,
  .app.beat-flash::after,
  .cinematic-intro::before,
  .cinematic-intro.solid-mode .intro-vignette,
  .cinematic-intro.solid-mode .intro-welcome,
  .cinematic-intro.solid-mode .intro-title,
  .cinematic-intro.solid-mode .intro-subtitle {
    animation: none !important;
    transition: none !important;
  }
}
