feat(sasch40): multi-room tavern, authentic character portraits, pre-level start screens & bollerwagen redesign
This commit is contained in:
@@ -7,6 +7,9 @@ import { sound } from '../audio/synthAudio'
|
||||
|
||||
const store = useGameStore()
|
||||
|
||||
type TavernRoom = 'schankraum' | 'marktplatz' | 'hinterland' | 'hinterzimmer'
|
||||
const currentRoom = ref<TavernRoom>('schankraum')
|
||||
|
||||
interface ActiveDialog {
|
||||
characterId: string
|
||||
name: string
|
||||
@@ -23,6 +26,17 @@ const duelStep = ref(0)
|
||||
const duelWon = ref(false)
|
||||
const zulumanMirrorActive = ref(false)
|
||||
|
||||
function switchRoom(room: TavernRoom) {
|
||||
sound.playDialogueBlip()
|
||||
currentRoom.value = room
|
||||
}
|
||||
|
||||
function enterSecretHinterzimmer() {
|
||||
sound.playFanfare()
|
||||
store.unlockEasterEgg('hinterzimmer')
|
||||
currentRoom.value = 'hinterzimmer'
|
||||
}
|
||||
|
||||
function openCharacterDialog(charId: string) {
|
||||
const char = CHARACTERS[charId]
|
||||
if (!char) return
|
||||
@@ -81,42 +95,16 @@ function openCharacterDialog(charId: string) {
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'pue') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Majestät! Die magischen Kristall-Fackeln sind verkabelt und synchronisiert. Sobald der Drop bei 135 BPM einschlägt, brennt der Saal!',
|
||||
actionLabel: 'Zünde den Stroboskop-Zauber!',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(4)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'mane') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Servus beinand! Ich wandere grad gemütlich durch die Schenke. Wander-Tipp: Wenn du nachher auf den Festwagen steigst, halte dich an die Kronkorken-Spur!',
|
||||
actionLabel: 'Danke Mane! Berg heil!',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(2)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'mario') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Hoppla die Waldfee! Schau wie die Bierkrüge und Hopfendolden durch die Luft wirbeln! Ein Hoch auf König Sascha!',
|
||||
actionLabel: 'Sauber jongliert, Mario! (+3 Kronkorken)',
|
||||
text: 'Hoppla die Waldfee! Schau wie die kreischenden Kettensägen und Hopfenkrüge durch die Luft wirbeln! Keine Sorge Majestät, die Ketten sind frisch geölt! Nimm diese 4 Meister-Korken!',
|
||||
actionLabel: 'Sauber jongliert, Mario! (+4 Kronkorken)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(3)
|
||||
store.addKronkorken(4)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
@@ -134,6 +122,72 @@ function openCharacterDialog(charId: string) {
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'mane') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Servus beinand! Ich wandere grad über den Haumdaucher Höhenweg. Wander-Tipp: Wer rastet, der rostet – und wer nicht tanzt, kriegt keinen Schaum auf die Halbe! Hier, 4 Kronkorken für den Gipfelsturm!',
|
||||
actionLabel: 'Danke Mane! Berg heil! (+4 Kronkorken)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(4)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'hansi') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Habe die Ehre Sascha! Schau dir dieses Panorama an. Ich halte hier die Stellung und habe dir 4 Kronkorken gesichert!',
|
||||
actionLabel: 'Danke Hansi! (+4 Kronkorken)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(4)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'pue') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Majestät! Willkommen im innersten VIP-Kreis des Basses! Die magischen Kristalle vibrieren auf 135 BPM und die Lasershow brennt! Hier sind 5 Kronkorken für den Stroboskop-Zauber!',
|
||||
actionLabel: 'Zünde den Kristall-Zauber, Pü! (+5 Kronkorken)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(5)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'flo_maier') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Habe die Ehre Sascha! Die Monitore wummern mit 135 BPM! Ich hab dir eine geheime Bass-Platte aufgelegt – hier sind 5 Meister-Kronkorken für den nächsten Drop!',
|
||||
actionLabel: 'Dreh die Bässe auf, Flo! (+5 Kronkorken)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(5)
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
} else if (charId === 'viktor') {
|
||||
activeDialog.value = {
|
||||
characterId: charId,
|
||||
name: char.name,
|
||||
title: char.title,
|
||||
portrait: char.portrait,
|
||||
text: 'Servus König Sascha! Im Hinterzimmer fließt das Helle kälter als die Nacht! Hoch die Krüge auf 40 Jahre Regentschaft!',
|
||||
actionLabel: 'Prost Viktor! (+3 Kronkorken & Helles)',
|
||||
actionFn: () => {
|
||||
store.addKronkorken(3)
|
||||
store.addBeer()
|
||||
activeDialog.value = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,57 +226,192 @@ function proceedToExpress() {
|
||||
<template>
|
||||
<div class="tavern-container">
|
||||
<div class="scene-viewport">
|
||||
<img src="/assets/scenes/tavern.jpg" alt="Taverne Zum wummernden Ritter" class="tavern-bg" />
|
||||
|
||||
<!-- Interactive Hotspots on the visual scene with Avatar Thumbnails -->
|
||||
<button class="hotspot hotspot-verena" @click="openCharacterDialog('verena')">
|
||||
<img :src="CHARACTERS.verena.portrait" class="hotspot-thumb" alt="Königin Verena" />
|
||||
<span class="hotspot-badge">Verena 👑</span>
|
||||
</button>
|
||||
<!-- ================= 1. GASTSTUBE (SCHANKRAUM) ================= -->
|
||||
<template v-if="currentRoom === 'schankraum'">
|
||||
<img src="/assets/scenes/tavern.jpg" alt="Gaststube Zum wummernden Ritter" class="tavern-bg" />
|
||||
|
||||
<button class="hotspot hotspot-armend" @click="openCharacterDialog('armend')">
|
||||
<img :src="CHARACTERS.armend.portrait" class="hotspot-thumb" alt="Armend" />
|
||||
<span class="hotspot-badge">Armend 🔨</span>
|
||||
</button>
|
||||
<!-- Verena on the wooden gallery -->
|
||||
<button class="hotspot hotspot-verena" @click="openCharacterDialog('verena')">
|
||||
<img :src="CHARACTERS.verena.portrait" class="hotspot-thumb" alt="Königin Verena" />
|
||||
<span class="hotspot-badge">Verena 👑</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-lutz" @click="openCharacterDialog('lutz')">
|
||||
<img :src="CHARACTERS.lutz.portrait" class="hotspot-thumb" alt="Lutz" />
|
||||
<span class="hotspot-badge">Lutz (ZTUL) 🎩</span>
|
||||
</button>
|
||||
<!-- Armend at the forge/anvil -->
|
||||
<button class="hotspot hotspot-armend" @click="openCharacterDialog('armend')">
|
||||
<img :src="CHARACTERS.armend.portrait" class="hotspot-thumb" alt="Armend" />
|
||||
<span class="hotspot-badge">Armend 🔨</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-amy" @click="openCharacterDialog('amy')">
|
||||
<img :src="CHARACTERS.amy.portrait" class="hotspot-thumb" alt="Amy" />
|
||||
<span class="hotspot-badge">Amy 🎨</span>
|
||||
</button>
|
||||
<!-- Lutz at the fireplace -->
|
||||
<button class="hotspot hotspot-lutz" @click="openCharacterDialog('lutz')">
|
||||
<img :src="CHARACTERS.lutz.portrait" class="hotspot-thumb" alt="Lutz" />
|
||||
<span class="hotspot-badge">Lutz (ZTUL) 🎩</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-mirror" @click="inspectMirror">
|
||||
<span class="mirror-icon">🪞</span>
|
||||
<span class="hotspot-badge pulse">Zuluman-Spiegel</span>
|
||||
</button>
|
||||
<!-- Amy at the tavern table -->
|
||||
<button class="hotspot hotspot-amy" @click="openCharacterDialog('amy')">
|
||||
<img :src="CHARACTERS.amy.portrait" class="hotspot-thumb" alt="Amy" />
|
||||
<span class="hotspot-badge">Amy 🎨</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-pue" @click="openCharacterDialog('pue')">
|
||||
<img :src="CHARACTERS.pue.portrait" class="hotspot-thumb" alt="Pü" />
|
||||
<span class="hotspot-badge">Pü (Licht) 💡</span>
|
||||
</button>
|
||||
<!-- Zuluman Magic Mirror on the pillar -->
|
||||
<button class="hotspot hotspot-mirror" @click="inspectMirror">
|
||||
<span class="mirror-icon">🪞</span>
|
||||
<span class="hotspot-badge pulse">Zuluman-Spiegel</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-mane" @click="openCharacterDialog('mane')">
|
||||
<img :src="CHARACTERS.mane.portrait" class="hotspot-thumb" alt="Mane" />
|
||||
<span class="hotspot-badge">Mane 🥾</span>
|
||||
</button>
|
||||
<!-- Doorway to Marktplatz -->
|
||||
<button class="hotspot door-hotspot hotspot-door-marktplatz" @click="switchRoom('marktplatz')">
|
||||
<span class="door-icon">🚪</span>
|
||||
<span class="hotspot-badge glow-door">Zum Marktplatz ▶</span>
|
||||
</button>
|
||||
|
||||
<button class="hotspot hotspot-nat" @click="openCharacterDialog('nat')">
|
||||
<img :src="CHARACTERS.nat.portrait" class="hotspot-thumb" alt="NAT" />
|
||||
<span class="hotspot-badge">NAT 🐗</span>
|
||||
</button>
|
||||
<!-- SECRET EASTER EGG TRIGGER: Hidden Beer Tap to Hinterzimmer -->
|
||||
<button class="hotspot secret-tap-hotspot" @click="enterSecretHinterzimmer" title="Ein sonderbarer goldener Zapfhahn...">
|
||||
<span class="secret-tap-icon pulse">🗝️</span>
|
||||
<span class="secret-badge">Geheimer Zapfhahn</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<button class="hotspot hotspot-mario" @click="openCharacterDialog('mario')">
|
||||
<img :src="CHARACTERS.mario.portrait" class="hotspot-thumb" alt="Mario" />
|
||||
<span class="hotspot-badge">Mario 🤹</span>
|
||||
</button>
|
||||
<!-- ================= 2. MARKTPLATZ ================= -->
|
||||
<template v-else-if="currentRoom === 'marktplatz'">
|
||||
<img src="/assets/scenes/marktplatz.jpg" alt="Marktplatz Haumdaucher" class="tavern-bg" />
|
||||
|
||||
<!-- Gaukler Mario juggling chainsaws with animations & flying sparks -->
|
||||
<div class="mario-container">
|
||||
<button class="hotspot hotspot-mario" @click="openCharacterDialog('mario')">
|
||||
<div class="chainsaw-circus">
|
||||
<span class="saw saw-left">🪚</span>
|
||||
<span class="saw saw-right">🪚</span>
|
||||
<span class="spark spark-1">⚡</span>
|
||||
<span class="spark spark-2">✨</span>
|
||||
</div>
|
||||
<img :src="CHARACTERS.mario.portrait" class="hotspot-thumb" alt="Mario" />
|
||||
<span class="hotspot-badge">Mario (Kettensägen!) 🤹</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- NAT at the fountain -->
|
||||
<button class="hotspot hotspot-nat" @click="openCharacterDialog('nat')">
|
||||
<img :src="CHARACTERS.nat.portrait" class="hotspot-thumb" alt="NAT" />
|
||||
<span class="hotspot-badge">NAT (Josef) 🐗</span>
|
||||
</button>
|
||||
|
||||
<!-- Door back to Gaststube -->
|
||||
<button class="hotspot door-hotspot hotspot-door-back-gaststube" @click="switchRoom('schankraum')">
|
||||
<span class="door-icon">🚪</span>
|
||||
<span class="hotspot-badge glow-door">◀ Zur Gaststube</span>
|
||||
</button>
|
||||
|
||||
<!-- Trail to Hinterland -->
|
||||
<button class="hotspot door-hotspot hotspot-door-hinterland" @click="switchRoom('hinterland')">
|
||||
<span class="door-icon">🌲</span>
|
||||
<span class="hotspot-badge glow-door">Zum Hinterland ▶</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<!-- ================= 3. HINTERLAND ================= -->
|
||||
<template v-else-if="currentRoom === 'hinterland'">
|
||||
<img src="/assets/scenes/hinterland.jpg" alt="Hinterland Haumdaucher Alm" class="tavern-bg" />
|
||||
|
||||
<!-- Wanderin Mane (Ramona) hiking with animated stride -->
|
||||
<button class="hotspot hotspot-mane hiking-anim" @click="openCharacterDialog('mane')">
|
||||
<span class="hiking-stick">🦯</span>
|
||||
<img :src="CHARACTERS.mane.portrait" class="hotspot-thumb" alt="Mane" />
|
||||
<span class="hotspot-badge">Mane (Wanderin) 🥾</span>
|
||||
</button>
|
||||
|
||||
<!-- Hansi enjoying the view on the bench -->
|
||||
<button class="hotspot hotspot-hansi" @click="openCharacterDialog('hansi')">
|
||||
<img :src="CHARACTERS.hansi.portrait" class="hotspot-thumb" alt="Hansi" />
|
||||
<span class="hotspot-badge">Hansi 🧔</span>
|
||||
</button>
|
||||
|
||||
<!-- Trail back to Marktplatz -->
|
||||
<button class="hotspot door-hotspot hotspot-door-back-marktplatz" @click="switchRoom('marktplatz')">
|
||||
<span class="door-icon">🎪</span>
|
||||
<span class="hotspot-badge glow-door">◀ Zum Marktplatz</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<!-- ================= 4. HINTERZIMMER (SECRET VIP RAVE) ================= -->
|
||||
<template v-else-if="currentRoom === 'hinterzimmer'">
|
||||
<img src="/assets/scenes/hinterzimmer.jpg" alt="Geheimes VIP Hinterzimmer" class="tavern-bg" />
|
||||
<div class="strobe-overlay"></div>
|
||||
|
||||
<!-- Pü with pulsing crystal staff and disco lasers -->
|
||||
<button class="hotspot hotspot-pue rave-pulse" @click="openCharacterDialog('pue')">
|
||||
<span class="crystal-laser">💎✨</span>
|
||||
<img :src="CHARACTERS.pue.portrait" class="hotspot-thumb" alt="Pü" />
|
||||
<span class="hotspot-badge">Pü (Kristall-Zauber) 💡</span>
|
||||
</button>
|
||||
|
||||
<!-- Flo Maier at mixing deck -->
|
||||
<button class="hotspot hotspot-flo" @click="openCharacterDialog('flo_maier')">
|
||||
<img :src="CHARACTERS.flo_maier.portrait" class="hotspot-thumb" alt="Flo Maier" />
|
||||
<span class="hotspot-badge">DJ Flo Maier 🎧</span>
|
||||
</button>
|
||||
|
||||
<!-- Viktor the vampire night-guard -->
|
||||
<button class="hotspot hotspot-viktor" @click="openCharacterDialog('viktor')">
|
||||
<img :src="CHARACTERS.viktor.portrait" class="hotspot-thumb" alt="Viktor" />
|
||||
<span class="hotspot-badge">Viktor 🧛</span>
|
||||
</button>
|
||||
|
||||
<!-- Door back to Gaststube -->
|
||||
<button class="hotspot door-hotspot hotspot-door-back-vip" @click="switchRoom('schankraum')">
|
||||
<span class="door-icon">🚪</span>
|
||||
<span class="hotspot-badge glow-door">◀ Zurück in die Gaststube</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<!-- Bottom Scene Navigation & Duel -->
|
||||
<div class="scene-bottom-nav">
|
||||
<div class="tavern-bar-title">🍻 TAVERNE ZUM WUMMERNDEN RITTER 🍻</div>
|
||||
<!-- Room Title Badge -->
|
||||
<div class="tavern-bar-title">
|
||||
{{
|
||||
currentRoom === 'schankraum' ? '🍻 AKT III: GASTSTUBE ZUM WUMMERNDEN RITTER 🍻' :
|
||||
currentRoom === 'marktplatz' ? '🎪 AKT III: HAUMDAUCHER MARKTPLATZ 🎪' :
|
||||
currentRoom === 'hinterland' ? '🌲 AKT III: ALPINES HINTERLAND 🌲' :
|
||||
'🪩 AKT III: GEHEIMES VIP-HINTERZIMMER 🪩'
|
||||
}}
|
||||
</div>
|
||||
|
||||
<!-- Quick Room Navigation Tabs -->
|
||||
<div class="room-nav-tabs">
|
||||
<button
|
||||
class="room-tab"
|
||||
:class="{ active: currentRoom === 'schankraum' }"
|
||||
@click="switchRoom('schankraum')"
|
||||
>
|
||||
🍺 Gaststube
|
||||
</button>
|
||||
<button
|
||||
class="room-tab"
|
||||
:class="{ active: currentRoom === 'marktplatz' }"
|
||||
@click="switchRoom('marktplatz')"
|
||||
>
|
||||
🎪 Marktplatz
|
||||
</button>
|
||||
<button
|
||||
class="room-tab"
|
||||
:class="{ active: currentRoom === 'hinterland' }"
|
||||
@click="switchRoom('hinterland')"
|
||||
>
|
||||
🌲 Hinterland
|
||||
</button>
|
||||
<button
|
||||
v-if="store.unlockedEasterEggs.includes('hinterzimmer') || currentRoom === 'hinterzimmer'"
|
||||
class="room-tab vip-tab"
|
||||
:class="{ active: currentRoom === 'hinterzimmer' }"
|
||||
@click="switchRoom('hinterzimmer')"
|
||||
>
|
||||
🪩 Hinterzimmer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Action Row (Duel & Next Level) -->
|
||||
<div class="tavern-nav-buttons">
|
||||
<button class="duel-trigger" @click="startGstanzlDuel">
|
||||
⚔️ Gstanzl-Fechten
|
||||
@@ -338,7 +527,7 @@ function proceedToExpress() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: rgba(26, 15, 10, 0.85);
|
||||
background: rgba(26, 15, 10, 0.88);
|
||||
border: 1.5px solid #ffd700;
|
||||
border-radius: 16px;
|
||||
padding: 2px 6px 2px 2px;
|
||||
@@ -363,8 +552,8 @@ function proceedToExpress() {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.mirror-icon {
|
||||
font-size: 16px;
|
||||
.mirror-icon, .door-icon {
|
||||
font-size: 15px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
@@ -375,15 +564,164 @@ function proceedToExpress() {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.hotspot-verena { top: 15%; left: 80%; }
|
||||
/* Door Hotspots */
|
||||
.door-hotspot {
|
||||
background: rgba(15, 23, 42, 0.9);
|
||||
border: 1.5px solid #38bdf8;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.glow-door {
|
||||
color: #38bdf8;
|
||||
}
|
||||
|
||||
/* Secret Tap Easter Egg */
|
||||
.secret-tap-hotspot {
|
||||
position: absolute;
|
||||
top: 73%;
|
||||
left: 88%;
|
||||
background: rgba(234, 179, 8, 0.2);
|
||||
border: 1.5px dashed #ffd700;
|
||||
border-radius: 12px;
|
||||
padding: 3px 6px;
|
||||
cursor: pointer;
|
||||
z-index: 12;
|
||||
}
|
||||
|
||||
.secret-tap-icon {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.secret-badge {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 5.5px;
|
||||
color: #fef08a;
|
||||
}
|
||||
|
||||
/* 1. Schankraum Hotspots */
|
||||
.hotspot-verena { top: 16%; left: 78%; }
|
||||
.hotspot-armend { top: 62%; left: 24%; }
|
||||
.hotspot-lutz { top: 38%; left: 20%; }
|
||||
.hotspot-amy { top: 52%; left: 80%; }
|
||||
.hotspot-mirror { top: 32%; left: 63%; }
|
||||
.hotspot-amy { top: 52%; left: 82%; }
|
||||
.hotspot-pue { top: 20%; left: 35%; }
|
||||
.hotspot-mane { top: 45%; left: 66%; }
|
||||
.hotspot-nat { top: 63%; left: 85%; }
|
||||
.hotspot-mario { top: 36%; left: 90%; }
|
||||
.hotspot-door-marktplatz { top: 56%; left: 90%; }
|
||||
|
||||
/* 2. Marktplatz Hotspots */
|
||||
.mario-container {
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
left: 34%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.hotspot-mario {
|
||||
position: relative;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.chainsaw-circus {
|
||||
position: absolute;
|
||||
top: -24px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 50px;
|
||||
height: 24px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.saw {
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
animation: spinSaw 0.3s infinite linear;
|
||||
}
|
||||
|
||||
.saw-left {
|
||||
left: -4px;
|
||||
animation-direction: normal;
|
||||
}
|
||||
|
||||
.saw-right {
|
||||
right: -4px;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
|
||||
.spark {
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
animation: sparkFlicker 0.2s infinite alternate;
|
||||
}
|
||||
|
||||
.spark-1 { top: -6px; left: 10px; color: #f59e0b; }
|
||||
.spark-2 { top: 4px; right: 10px; color: #ef4444; }
|
||||
|
||||
@keyframes spinSaw {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes sparkFlicker {
|
||||
0% { opacity: 0.2; transform: scale(0.8); }
|
||||
100% { opacity: 1; transform: scale(1.3); }
|
||||
}
|
||||
|
||||
.hotspot-nat { top: 62%; left: 74%; }
|
||||
.hotspot-door-back-gaststube { top: 72%; left: 16%; }
|
||||
.hotspot-door-hinterland { top: 36%; left: 84%; }
|
||||
|
||||
/* 3. Hinterland Hotspots */
|
||||
.hotspot-mane { top: 50%; left: 42%; }
|
||||
.hiking-anim {
|
||||
animation: hikeBob 1.2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes hikeBob {
|
||||
0%, 100% { transform: translate(-50%, -50%) translateY(0); }
|
||||
50% { transform: translate(-50%, -50%) translateY(-6px) rotate(-2deg); }
|
||||
}
|
||||
|
||||
.hiking-stick {
|
||||
font-size: 12px;
|
||||
transform: rotate(20deg);
|
||||
}
|
||||
|
||||
.hotspot-hansi { top: 66%; left: 78%; }
|
||||
.hotspot-door-back-marktplatz { top: 74%; left: 20%; }
|
||||
|
||||
/* 4. Hinterzimmer Hotspots & Strobe */
|
||||
.strobe-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
mix-blend-mode: overlay;
|
||||
animation: discoFlash 0.6s infinite alternate;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
@keyframes discoFlash {
|
||||
0% { background: rgba(236, 72, 153, 0.25); }
|
||||
33% { background: rgba(59, 130, 246, 0.25); }
|
||||
66% { background: rgba(234, 179, 8, 0.25); }
|
||||
100% { background: rgba(168, 85, 247, 0.25); }
|
||||
}
|
||||
|
||||
.hotspot-pue { top: 46%; left: 48%; }
|
||||
.rave-pulse {
|
||||
animation: raveGlow 1s infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes raveGlow {
|
||||
0% { box-shadow: 0 0 4px #eab308; }
|
||||
100% { box-shadow: 0 0 16px #ec4899; }
|
||||
}
|
||||
|
||||
.crystal-laser {
|
||||
font-size: 13px;
|
||||
animation: pulseAnim 0.8s infinite;
|
||||
}
|
||||
|
||||
.hotspot-flo { top: 40%; left: 22%; }
|
||||
.hotspot-viktor { top: 62%; left: 78%; }
|
||||
.hotspot-door-back-vip { top: 78%; left: 50%; }
|
||||
|
||||
.pulse {
|
||||
animation: pulseAnim 1.5s infinite;
|
||||
@@ -394,12 +732,13 @@ function proceedToExpress() {
|
||||
50% { box-shadow: 0 0 12px #ec4899; }
|
||||
}
|
||||
|
||||
/* Bottom Navigation */
|
||||
.scene-bottom-nav {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 84px;
|
||||
height: 94px;
|
||||
background: linear-gradient(180deg, #451a03 0%, #26140b 100%);
|
||||
border-top: 3px solid #b45309;
|
||||
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.95);
|
||||
@@ -407,20 +746,53 @@ function proceedToExpress() {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
gap: 5px;
|
||||
padding: 6px 10px;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.tavern-bar-title {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 7px;
|
||||
font-size: 6.5px;
|
||||
color: #fef08a;
|
||||
text-shadow: 1px 1px 0 #000;
|
||||
letter-spacing: 0.5px;
|
||||
letter-spacing: 0.3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.room-nav-tabs {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.room-tab {
|
||||
background: #2b1810;
|
||||
border: 1px solid #78350f;
|
||||
color: #cbd5e1;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 6px;
|
||||
padding: 4px 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.room-tab.active {
|
||||
background: #b45309;
|
||||
border-color: #ffd700;
|
||||
color: #fff;
|
||||
box-shadow: 0 0 6px rgba(255, 215, 0, 0.4);
|
||||
}
|
||||
|
||||
.vip-tab {
|
||||
background: #3b0764;
|
||||
border-color: #a855f7;
|
||||
color: #f0abfc;
|
||||
animation: pulseAnim 1.5s infinite;
|
||||
}
|
||||
|
||||
.tavern-nav-buttons {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
@@ -435,8 +807,8 @@ function proceedToExpress() {
|
||||
border: 1.5px solid #ffd700;
|
||||
border-radius: 6px;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 7.5px;
|
||||
padding: 8px 10px;
|
||||
font-size: 7px;
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.6);
|
||||
}
|
||||
@@ -447,8 +819,8 @@ function proceedToExpress() {
|
||||
border: 1.5px solid #86efac;
|
||||
border-radius: 6px;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 7.5px;
|
||||
padding: 8px 10px;
|
||||
font-size: 7px;
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.6);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user