193816f5ec
- Fix SiteLayout WORLD_LINKS to correct /world/* paths
- Add Spotify frame-src to CSP (next.config.ts)
- pages/world/characters.tsx: full character roster page (6 cards, Aaron Pressey credit)
- pages/world/gallery.tsx: tabbed Official/Fan Art gallery with coming-soon states
- pages/world/music.tsx: soundtrack page with Spotify album embed + YouTube CTA
- pages/world/lore.tsx: atmospheric lore with Bone Kingdom, Ledger, Origins/Prophecy placeholders
- pages/world/world.tsx: 3 region cards (Bone Kingdom, Bonefield, Pyre Gates)
- pages/{lore,world,characters,music,gallery}.tsx: 301 redirects to /world/* routes
- All world pages use SiteLayout, dark themed, proper SEO keywords
156 lines
4.0 KiB
TypeScript
156 lines
4.0 KiB
TypeScript
import SiteLayout from "@/pages/components/SiteLayout";
|
|
|
|
const s = {
|
|
page: {
|
|
maxWidth: "1100px",
|
|
margin: "0 auto",
|
|
padding: "64px 32px 96px",
|
|
} as React.CSSProperties,
|
|
hero: {
|
|
marginBottom: "56px",
|
|
textAlign: "center" as const,
|
|
} as React.CSSProperties,
|
|
eyebrow: {
|
|
display: "block",
|
|
fontSize: "0.75rem",
|
|
fontWeight: 700,
|
|
letterSpacing: "0.18em",
|
|
textTransform: "uppercase" as const,
|
|
color: "#c0392b",
|
|
marginBottom: "16px",
|
|
} as React.CSSProperties,
|
|
h1: {
|
|
fontFamily: "'Georgia', 'Times New Roman', serif",
|
|
fontSize: "clamp(2.4rem, 6vw, 4rem)",
|
|
fontWeight: 700,
|
|
color: "#e8dcc8",
|
|
lineHeight: 1.1,
|
|
marginBottom: "20px",
|
|
} as React.CSSProperties,
|
|
heroSub: {
|
|
fontSize: "1.05rem",
|
|
color: "#9e9080",
|
|
maxWidth: "520px",
|
|
margin: "0 auto",
|
|
lineHeight: 1.7,
|
|
} as React.CSSProperties,
|
|
grid: {
|
|
display: "grid",
|
|
gridTemplateColumns: "repeat(3, 1fr)",
|
|
gap: "20px",
|
|
marginBottom: "40px",
|
|
} as React.CSSProperties,
|
|
card: {
|
|
background: "#1a1510",
|
|
border: "1px solid rgba(232,220,200,0.12)",
|
|
borderRadius: "8px",
|
|
padding: "36px 28px",
|
|
} as React.CSSProperties,
|
|
cardEmoji: {
|
|
fontSize: "2.4rem",
|
|
display: "block",
|
|
marginBottom: "20px",
|
|
} as React.CSSProperties,
|
|
cardName: {
|
|
fontFamily: "'Georgia', 'Times New Roman', serif",
|
|
fontSize: "1.3rem",
|
|
fontWeight: 700,
|
|
color: "#e8dcc8",
|
|
marginBottom: "6px",
|
|
} as React.CSSProperties,
|
|
cardRole: {
|
|
fontSize: "0.75rem",
|
|
fontWeight: 700,
|
|
letterSpacing: "0.12em",
|
|
textTransform: "uppercase" as const,
|
|
color: "#c0392b",
|
|
marginBottom: "16px",
|
|
} as React.CSSProperties,
|
|
cardDesc: {
|
|
fontSize: "0.92rem",
|
|
color: "#9e9080",
|
|
lineHeight: 1.65,
|
|
} as React.CSSProperties,
|
|
credit: {
|
|
textAlign: "center" as const,
|
|
fontSize: "0.82rem",
|
|
color: "#9e9080",
|
|
marginTop: "8px",
|
|
letterSpacing: "0.04em",
|
|
} as React.CSSProperties,
|
|
};
|
|
|
|
const CHARACTERS = [
|
|
{
|
|
emoji: "🦴",
|
|
name: "Bone Lord Bob",
|
|
role: "The Protagonist",
|
|
desc: "A man cursed to walk between worlds — carrying the weight of the dead and the rage of the living. He answers to no one.",
|
|
},
|
|
{
|
|
emoji: "🔥",
|
|
name: "???",
|
|
role: "Coming Soon",
|
|
desc: "More characters will be revealed as the story unfolds.",
|
|
},
|
|
{
|
|
emoji: "⚔️",
|
|
name: "???",
|
|
role: "Coming Soon",
|
|
desc: "Every legend needs its foil. Every bone lord needs someone willing to break them.",
|
|
},
|
|
{
|
|
emoji: "💀",
|
|
name: "???",
|
|
role: "Coming Soon",
|
|
desc: "The dead keep their secrets. This one keeps more than most.",
|
|
},
|
|
{
|
|
emoji: "🌑",
|
|
name: "???",
|
|
role: "Coming Soon",
|
|
desc: "Some figures are felt before they are seen. This one you feel first.",
|
|
},
|
|
{
|
|
emoji: "🔮",
|
|
name: "???",
|
|
role: "Coming Soon",
|
|
desc: "Knowledge is power in the Bone Kingdom. This character has both — and charges accordingly.",
|
|
},
|
|
];
|
|
|
|
export default function Characters() {
|
|
return (
|
|
<SiteLayout
|
|
title="Characters"
|
|
description="Meet the cast of Bone Lord Bob — a dark American Anime. Warriors, ghosts, and things that defy naming."
|
|
keywords="Bone Lord Bob, characters, cast, dark fantasy, American Anime, character art, Aaron Pressey"
|
|
>
|
|
<div style={s.page}>
|
|
{/* Hero */}
|
|
<div style={s.hero}>
|
|
<span style={s.eyebrow}>Characters</span>
|
|
<h1 style={s.h1}>The Cast</h1>
|
|
<p style={s.heroSub}>
|
|
Every soul in this world has a price. Meet the ones who pay it.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Grid */}
|
|
<div style={s.grid}>
|
|
{CHARACTERS.map((c, i) => (
|
|
<div key={i} style={s.card}>
|
|
<span style={s.cardEmoji}>{c.emoji}</span>
|
|
<div style={s.cardName}>{c.name}</div>
|
|
<div style={s.cardRole}>{c.role}</div>
|
|
<p style={s.cardDesc}>{c.desc}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<p style={s.credit}>Character art by Aaron Pressey</p>
|
|
</div>
|
|
</SiteLayout>
|
|
);
|
|
}
|