Skip to content

Commit d9c2a57

Browse files
committed
refactor: dnd pages pt3
1 parent d2daeae commit d9c2a57

File tree

4 files changed

+140
-44
lines changed

4 files changed

+140
-44
lines changed

public/stories/the-reflections/en/the-case-of-the-mirror-man.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ bourbon on my desk said "**Old Grand-Dad**." **Both were liars**. I hadn't inves
55
lately, and there was nothing grand about my life.
66

77
The call came from a public phone just before midnight. _Some rookie cop_, his voice trembling like a
8-
leaf in a hurricane. A **John Doe**, face-down in an alley off 4th street. **_My beat. My problem.**_
8+
leaf in a hurricane. A **John Doe**, face-down in an alley off 4th street. **My beat. My problem.**
99

1010
When the coroner, a stooped old man with spectacles thick as ale bottles, rolled the body over, the
1111
city's hum faded. The face staring up at the smog-choked sky was my own. Same busted nose from that

src/components/dnd/DndLayout.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,46 @@ import dndWallpapers from '../../utils/dndWallpapers';
66
import { parseWallpaperName } from '../../utils/dndUtils';
77
import '../../styles/dnd-refactor.css';
88

9+
const DustMotes = () => (
10+
<div className="fixed inset-0 pointer-events-none z-10 overflow-hidden">
11+
{[...Array(20)].map((_, i) => (
12+
<div
13+
key={i}
14+
className="dnd-dust-particle"
15+
style={{
16+
left: `${Math.random() * 100}%`,
17+
top: `${100 + Math.random() * 20}%`,
18+
animationDuration: `${10 + Math.random() * 20}s`,
19+
animationDelay: `${-Math.random() * 20}s`,
20+
width: `${1 + Math.random() * 2}px`,
21+
height: `${1 + Math.random() * 2}px`,
22+
}}
23+
/>
24+
))}
25+
</div>
26+
);
27+
28+
const FloatingRunes = () => {
29+
const runes = ['ᚠ', 'ᚢ', 'ᚦ', 'ᚨ', 'ᚱ', 'ᚲ', 'ᚷ', 'ᚹ', 'ᚺ', 'ᚾ', 'ᛁ', 'ᛃ', 'ᛈ', 'ᛇ', 'ᛉ', 'ᛊ', 'ᛏ', 'ᛒ', 'ᛖ', 'ᛗ', 'ᛚ', 'ᛜ', 'ᛞ', 'ᛟ'];
30+
return (
31+
<div className="fixed inset-0 pointer-events-none z-0 overflow-hidden">
32+
{[...Array(15)].map((_, i) => (
33+
<div
34+
key={i}
35+
className="dnd-floating-rune text-4xl"
36+
style={{
37+
left: `${Math.random() * 100}%`,
38+
top: `${Math.random() * 100}%`,
39+
transform: `rotate(${Math.random() * 360}deg)`,
40+
}}
41+
>
42+
{runes[Math.floor(Math.random() * runes.length)]}
43+
</div>
44+
))}
45+
</div>
46+
);
47+
};
48+
949
const DndLayout = ({ children }) => {
1050
const { setBgImageName } = useContext(DndContext);
1151
const [bgImage, setBgImage] = useState('');
@@ -18,6 +58,8 @@ const DndLayout = ({ children }) => {
1858

1959
return (
2060
<div className="dnd-theme-root min-h-screen flex flex-col relative overflow-x-hidden">
61+
<DustMotes />
62+
<FloatingRunes />
2163
{/* Immersive Background */}
2264
<div className="fixed inset-0 z-0">
2365
<div

src/pages/dnd/DndEpisodePage.js

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import rehypeRaw from 'rehype-raw';
1010
import { Scroll, CaretLeft, CaretRight, List, ShieldCheck } from '@phosphor-icons/react';
1111

1212
const WaxSeal = ({ text = 'FC' }) => (
13-
<div className="dnd-wax-seal group-hover:scale-110 transition-transform duration-500">
13+
<div className="dnd-wax-seal group-hover:scale-110 dnd-magical-pulse transition-transform duration-500">
1414
<span className="dnd-wax-seal-inner">{text}</span>
1515
</div>
1616
);
@@ -154,21 +154,21 @@ function DndEpisodePage() {
154154

155155
</header>
156156

157-
{book && currentEpisode && (
157+
{book && currentEpisode && (
158158

159-
<div className="grid grid-cols-1 lg:grid-cols-5 gap-12 mb-12">
159+
<div className="grid grid-cols-1 lg:grid-cols-5 gap-12 mb-12">
160160

161-
<motion.aside
161+
<motion.aside
162162

163-
initial={{ opacity: 0, x: -20 }}
163+
initial={{ opacity: 0, x: -20 }}
164164

165-
animate={{ opacity: 1, x: 0 }}
165+
animate={{ opacity: 1, x: 0 }}
166166

167-
className="lg:col-span-1"
167+
className="lg:col-span-1"
168168

169-
>
169+
>
170170

171-
<div className="dnd-parchment-container p-6 shadow-xl sticky top-40 border-2 border-black/10 group">
171+
<div className="dnd-parchment-container p-6 shadow-xl lg:sticky lg:top-40 border-2 border-black/10 group">
172172

173173
{/* Small Ornate Corners for Sidebar */}
174174

@@ -284,73 +284,85 @@ function DndEpisodePage() {
284284

285285
)}
286286

287-
<div className="flex flex-col md:flex-row items-stretch justify-between gap-8 pt-12 border-t border-white/10">
287+
<div className="flex flex-col md:flex-row items-stretch justify-between gap-8 pt-12 border-t border-white/10">
288+
289+
<div className="w-full md:w-1/3 flex">
290+
291+
{prevEpisode && (
292+
293+
<Link
294+
295+
to={`/stories/books/${bookId}/pages/${prevEpisode.id}`}
296+
297+
className="group relative flex items-center gap-4 p-6 dnd-parchment-container border-2 border-black/10 hover:border-dnd-gold/50 transition-all shadow-xl hover:-translate-y-1 w-full overflow-hidden"
298+
299+
>
288300

289-
<div className="w-full md:w-1/3 flex">
301+
<div className="absolute top-0 left-0 w-4 h-4 border-t border-l border-dnd-gold opacity-40 group-hover:opacity-100" />
290302

291-
{prevEpisode && (
303+
<div className="absolute bottom-0 right-0 w-4 h-4 border-b border-r border-dnd-gold opacity-40 group-hover:opacity-100" />
292304

293-
<Link
305+
<CaretLeft size={24} weight="bold" className="text-dnd-crimson group-hover:scale-125 transition-transform" />
294306

295-
to={`/stories/books/${bookId}/pages/${prevEpisode.id}`}
307+
<div className="flex flex-col text-left relative z-10">
296308

297-
className="group flex items-center gap-4 px-6 py-4 bg-white text-black hover:bg-dnd-gold hover:text-primary-600 transition-all shadow-[0_10px_30px_rgba(0,0,0,0.5)] hover:-translate-y-1 rounded-sm w-full"
309+
<span className="text-[8px] font-mono uppercase tracking-widest text-black/40">Prior Entry</span>
298310

299-
>
311+
<span className="text-sm font-arvo font-bold text-dnd-crimson line-clamp-1">{prevEpisode.title}</span>
300312

301-
<CaretLeft size={20} weight="bold" />
313+
</div>
302314

303-
<div className="flex flex-col text-left">
315+
</Link>
304316

305-
<span className="text-[8px] font-mono uppercase tracking-widest opacity-60">Prior Entry</span>
317+
)}
306318

307-
<span className="text-sm font-arvo font-bold line-clamp-1">{prevEpisode.title}</span>
319+
</div>
308320

309-
</div>
321+
<Link to="/stories/lore" className="group relative flex items-center justify-center gap-3 px-10 py-5 dnd-parchment-container border-2 border-black/10 hover:border-dnd-gold/50 transition-all shadow-xl hover:-translate-y-1 min-w-[240px] overflow-hidden">
310322

311-
</Link>
323+
<div className="absolute top-0 left-0 w-4 h-4 border-t border-l border-dnd-gold opacity-40 group-hover:opacity-100" />
312324

313-
)}
325+
<div className="absolute bottom-0 right-0 w-4 h-4 border-b border-r border-dnd-gold opacity-40 group-hover:opacity-100" />
314326

315-
</div>
327+
<List size={20} weight="bold" className="text-dnd-crimson" />
316328

317-
<Link to="/stories/lore" className="group flex items-center justify-center gap-3 px-10 py-5 bg-white text-black font-mono font-black text-xs tracking-[0.4em] hover:bg-dnd-gold hover:text-primary-600 transition-all shadow-[0_10px_30px_rgba(0,0,0,0.5)] hover:-translate-y-1 rounded-sm min-w-[200px]">
329+
<span className="font-mono font-black text-xs tracking-[0.4em] text-dnd-crimson">Show Index</span>
318330

319-
<List size={18} weight="bold" />
331+
</Link>
320332

321-
Show Index
333+
<div className="w-full md:w-1/3 flex justify-end">
322334

323-
</Link>
335+
{nextEpisode && (
324336

325-
<div className="w-full md:w-1/3 flex justify-end">
337+
<Link
326338

327-
{nextEpisode && (
339+
to={`/stories/books/${bookId}/pages/${nextEpisode.id}`}
328340

329-
<Link
341+
className="group relative flex items-center justify-between gap-4 p-6 dnd-parchment-container border-2 border-black/10 hover:border-dnd-gold/50 transition-all shadow-xl hover:-translate-y-1 w-full overflow-hidden"
330342

331-
to={`/stories/books/${bookId}/pages/${nextEpisode.id}`}
343+
>
332344

333-
className="group flex items-center justify-between gap-4 px-6 py-4 bg-white text-black hover:bg-dnd-gold hover:text-primary-600 transition-all shadow-[0_10px_30px_rgba(0,0,0,0.5)] hover:-translate-y-1 rounded-sm w-full"
345+
<div className="absolute top-0 right-0 w-4 h-4 border-t border-r border-dnd-gold opacity-40 group-hover:opacity-100" />
334346

335-
>
347+
<div className="absolute bottom-0 left-0 w-4 h-4 border-b border-l border-dnd-gold opacity-40 group-hover:opacity-100" />
336348

337-
<div className="flex flex-col text-right flex-grow">
349+
<div className="flex flex-col text-right flex-grow relative z-10">
338350

339-
<span className="text-[8px] font-mono uppercase tracking-widest opacity-60">Next Entry</span>
351+
<span className="text-[8px] font-mono uppercase tracking-widest text-black/40">Next Entry</span>
340352

341-
<span className="text-sm font-arvo font-bold line-clamp-1">{nextEpisode.title}</span>
353+
<span className="text-sm font-arvo font-bold text-dnd-crimson line-clamp-1">{nextEpisode.title}</span>
342354

343-
</div>
355+
</div>
344356

345-
<CaretRight size={20} weight="bold" />
357+
<CaretRight size={24} weight="bold" className="text-dnd-crimson group-hover:scale-125 transition-transform" />
346358

347-
</Link>
359+
</Link>
348360

349-
)}
361+
)}
350362

351-
</div>
363+
</div>
352364

353-
</div> </div>
365+
</div> </div>
354366
</DndLayout>
355367
);
356368
}

src/styles/dnd-refactor.css

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,45 @@
200200
font-size: 2.2rem;
201201
text-shadow: 2px 2px 4px rgba(0,0,0,0.6);
202202
}
203+
204+
/* Dust Motes Animation */
205+
@keyframes dnd-dust {
206+
0% { transform: translateY(0) translateX(0); opacity: 0; }
207+
20% { opacity: 0.2; }
208+
80% { opacity: 0.2; }
209+
100% { transform: translateY(-100vh) translateX(20px); opacity: 0; }
210+
}
211+
212+
.dnd-dust-particle {
213+
position: fixed;
214+
width: 2px;
215+
height: 2px;
216+
background: white;
217+
border-radius: 50%;
218+
pointer-events: none;
219+
z-index: 5;
220+
animation: dnd-dust linear infinite;
221+
}
222+
223+
/* Magical Aura/Pulse */
224+
@keyframes dnd-aura {
225+
0% { box-shadow: 0 0 0px rgba(212, 175, 55, 0); }
226+
50% { box-shadow: 0 0 20px rgba(212, 175, 55, 0.4); }
227+
100% { box-shadow: 0 0 0px rgba(212, 175, 55, 0); }
228+
}
229+
230+
.dnd-magical-pulse {
231+
animation: dnd-aura 3s infinite ease-in-out;
232+
}
233+
234+
/* Floating Rune Style */
235+
.dnd-floating-rune {
236+
position: fixed;
237+
font-family: 'MedievalSharp', cursive;
238+
color: var(--dnd-gold);
239+
opacity: 0.03;
240+
pointer-events: none;
241+
z-index: 1;
242+
user-select: none;
243+
filter: blur(1px);
244+
}

0 commit comments

Comments
 (0)