diff --git a/src/components/Hud.vue b/src/components/Hud.vue
index 9f5cd54..b7bf83b 100644
--- a/src/components/Hud.vue
+++ b/src/components/Hud.vue
@@ -1,5 +1,5 @@
diff --git a/src/components/UserProfileBar.vue b/src/components/UserProfileBar.vue
index b1d0aa1..0fd9b25 100644
--- a/src/components/UserProfileBar.vue
+++ b/src/components/UserProfileBar.vue
@@ -49,7 +49,9 @@ async function doLogout(): Promise {
.profile-bar {
display: flex;
align-items: center;
+ flex-wrap: wrap;
gap: 8px;
+ max-width: 100%;
background: var(--panel);
border: 1px solid var(--panel-border);
border-radius: 12px;
@@ -79,6 +81,25 @@ async function doLogout(): Promise {
padding: 5px 10px;
cursor: pointer;
}
+
+/* Phones: chips wrap into compact rows instead of overflowing */
+@media (max-width: 560px) {
+ .profile-bar {
+ gap: 5px;
+ padding: 5px 8px;
+ }
+ .crystals {
+ font-size: 13px;
+ }
+ .name {
+ font-size: 11.5px;
+ max-width: 92px;
+ }
+ .chip {
+ font-size: 11px;
+ padding: 4px 8px;
+ }
+}
.chip:hover {
border-color: var(--accent);
}
diff --git a/src/game/engine.ts b/src/game/engine.ts
index 005976a..45dbe3c 100644
--- a/src/game/engine.ts
+++ b/src/game/engine.ts
@@ -575,6 +575,24 @@ export class GameEngine {
this.onGameEnd?.({ win, score: this.score, wave: this.waveNo, kills: this.kills, crystalsEarned })
}
+ /**
+ * Solo: leaving a running game via "zum Hauptmenü"/Pause-Menü. Records the
+ * run (best score, stats, crystals — counted as a defeat) so progress from
+ * endless runs or early exits is not lost. No-ops when no game is running
+ * or the result was already reported by finish().
+ */
+ abandon(): void {
+ if (this.mpGameActive) return
+ if (this.phase !== 'wave' && this.phase !== 'intermission') return
+ const bestBefore = loadBest(this.difficulty, this.mapId)
+ const best = Math.max(bestBefore, this.score)
+ if (typeof localStorage !== 'undefined') {
+ localStorage.setItem(bestScoreKey(this.difficulty, this.mapId), String(best))
+ }
+ const crystalsEarned = calcCrystalsEarned(this.waveNo, this.score, false)
+ this.onGameEnd?.({ win: false, score: this.score, wave: this.waveNo, kills: this.kills, crystalsEarned })
+ }
+
private spawnEnemy(kind: EnemyKind): void {
const def = ENEMIES[kind]
const diff = DIFFICULTIES[this.difficulty]
diff --git a/src/game/store.ts b/src/game/store.ts
index 45208a2..66b4253 100644
--- a/src/game/store.ts
+++ b/src/game/store.ts
@@ -41,6 +41,9 @@ export const store = reactive({
buildType: null as TowerKind | null,
hoverValid: false,
+
+ /** automatically start the next wave as soon as intermission begins */
+ autoWave: typeof localStorage !== 'undefined' && localStorage.getItem('trxtd-autowave') === '1',
selected: null as SelectedTowerInfo | null,
obstacle: null as { tx: number; ty: number; type: 'tree' | 'rock'; cost: number } | null,