Skip to content

Commit c5c52bf

Browse files
committed
refactor: dnd pages pt7
1 parent 3173d97 commit c5c52bf

File tree

3 files changed

+136
-10
lines changed

3 files changed

+136
-10
lines changed

src/components/dnd/DndLayout.js

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,55 @@ import DndFooter from './DndFooter';
66
import dndWallpapers from '../../utils/dndWallpapers';
77
import { parseWallpaperName } from '../../utils/dndUtils';
88
import '../../styles/dnd-refactor.css';
9-
import { GameController, Flame } from '@phosphor-icons/react';
9+
import { GameController, Flame, TreasureChest } from '@phosphor-icons/react';
10+
import { useToast } from '../../hooks/useToast';
11+
12+
const Lightning = () => (
13+
<div className="dnd-lightning-overlay" />
14+
);
15+
16+
const LootDiscovery = () => {
17+
const { addToast } = useToast();
18+
const [showLoot, setShowLoot] = useState(false);
19+
const [lootPos, setLootPos] = useState({ top: '50%', left: '50%' });
20+
21+
useEffect(() => {
22+
const interval = setInterval(() => {
23+
// 50% chance every 15 seconds
24+
if (Math.random() > 0.5) {
25+
setLootPos({
26+
top: `${30 + Math.random() * 40}%`,
27+
left: `${20 + Math.random() * 60}%`,
28+
});
29+
setShowLoot(true);
30+
setTimeout(() => setShowLoot(false), 8000); // Hide after 8s
31+
}
32+
}, 15000);
33+
return () => clearInterval(interval);
34+
}, []);
35+
36+
if (!showLoot) return null;
37+
38+
return (
39+
<motion.div
40+
initial={{ opacity: 0, scale: 0 }}
41+
animate={{ opacity: 1, scale: 1 }}
42+
exit={{ opacity: 0, scale: 0 }}
43+
onClick={() => {
44+
addToast({
45+
title: 'Loot Discovered!',
46+
message: 'You found an ancient relic in the archives.',
47+
type: 'gold',
48+
});
49+
setShowLoot(false);
50+
}}
51+
className="fixed z-[150] dnd-loot-item text-dnd-gold"
52+
style={{ top: lootPos.top, left: lootPos.left }}
53+
>
54+
<TreasureChest size={32} weight="fill" />
55+
</motion.div>
56+
);
57+
};
1058

