Add Player Menu with Inventory drawer, house selection, and mobile-first header

This commit is contained in:
Maxi
2026-09-22 19:02:07 +02:00
parent c5c0bad3e6
commit 9f5e5085ec
9 changed files with 1076 additions and 182 deletions
+529 -125
View File
@@ -1,6 +1,6 @@
:root {
--bg-dark: #0d0c13;
--bg-card: rgba(26, 24, 38, 0.92);
--bg-card: rgba(26, 24, 38, 0.94);
--gold: #e5b948;
--gold-glow: rgba(229, 185, 72, 0.4);
--gold-hover: #f7d274;
@@ -15,6 +15,7 @@
--wine-red: #9e2a2b;
--text-light: #ece8e1;
--text-dim: #a59fa8;
--house-accent: #d3a625;
--font-gothic: 'MedievalSharp', cursive, serif;
--font-script: 'Caveat', cursive, sans-serif;
}
@@ -39,7 +40,7 @@ body {
flex-direction: column;
}
/* Site Header */
/* Site Header (Sleek & Mobile First) */
.site-header {
background: rgba(13, 12, 19, 0.95);
border-bottom: 2px solid var(--gold);
@@ -53,55 +54,89 @@ body {
.header-inner {
max-width: 1200px;
margin: 0 auto;
padding: 0.75rem 1.25rem;
padding: 0.6rem 1rem;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 0.75rem;
gap: 0.5rem;
}
.brand-link {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 0.4rem;
text-decoration: none;
color: var(--gold);
font-size: 1.4rem;
font-size: 1.3rem;
text-shadow: 0 0 10px var(--gold-glow);
transition: transform 0.2s;
white-space: nowrap;
}
.brand-link:hover {
transform: scale(1.03);
.brand-sparkle {
font-size: 1.3rem;
}
.brand-title {
font-weight: bold;
}
.header-right {
display: flex;
align-items: center;
gap: 0.75rem;
gap: 0.6rem;
}
.nav-links {
/* Player Bag Button */
.btn-bag {
background: linear-gradient(135deg, #2b1f14, #4a3520);
color: var(--gold);
border: 2px solid var(--gold);
padding: 0.4rem 0.85rem;
border-radius: 20px;
cursor: pointer;
font-family: inherit;
font-size: 1rem;
font-weight: bold;
display: flex;
align-items: center;
gap: 1rem;
gap: 0.4rem;
transition: all 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
user-select: none;
}
.nav-link {
color: var(--text-light);
text-decoration: none;
font-size: 1rem;
padding: 0.35rem 0.75rem;
border-radius: 6px;
border: 1px solid transparent;
transition: all 0.2s;
.btn-bag:hover {
background: linear-gradient(135deg, #4a3520, #6e4f30);
transform: translateY(-2px) scale(1.04);
box-shadow: 0 4px 15px var(--gold-glow);
color: #fff;
}
.nav-link:hover, .nav-link.active {
color: var(--gold);
border-color: var(--gold);
background: rgba(229, 185, 72, 0.1);
.bag-house-icon {
font-size: 1.15rem;
}
.bag-label {
display: inline-block;
}
.bag-badge {
background: #e63946;
color: #fff;
font-size: 0.75rem;
padding: 0.15rem 0.45rem;
border-radius: 10px;
font-weight: bold;
border: 1px solid #ffd700;
}
.bag-badge.pulse {
animation: badgePulse 0.6s infinite alternate;
}
@keyframes badgePulse {
0% { transform: scale(1); filter: brightness(1); }
100% { transform: scale(1.3); filter: brightness(1.4) drop-shadow(0 0 8px #ff0055); }
}
/* Control Buttons */
@@ -109,15 +144,22 @@ body {
background: rgba(255, 255, 255, 0.08);
color: var(--gold);
border: 1px solid var(--gold);
padding: 0.4rem 0.8rem;
border-radius: 6px;
padding: 0.4rem 0.75rem;
border-radius: 8px;
cursor: pointer;
font-family: inherit;
font-size: 0.9rem;
font-size: 0.95rem;
display: flex;
align-items: center;
gap: 0.4rem;
transition: all 0.2s;
user-select: none;
}
.btn-control.icon-only {
padding: 0.4rem 0.55rem;
font-size: 1.1rem;
border-radius: 50%;
}
.btn-control:hover {
@@ -126,16 +168,371 @@ body {
box-shadow: 0 0 12px var(--gold-glow);
}
.lang-btn.active {
background: var(--gold);
color: var(--bg-dark);
/* Slide-Over Drawer & Backdrop */
.drawer-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.75);
backdrop-filter: blur(4px);
z-index: 2000;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.drawer-backdrop.open {
opacity: 1;
pointer-events: auto;
}
.player-drawer {
position: fixed;
top: 0;
right: 0;
width: 400px;
max-width: 92vw;
height: 100vh;
background: var(--bg-dark);
background-image:
radial-gradient(circle at 10% 10%, rgba(229, 185, 72, 0.08) 0%, transparent 40%),
url('/static/img/parchment_texture.jpg');
background-blend-mode: overlay;
border-left: 3px solid var(--gold);
box-shadow: -5px 0 35px rgba(0, 0, 0, 0.85);
z-index: 2001;
display: flex;
flex-direction: column;
transform: translateX(100%);
transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.player-drawer.open {
transform: translateX(0);
}
.drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1.1rem 1.25rem;
border-bottom: 2px solid rgba(229, 185, 72, 0.3);
background: rgba(17, 15, 25, 0.95);
}
.drawer-title {
font-size: 1.4rem;
color: var(--gold);
display: flex;
align-items: center;
gap: 0.5rem;
}
.drawer-close-btn {
background: none;
border: none;
color: var(--text-dim);
font-size: 1.5rem;
cursor: pointer;
transition: color 0.2s;
line-height: 1;
}
.drawer-close-btn:hover {
color: var(--gold);
}
.drawer-tabs {
display: flex;
border-bottom: 1px solid rgba(229, 185, 72, 0.25);
background: rgba(22, 19, 32, 0.9);
}
.drawer-tab-btn {
flex: 1;
padding: 0.75rem 0.5rem;
background: none;
border: none;
color: var(--text-dim);
font-family: inherit;
font-size: 0.95rem;
cursor: pointer;
border-bottom: 3px solid transparent;
transition: all 0.2s;
}
.drawer-tab-btn:hover {
color: var(--text-light);
background: rgba(229, 185, 72, 0.05);
}
.drawer-tab-btn.active {
color: var(--gold);
border-bottom-color: var(--gold);
font-weight: bold;
background: rgba(229, 185, 72, 0.1);
}
.drawer-body {
flex: 1;
overflow-y: auto;
padding: 1.25rem;
}
.drawer-tab-pane {
display: none;
}
.drawer-tab-pane.active {
display: block;
animation: fadeIn 0.25s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
.drawer-footer {
padding: 1rem 1.25rem;
border-top: 1px solid rgba(229, 185, 72, 0.25);
background: rgba(17, 15, 25, 0.95);
}
/* Inventory Grid (Tab 1) */
.inv-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.75rem;
margin-bottom: 1.25rem;
}
.inv-item-slot {
background: rgba(26, 23, 38, 0.85);
border: 2px solid rgba(229, 185, 72, 0.35);
border-radius: 10px;
padding: 0.85rem 0.5rem;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.2s;
user-select: none;
}
.inv-item-slot:hover {
border-color: var(--gold);
transform: translateY(-3px);
box-shadow: 0 4px 15px rgba(229, 185, 72, 0.25);
}
.inv-item-slot.selected {
border-color: var(--gold);
background: rgba(229, 185, 72, 0.15);
box-shadow: 0 0 15px var(--gold-glow);
}
.inv-item-icon {
font-size: 2.2rem;
margin-bottom: 0.35rem;
}
.inv-item-name {
font-size: 0.85rem;
text-align: center;
color: var(--text-light);
font-weight: bold;
}
/* Item Detail Card */
.inv-detail-card {
background: rgba(18, 15, 26, 0.95);
border: 2px solid var(--gold);
border-radius: 12px;
padding: 1.1rem;
text-align: center;
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.6);
}
.inv-detail-icon {
font-size: 3rem;
margin-bottom: 0.4rem;
}
.inv-detail-name {
font-size: 1.25rem;
color: var(--gold);
margin-bottom: 0.4rem;
font-weight: bold;
}
.inv-detail-desc {
color: var(--text-dim);
font-size: 0.9rem;
line-height: 1.5;
margin-bottom: 1rem;
}
/* House Picker (Tab 2) */
.house-picker-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.6rem;
margin-bottom: 1.25rem;
}
.house-select-btn {
background: rgba(22, 19, 32, 0.85);
border: 2px solid rgba(229, 185, 72, 0.3);
border-radius: 10px;
padding: 0.75rem 0.5rem;
color: var(--text-light);
font-family: inherit;
font-size: 0.95rem;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
transition: all 0.2s;
}
.house-select-btn:hover {
border-color: var(--gold);
transform: scale(1.03);
}
.house-select-btn.active {
border-color: var(--gold);
background: rgba(229, 185, 72, 0.2);
box-shadow: 0 0 12px var(--gold-glow);
font-weight: bold;
}
.house-icon {
font-size: 1.8rem;
}
.profile-stats-card {
background: rgba(20, 18, 29, 0.9);
border: 1px solid rgba(229, 185, 72, 0.3);
border-radius: 10px;
padding: 0.9rem 1rem;
}
.stat-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.45rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
font-size: 0.9rem;
}
.stat-row:last-child {
border-bottom: none;
}
/* Chambers Navigation (Tab 3) */
.rooms-nav-list {
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.room-nav-item {
display: flex;
align-items: center;
gap: 0.85rem;
padding: 0.75rem 1rem;
background: rgba(25, 22, 36, 0.85);
border: 1px solid rgba(229, 185, 72, 0.3);
border-radius: 10px;
text-decoration: none;
color: var(--text-light);
transition: all 0.2s;
}
.room-nav-item:hover, .room-nav-item.current {
border-color: var(--gold);
background: rgba(229, 185, 72, 0.15);
transform: translateX(4px);
}
.room-nav-item.external {
border-color: #ffd700;
background: rgba(212, 175, 55, 0.1);
}
.room-icon {
font-size: 1.8rem;
}
.room-info {
display: flex;
flex-direction: column;
}
.room-info strong {
font-size: 1rem;
color: var(--gold);
}
.room-info small {
font-size: 0.8rem;
color: var(--text-dim);
}
/* Floating Toast */
.escape-toast {
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%) translateY(30px);
background: rgba(18, 14, 26, 0.96);
border: 2px solid var(--gold);
border-radius: 12px;
padding: 0.8rem 1.4rem;
color: var(--text-light);
font-size: 1rem;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.8), 0 0 20px var(--gold-glow);
z-index: 9999;
opacity: 0;
pointer-events: none;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
text-align: center;
max-width: 90vw;
}
.escape-toast.show {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
/* Lumos Effect Overlay */
.lumos-light {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
z-index: 500;
background: radial-gradient(circle at 50% 50%, rgba(255, 248, 220, 0.18) 0%, transparent 60%);
opacity: 0;
transition: opacity 0.5s ease;
}
.lumos-light.active {
opacity: 1;
}
/* Container */
.container {
max-width: 1100px;
margin: 1.5rem auto 3rem auto;
margin: 1.2rem auto 2.5rem auto;
padding: 0 1rem;
flex: 1;
width: 100%;
@@ -147,26 +544,26 @@ body {
color: var(--parchment-ink);
border: 4px double var(--parchment-border);
border-radius: 12px;
padding: 2rem;
padding: 1.5rem 1.25rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7), inset 0 0 40px rgba(139, 109, 59, 0.25);
position: relative;
margin-bottom: 2rem;
margin-bottom: 1.5rem;
}
.parchment-title {
font-size: 2rem;
font-size: 1.8rem;
text-align: center;
color: #5c1818;
margin-bottom: 1rem;
margin-bottom: 0.75rem;
text-shadow: 1px 1px 0px rgba(255,255,255,0.7);
}
.riddle-poem {
font-family: var(--font-script);
font-size: 1.5rem;
line-height: 1.8;
font-size: 1.35rem;
line-height: 1.7;
text-align: center;
margin: 1.5rem 0;
margin: 1rem 0;
white-space: pre-line;
font-weight: bold;
}
@@ -178,22 +575,22 @@ body {
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
margin-bottom: 2rem;
margin-bottom: 1.5rem;
}
/* Chamber Overview Grid */
.chamber-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-top: 1.5rem;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.25rem;
margin-top: 1.25rem;
}
.chamber-card {
background: rgba(20, 18, 30, 0.9);
border: 2px solid rgba(229, 185, 72, 0.3);
border-radius: 12px;
padding: 1.5rem;
padding: 1.25rem;
display: flex;
flex-direction: column;
justify-content: space-between;
@@ -203,20 +600,20 @@ body {
}
.chamber-card:hover {
transform: translateY(-5px);
transform: translateY(-4px);
border-color: var(--gold);
box-shadow: 0 10px 30px var(--gold-glow);
}
.chamber-badge {
position: absolute;
top: 1rem;
right: 1rem;
top: 0.8rem;
right: 0.8rem;
background: rgba(229, 185, 72, 0.2);
border: 1px solid var(--gold);
color: var(--gold);
font-size: 0.8rem;
padding: 0.2rem 0.6rem;
font-size: 0.75rem;
padding: 0.2rem 0.5rem;
border-radius: 20px;
}
@@ -227,23 +624,23 @@ body {
}
.chamber-icon {
font-size: 3.5rem;
margin-bottom: 1rem;
font-size: 3rem;
margin-bottom: 0.75rem;
text-align: center;
}
.chamber-title {
font-size: 1.5rem;
font-size: 1.35rem;
color: var(--gold);
margin-bottom: 0.75rem;
margin-bottom: 0.6rem;
text-align: center;
}
.chamber-desc {
color: var(--text-dim);
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 1.25rem;
font-size: 0.9rem;
line-height: 1.5;
margin-bottom: 1rem;
text-align: center;
}
@@ -254,8 +651,8 @@ body {
color: #1a1505;
text-decoration: none;
font-weight: bold;
font-size: 1.1rem;
padding: 0.8rem 1.5rem;
font-size: 1.05rem;
padding: 0.75rem 1.25rem;
border-radius: 8px;
border: none;
cursor: pointer;
@@ -271,13 +668,13 @@ body {
color: #000;
}
/* Flaming Gates (Bottles Riddle) */
/* Flaming Gates */
.flame-chamber-arena {
position: relative;
background: radial-gradient(circle at center, #191629 0%, #0c0a14 100%);
border: 2px solid #4a3b63;
border-radius: 16px;
padding: 2rem 1.5rem;
padding: 1.5rem 1rem;
box-shadow: inset 0 0 80px rgba(0,0,0,0.9), 0 10px 40px rgba(0,0,0,0.8);
overflow: hidden;
}
@@ -285,13 +682,14 @@ body {
.flame-wall-container {
display: flex;
justify-content: space-between;
margin-bottom: 2rem;
margin-bottom: 1.5rem;
position: relative;
gap: 0.75rem;
}
.flame-gate {
width: 48%;
padding: 1.5rem 1rem;
flex: 1;
padding: 1.2rem 0.75rem;
border-radius: 12px;
text-align: center;
position: relative;
@@ -301,17 +699,17 @@ body {
.flame-gate.purple {
background: rgba(75, 15, 110, 0.35);
border: 2px solid var(--purple-fire);
box-shadow: 0 0 35px var(--purple-fire-glow);
box-shadow: 0 0 25px var(--purple-fire-glow);
}
.flame-gate.black {
background: rgba(18, 12, 28, 0.8);
border: 2px solid #5a287a;
box-shadow: 0 0 35px var(--black-fire-glow);
box-shadow: 0 0 25px var(--black-fire-glow);
}
.flame-icon-animated {
font-size: 3rem;
font-size: 2.5rem;
animation: flameFlicker 1.5s infinite alternate;
}
@@ -323,8 +721,8 @@ body {
/* 7 Bottles Table */
.bottles-table-wrapper {
margin: 2rem 0;
padding: 1.5rem 1rem;
margin: 1.5rem 0;
padding: 1.25rem 0.75rem;
background: linear-gradient(180deg, #2a201b 0%, #17110e 100%);
border: 3px solid #6b5338;
border-radius: 14px;
@@ -335,63 +733,63 @@ body {
display: flex;
justify-content: space-around;
align-items: flex-end;
gap: 0.75rem;
gap: 0.5rem;
flex-wrap: nowrap;
overflow-x: auto;
padding: 1rem 0;
padding: 0.5rem 0;
-webkit-overflow-scrolling: touch;
}
.bottle-slot {
display: flex;
flex-direction: column;
align-items: center;
min-width: 95px;
min-width: 85px;
cursor: pointer;
transition: transform 0.2s;
user-select: none;
}
.bottle-slot:hover {
transform: translateY(-8px);
transform: translateY(-6px);
}
.bottle-slot.selected {
transform: translateY(-12px);
transform: translateY(-10px);
filter: drop-shadow(0 0 15px var(--gold));
}
.bottle-pedestal {
width: 80px;
width: 75px;
height: 18px;
background: linear-gradient(180deg, #574635 0%, #2f251c 100%);
border: 2px solid #856a52;
border-radius: 6px;
margin-top: 0.5rem;
margin-top: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
font-size: 0.75rem;
color: var(--gold);
font-weight: bold;
}
/* SVG Bottles */
.bottle-svg {
filter: drop-shadow(0 8px 12px rgba(0,0,0,0.6));
filter: drop-shadow(0 6px 10px rgba(0,0,0,0.6));
transition: filter 0.3s;
}
/* Bottle tags */
.bottle-tag-select {
margin-top: 0.4rem;
margin-top: 0.35rem;
background: rgba(13, 12, 19, 0.9);
border: 1px solid var(--gold);
color: var(--text-light);
font-family: inherit;
font-size: 0.75rem;
padding: 0.2rem;
padding: 0.15rem;
border-radius: 4px;
cursor: pointer;
width: 80px;
}
/* Canvas Broom Game */
@@ -410,7 +808,7 @@ body {
#broomCanvas {
display: block;
width: 100%;
height: 520px;
height: 480px;
cursor: crosshair;
}
@@ -418,18 +816,20 @@ body {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 1.25rem;
padding: 0.6rem 1rem;
background: rgba(13, 12, 19, 0.9);
border-bottom: 2px solid var(--gold);
font-size: 1.1rem;
font-size: 1rem;
color: var(--gold);
flex-wrap: wrap;
gap: 0.5rem;
}
.mobile-controls {
display: none;
margin-top: 1rem;
justify-content: center;
gap: 1rem;
gap: 0.8rem;
}
@media (max-width: 768px) {
@@ -438,13 +838,18 @@ body {
}
.flame-wall-container {
flex-direction: column;
gap: 1rem;
}
.flame-gate {
width: 100%;
}
#broomCanvas {
height: 380px;
height: 360px;
}
.brand-title {
font-size: 1.15rem;
}
.bag-label {
display: none; /* Icon and badge only on small screens for ultra compact header */
}
.btn-bag {
padding: 0.35rem 0.6rem;
}
}
@@ -475,9 +880,9 @@ body {
background: var(--bg-card);
border: 2px solid var(--gold);
border-radius: 14px;
max-width: 550px;
max-width: 520px;
width: 100%;
padding: 2rem;
padding: 1.75rem;
text-align: center;
box-shadow: 0 0 50px var(--gold-glow);
transform: scale(0.9);
@@ -489,57 +894,38 @@ body {
}
.modal-icon {
font-size: 4rem;
margin-bottom: 1rem;
font-size: 3.5rem;
margin-bottom: 0.8rem;
}
.modal-title {
font-size: 1.8rem;
font-size: 1.6rem;
color: var(--gold);
margin-bottom: 1rem;
margin-bottom: 0.8rem;
}
.modal-text {
color: var(--text-light);
font-size: 1.1rem;
font-size: 1.05rem;
line-height: 1.6;
margin-bottom: 1.5rem;
}
/* Footer */
.footer {
background: rgba(10, 9, 15, 0.95);
border-top: 1px solid rgba(229, 185, 72, 0.3);
text-align: center;
padding: 1.5rem 1rem;
color: var(--text-dim);
font-size: 0.9rem;
}
.footer a {
color: var(--gold);
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
margin-bottom: 1.25rem;
}
/* Sliding Puzzle (Schieberätsel) */
.sliding-board-container {
max-width: 440px;
margin: 1.5rem auto;
max-width: 380px;
margin: 1.25rem auto;
background: #171421;
border: 3px solid var(--gold);
border-radius: 14px;
padding: 1.25rem;
padding: 1rem;
box-shadow: 0 0 30px rgba(0,0,0,0.8), inset 0 0 30px rgba(0,0,0,0.6);
}
.sliding-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
grid-gap: 8px;
width: 100%;
aspect-ratio: 1 / 1;
}
@@ -556,7 +942,7 @@ body {
user-select: none;
transition: transform 0.15s, background 0.2s;
box-shadow: 0 4px 8px rgba(0,0,0,0.5);
padding: 0.5rem;
padding: 0.4rem;
}
.sliding-tile:hover {
@@ -572,19 +958,37 @@ body {
}
.tile-icon {
font-size: 2.2rem;
font-size: 2rem;
}
.tile-num {
font-size: 0.85rem;
font-size: 0.8rem;
color: var(--gold);
font-weight: bold;
}
.tile-name {
font-size: 0.75rem;
font-size: 0.7rem;
color: var(--text-dim);
text-align: center;
margin-top: 2px;
}
/* Footer */
.footer {
background: rgba(10, 9, 15, 0.95);
border-top: 1px solid rgba(229, 185, 72, 0.3);
text-align: center;
padding: 1.25rem 1rem;
color: var(--text-dim);
font-size: 0.85rem;
}
.footer a {
color: var(--gold);
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
}
+4
View File
@@ -124,6 +124,9 @@
if (data.result === 'success_ahead') {
if (window.soundFX) window.soundFX.playMagicSuccess();
if (window.notifyNewItem && data.new_item) {
window.notifyNewItem(data.new_item);
}
modalIcon.innerText = "❄️⚡";
modalTitle.innerText = "Hervorragend kombiniert!";
modalTitle.style.color = "#ffd700";
@@ -133,6 +136,7 @@
modalBtn.innerText = "Zum Finale & Escape-Triumph 🏆";
modalBtn.onclick = () => { window.location.href = data.next_url; };
modalBackdrop.classList.add('show');
} else if (data.result === 'success_back') {
if (window.soundFX) window.soundFX.playMagicSuccess();
modalIcon.innerText = "🟣";
+5 -1
View File
@@ -207,11 +207,15 @@
score += 500;
if (scoreVal) scoreVal.innerText = score;
if (window.soundFX) window.soundFX.playKeyChime();
if (window.notifyNewItem) {
window.notifyNewItem({ icon: "🗝️", name: "Geknickter Silberschlüssel" });
}
if (statusMsg) {
statusMsg.innerHTML = "✨ <strong>Schlüssel gefangen!</strong> Fliege jetzt zur schweren Holztür rechts und öffne das Schloss!";
statusMsg.innerHTML = "✨ <strong>Schlüssel gefangen & im Beutel!</strong> Fliege zur Holztür rechts und öffne das Schloss!";
statusMsg.style.color = "#2ecc71";
}
}
} else {
// Master key follows player
masterKey.x = player.x + 10;
+225
View File
@@ -0,0 +1,225 @@
// Player Menu & Inventory (Zauberer-Beutel & Profil)
(function() {
const drawer = document.getElementById('playerDrawer');
const drawerBackdrop = document.getElementById('drawerBackdrop');
const bagBtn = document.getElementById('openBagBtn');
const closeBtn = document.getElementById('closeDrawerBtn');
const bagBadge = document.getElementById('bagBadge');
const bagHouseIcon = document.getElementById('bagHouseIcon');
// Tabs
const tabBtns = document.querySelectorAll('.drawer-tab-btn');
const tabPanes = document.querySelectorAll('.drawer-tab-pane');
// Item Detail Card
const itemDetailBox = document.getElementById('itemDetailBox');
const itemDetailIcon = document.getElementById('itemDetailIcon');
const itemDetailName = document.getElementById('itemDetailName');
const itemDetailDesc = document.getElementById('itemDetailDesc');
const itemDetailActionBtn = document.getElementById('itemDetailActionBtn');
// House selection buttons
const houseBtns = document.querySelectorAll('.house-select-btn');
let currentItem = null;
let lumosActive = false;
window.togglePlayerDrawer = function() {
if (!drawer) return;
const isOpen = drawer.classList.contains('open');
if (isOpen) {
closePlayerDrawer();
} else {
openPlayerDrawer();
}
};
window.openPlayerDrawer = function(tabName) {
if (!drawer) return;
drawer.classList.add('open');
if (drawerBackdrop) drawerBackdrop.classList.add('open');
document.body.style.overflow = 'hidden';
if (window.soundFX) window.soundFX.playStoneSlide();
if (tabName) switchTab(tabName);
};
window.closePlayerDrawer = function() {
if (!drawer) return;
drawer.classList.remove('open');
if (drawerBackdrop) drawerBackdrop.classList.remove('open');
document.body.style.overflow = '';
if (window.soundFX) window.soundFX.playStoneSlide();
};
if (bagBtn) bagBtn.addEventListener('click', window.togglePlayerDrawer);
if (closeBtn) closeBtn.addEventListener('click', window.closePlayerDrawer);
if (drawerBackdrop) drawerBackdrop.addEventListener('click', window.closePlayerDrawer);
window.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && drawer && drawer.classList.contains('open')) {
window.closePlayerDrawer();
}
});
// Tab Switching
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
const target = btn.dataset.tab;
switchTab(target);
});
});
function switchTab(tabId) {
tabBtns.forEach(b => b.classList.toggle('active', b.dataset.tab === tabId));
tabPanes.forEach(p => p.classList.toggle('active', p.id === tabId));
if (window.soundFX) window.soundFX.playBottleClink();
}
// Item Selection in Bag
const itemSlots = document.querySelectorAll('.inv-item-slot');
itemSlots.forEach(slot => {
slot.addEventListener('click', () => {
selectItem(slot);
});
});
function selectItem(slot) {
itemSlots.forEach(s => s.classList.remove('selected'));
slot.classList.add('selected');
const itemId = slot.dataset.itemId;
const itemName = slot.dataset.itemName;
const itemIcon = slot.dataset.itemIcon;
const itemDesc = slot.dataset.itemDesc;
const actionLabel = slot.dataset.actionLabel;
const action = slot.dataset.action;
currentItem = { id: itemId, name: itemName, icon: itemIcon, action: action };
if (itemDetailBox) {
itemDetailBox.style.display = 'block';
itemDetailIcon.innerText = itemIcon;
itemDetailName.innerText = itemName;
itemDetailDesc.innerText = itemDesc;
itemDetailActionBtn.innerText = actionLabel || "Benutzen ✨";
itemDetailActionBtn.onclick = () => performItemAction(action);
}
if (window.soundFX) window.soundFX.playBottleClink();
}
function performItemAction(action) {
if (action === 'lumos') {
lumosActive = !lumosActive;
let glow = document.getElementById('lumosLightOverlay');
if (!glow) {
glow = document.createElement('div');
glow.id = 'lumosLightOverlay';
glow.className = 'lumos-light';
document.body.appendChild(glow);
}
glow.classList.toggle('active', lumosActive);
itemDetailActionBtn.innerText = lumosActive ? "Nox / Erlöschen 🌑" : "Lumos wirken 💡";
if (window.soundFX) window.soundFX.playKeyChime();
showFloatingToast(lumosActive ? "💡 Lumos! Dein Zauberstab erleuchtet die Kammer." : "🌑 Nox! Das Zauberlicht erlischt.");
} else if (action === 'read_scroll') {
// Open scroll modal
window.closePlayerDrawer();
const modalBackdrop = document.getElementById('modalBackdrop');
const modalTitle = document.getElementById('modalTitle');
const modalText = document.getElementById('modalText');
const modalBtn = document.getElementById('modalBtn');
const modalIcon = document.getElementById('modalIcon');
if (modalBackdrop) {
modalIcon.innerText = "📜";
modalTitle.innerText = "Snapes Logik-Rätsel";
modalText.innerHTML = `
<div style="font-family: 'Caveat', cursive; font-size: 1.35rem; line-height: 1.7; text-align: left; max-height: 50vh; overflow-y: auto; padding: 0.5rem 1rem;">
<em>"Gefahr liegt vor euch, die Rettung zurück,<br>
Zwei von uns helfen euch, habt ihr das Glück,<br>
Eine von sieben führt euch hindurch,<br>
Eine bringt den, der sie trinkt, sicher zurück,<br>
Zwei von ihnen enthalten nur Brennnesselwein,<br>
Drei sind tödlich, schenkt ihr sie ein.<br>
Wählt oder bleibt auf ewig hier stehen,<br>
Vier Hinweise helfen euch, alles zu sehen..."</em><br><br>
<strong>1.</strong> Links neben jedem Wein steht immer Gift.<br>
<strong>2.</strong> Die Enden sind verschieden, keines führt nach vorn.<br>
<strong>3.</strong> Weder Zwerg noch Riese birgt Gift.<br>
<strong>4.</strong> Zweite von links & zweite von rechts schmecken gleich!
</div>
`;
modalBtn.innerText = "Verstanden ➔";
modalBtn.onclick = () => modalBackdrop.classList.remove('show');
modalBackdrop.classList.add('show');
}
} else if (action === 'broom_polish') {
if (window.soundFX) window.soundFX.playWhoosh();
showFloatingToast("🧹 Der Nimbus 2000 glänzt wie neu. Die Zweige sind perfekt gestutzt!");
} else if (action === 'examine_key') {
if (window.soundFX) window.soundFX.playKeyChime();
showFloatingToast("🗝️ Der alte Silberschlüssel ist schwer und trägt Spuren vergangener Kämpfe.");
} else if (action === 'feel_power') {
if (window.soundFX) window.soundFX.playMagicSuccess();
showFloatingToast("💎 Eine unendliche Wärme durchströmt deine Finger. Der Stein schützt die Welt!");
}
}
// House selection
houseBtns.forEach(btn => {
btn.addEventListener('click', async () => {
const house = btn.dataset.house;
try {
const res = await fetch('/api/player/house', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ house: house })
});
const data = await res.json();
if (data.success) {
houseBtns.forEach(b => b.classList.toggle('active', b.dataset.house === house));
if (bagHouseIcon) bagHouseIcon.innerText = data.house.icon;
document.documentElement.style.setProperty('--house-accent', data.house.accent);
if (window.soundFX) window.soundFX.playMagicSuccess();
showFloatingToast(`Du gehörst nun stolz zum Haus ${data.house.name} ${data.house.icon}!`);
}
} catch (e) {
console.error(e);
}
});
});
// Toast Notification
window.showFloatingToast = function(msg) {
let toast = document.getElementById('floatingEscapeToast');
if (!toast) {
toast = document.createElement('div');
toast.id = 'floatingEscapeToast';
toast.className = 'escape-toast';
document.body.appendChild(toast);
}
toast.innerHTML = msg;
toast.classList.add('show');
clearTimeout(toast._timeout);
toast._timeout = setTimeout(() => {
toast.classList.remove('show');
}, 3500);
};
window.notifyNewItem = function(item) {
if (!item) return;
if (bagBadge) {
let count = parseInt(bagBadge.innerText, 10) || 0;
bagBadge.innerText = count + 1;
bagBadge.classList.add('pulse');
setTimeout(() => bagBadge.classList.remove('pulse'), 2000);
}
if (window.soundFX) window.soundFX.playMagicSuccess();
window.showFloatingToast(`🎒 <strong>Neuer Gegenstand im Beutel:</strong> ${item.icon} ${item.name}!`);
};
// Auto-select first item if available
if (itemSlots.length > 0) {
selectItem(itemSlots[0]);
}
})();