8afb112eee
- SiteLayout.tsx: shared layout component with nav dropdown, mobile hamburger drawer, full footer - Nav: World dropdown menu (Lore, World, Characters, Music, Gallery) + Follow link - Footer: 3-column (World links, Social links, Legal links) + tagline - pages/lore.tsx: lore entry grid with placeholder canon entries - pages/world.tsx: location/setting cards with worldbuilding teaser - pages/characters.tsx: character roster with locked/revealed states - pages/music.tsx: soundtrack page with Patreon CTA (inspired by silmaai.com music page) - pages/gallery.tsx: tabbed Official / Fan Art gallery with empty states and social tag CTAs - styles/Layout.module.css: shared nav, dropdown, footer, page hero, coming-soon styles - styles/World.module.css: lore, location, character, music styles - styles/Gallery.module.css: tabs, grid, card, empty state styles - All pages: SEO meta, canonical URLs, OG tags
137 lines
5.1 KiB
TypeScript
137 lines
5.1 KiB
TypeScript
import { useState } from "react";
|
|
import SiteLayout from "./components/SiteLayout";
|
|
import layoutStyles from "@/styles/Layout.module.css";
|
|
import styles from "@/styles/Gallery.module.css";
|
|
|
|
type GalleryTab = "official" | "fan";
|
|
|
|
// Placeholder art items — swap src for real image paths when assets are ready
|
|
const OFFICIAL_ART: { src: string; alt: string; caption?: string }[] = [
|
|
// { src: "/gallery/official/blb-key-art.jpg", alt: "Bone Lord Bob key art", caption: "Key Art — Season 1" },
|
|
];
|
|
|
|
const FAN_ART: { src: string; alt: string; artist?: string; artistUrl?: string }[] = [
|
|
// { src: "/gallery/fan/fan-art-1.jpg", alt: "Fan art by ...", artist: "Artist Name", artistUrl: "https://..." },
|
|
];
|
|
|
|
export default function Gallery() {
|
|
const [tab, setTab] = useState<GalleryTab>("official");
|
|
|
|
return (
|
|
<SiteLayout
|
|
title="Gallery"
|
|
description="Official art and fan creations from the world of Bone Lord Bob."
|
|
keywords="Bone Lord Bob art, BLB gallery, fan art, official art, anime art, dark fantasy art"
|
|
canonical="/gallery"
|
|
>
|
|
{/* Hero */}
|
|
<div className={layoutStyles.pageHero}>
|
|
<span className={layoutStyles.pageEyebrow}>Art of the Bone Kingdom</span>
|
|
<h1 className={layoutStyles.pageTitle}>Gallery</h1>
|
|
<p className={layoutStyles.pageSub}>
|
|
Official art from the series — and the community that's building around it.
|
|
</p>
|
|
</div>
|
|
|
|
<div className={layoutStyles.pageContent}>
|
|
{/* Tab switcher */}
|
|
<div className={styles.tabs}>
|
|
<button
|
|
className={`${styles.tab} ${tab === "official" ? styles.tabActive : ""}`}
|
|
onClick={() => setTab("official")}
|
|
>
|
|
Official Art
|
|
</button>
|
|
<button
|
|
className={`${styles.tab} ${tab === "fan" ? styles.tabActive : ""}`}
|
|
onClick={() => setTab("fan")}
|
|
>
|
|
Fan Art
|
|
</button>
|
|
</div>
|
|
|
|
{/* Official art */}
|
|
{tab === "official" && (
|
|
<div className={styles.section}>
|
|
{OFFICIAL_ART.length > 0 ? (
|
|
<div className={styles.grid}>
|
|
{OFFICIAL_ART.map((item, i) => (
|
|
<div key={i} className={styles.card}>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img src={item.src} alt={item.alt} className={styles.cardImg} loading="lazy" />
|
|
{item.caption && <p className={styles.cardCaption}>{item.caption}</p>}
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className={styles.empty}>
|
|
<span className={styles.emptyIcon}>🎨</span>
|
|
<p className={styles.emptyTitle}>Official art gallery coming soon</p>
|
|
<p className={styles.emptyText}>
|
|
Character sheets, key art, and episode stills will live here.
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Fan art */}
|
|
{tab === "fan" && (
|
|
<div className={styles.section}>
|
|
{FAN_ART.length > 0 ? (
|
|
<div className={styles.grid}>
|
|
{FAN_ART.map((item, i) => (
|
|
<div key={i} className={styles.card}>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img src={item.src} alt={item.alt} className={styles.cardImg} loading="lazy" />
|
|
{item.artist && (
|
|
<p className={styles.cardCaption}>
|
|
Art by{" "}
|
|
{item.artistUrl ? (
|
|
<a href={item.artistUrl} target="_blank" rel="noopener noreferrer">
|
|
{item.artist}
|
|
</a>
|
|
) : (
|
|
item.artist
|
|
)}
|
|
</p>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className={styles.empty}>
|
|
<span className={styles.emptyIcon}>💀</span>
|
|
<p className={styles.emptyTitle}>Fan art gallery — coming soon</p>
|
|
<p className={styles.emptyText}>
|
|
Create something. Tag us on social with{" "}
|
|
<strong style={{ color: "var(--bone)" }}>#BoneLordBob</strong> and we'll feature
|
|
it here.
|
|
</p>
|
|
<div className={styles.emptyLinks}>
|
|
<a
|
|
href="https://x.com/bonelordbob"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className={styles.emptyBtn}
|
|
>
|
|
Tag us on X
|
|
</a>
|
|
<a
|
|
href="https://www.instagram.com/bonelordbob"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className={styles.emptyBtn}
|
|
>
|
|
Tag us on Instagram
|
|
</a>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</SiteLayout>
|
|
);
|
|
}
|