1159
const FireplaceAudio = () => {
1260
const [isPlaying, setIsPlaying] = useState(false);
@@ -184,7 +232,7 @@ const DiceRoller = () => {
184232
)}
185233
<button
186234
onClick={rollDice}
187-
className={`p-4 bg-dnd-crimson border-2 border-dnd-gold rounded-full text-dnd-gold shadow-2xl transition-all hover:scale-110 active:scale-95 ${isRolling ? 'dnd-dice-action' : ''}`}
235+
className={`p-4 bg-dnd-crimson border-2 border-dnd-gold rounded-full text-white/50 shadow-2xl transition-all hover:scale-110 active:scale-95 ${isRolling ? 'dnd-dice-action' : ''}`}
188236
>
189237
<GameController size={32} weight="fill" />
190238
</button>
@@ -205,6 +253,8 @@ const DndLayout = ({ children }) => {
205253
return (
206254
<div className="dnd-theme-root min-h-screen flex flex-col relative overflow-x-hidden">
207255
<ViewportFrame />
256+
<Lightning />
257+
<LootDiscovery />
208258
<FireplaceAudio />
209259
<FireOverlay />
210260
<Torchlight />

src/pages/dnd/DndEpisodePage.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,17 @@ function DndEpisodePage() {
168168

169169
>
170170

171-
<div className="dnd-stat-block shadow-2xl lg:sticky lg:top-40 group">
171+
<div className="dnd-stat-block shadow-2xl lg:sticky lg:top-40 group">
172172

173-
<div className="dnd-stat-block-header">
173+
{/* Hidden message in sidebar */}
174+
175+
<div className="absolute -bottom-8 left-0 w-full text-center opacity-0 group-hover:opacity-100 transition-opacity duration-1000">
176+
177+
<span className="dnd-secret-text text-[8px] uppercase tracking-[0.2em]">Don't believe the scribes</span>
178+
179+
</div>
180+
181+
<div className="dnd-stat-block-header">
174182

175183
{currentEpisode.author}
176184

@@ -248,17 +256,31 @@ function DndEpisodePage() {
248256

249257
</motion.aside>
250258

251-
<motion.div
259+
<motion.div
260+
261+
initial={{ opacity: 0, y: 30 }}
262+
263+
animate={{ opacity: 1, y: 0 }}
264+
265+
className="lg:col-span-4 dnd-parchment-container p-8 md:p-24 shadow-2xl border-2 border-black/10 min-h-[60vh] flex flex-col relative dnd-parchment-glow"
266+
267+
>
268+
269+
{/* Secret Inscriptions */}
270+
271+
<div className="absolute top-1/4 -left-4 -rotate-90 pointer-events-none">
272+
273+
<span className="dnd-secret-text text-[10px] uppercase tracking-[1em]">The walls have eyes</span>
252274

253-
initial={{ opacity: 0, y: 30 }}
275+
</div>
254276

255-
animate={{ opacity: 1, y: 0 }}
277+
<div className="absolute bottom-1/4 -right-4 rotate-90 pointer-events-none">
256278

257-
className="lg:col-span-4 dnd-parchment-container p-8 md:p-24 shadow-2xl border-2 border-black/10 min-h-[60vh] flex flex-col relative dnd-parchment-glow"
279+
<span className="dnd-secret-text text-[10px] uppercase tracking-[1em]">History is written by survivors</span>
258280

259-
>
281+
</div>
260282

261-
{/* Scroll Ornaments */}
283+
{/* Scroll Ornaments */}
262284

263285
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-64 h-8 bg-dnd-crimson/5 rounded-b-full blur-xl dnd-scroll-accent" />
264286

src/styles/dnd-refactor.css

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,60 @@
279279
0 40px 80px rgba(0,0,0,0.7);
280280
}
281281

282+
/* Arcane Lightning Flash */
283+
@keyframes dnd-lightning {
284+
0%, 95%, 100% { opacity: 0; }
285+
96% { opacity: 0.2; }
286+
97% { opacity: 0.05; }
287+
98% { opacity: 0.4; }
288+
}
289+
290+
.dnd-lightning-overlay {
291+
position: fixed;
292+
inset: 0;
293+
background: white;
294+
pointer-events: none;
295+
z-index: 50;
296+
opacity: 0;
297+
mix-blend-mode: overlay;
298+
animation: dnd-lightning 7s infinite;
299+
}
300+
301+
/* Secret Inscriptions - More visible */
302+
.dnd-secret-text {
303+
font-family: 'MedievalSharp', cursive;
304+
color: var(--dnd-crimson);
305+
opacity: 0.15;
306+
filter: blur(1px);
307+
transition: all 0.5s ease;
308+
user-select: none;
309+
font-weight: bold;
310+
}
311+
312+
.dnd-parchment-container:hover .dnd-secret-text {
313+
opacity: 0.4;
314+
color: var(--dnd-gold);
315+
filter: blur(0px);
316+
text-shadow: 0 0 10px var(--dnd-gold);
317+
}
318+
319+
/* Gold Coin / Loot Styling */
320+
@keyframes loot-shine {
321+
0% { filter: brightness(1); }
322+
50% { filter: brightness(1.5) drop-shadow(0 0 10px gold); }
323+
100% { filter: brightness(1); }
324+
}
325+
326+
.dnd-loot-item {
327+
cursor: pointer;
328+
animation: loot-shine 2s infinite ease-in-out;
329+
transition: all 0.3s ease;
330+
}
331+
332+
.dnd-loot-item:hover {
333+
transform: scale(1.5) rotate(15deg);
334+
}
335+
282336
/* Silk Ribbon Style */
283337
.dnd-ribbon {
284338
position: absolute;

0 commit comments

Comments
 (0)