diff --git a/pages/characters.tsx b/pages/characters.tsx new file mode 100644 index 0000000..c3117e9 --- /dev/null +++ b/pages/characters.tsx @@ -0,0 +1,77 @@ +import SiteLayout from "./components/SiteLayout"; +import layoutStyles from "@/styles/Layout.module.css"; +import styles from "@/styles/World.module.css"; + +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. He owes everyone.", + revealed: true, + }, + { + emoji: "πŸ”₯", + name: "???", + role: "Coming Soon", + desc: "A figure from the oldest part of the war. Their allegiance changes everything.", + revealed: false, + }, + { + emoji: "βš”οΈ", + name: "???", + role: "Coming Soon", + desc: "Every legend needs its foil. Every bone lord needs someone willing to break them.", + revealed: false, + }, + { + emoji: "πŸŒ‘", + name: "???", + role: "Coming Soon", + desc: "They were there at the beginning. They will be there at the end. What happens in between is the story.", + revealed: false, + }, +]; + +export default function Characters() { + return ( + + {/* Hero */} +
+ The Cast +

Characters

+

+ Every soul in this world has a price. Meet the ones who pay it. +

+
+ +
+
+ {CHARACTERS.map((c, i) => ( +
+
+ {c.emoji} + {!c.revealed &&
?
} +
+
+ {c.role} +

{c.name}

+

{c.desc}

+
+
+ ))} +
+ +
+ πŸ‘€ +

Full character profiles reveal with each episode

+
+
+
+ ); +} diff --git a/pages/components/SiteLayout.tsx b/pages/components/SiteLayout.tsx new file mode 100644 index 0000000..538176a --- /dev/null +++ b/pages/components/SiteLayout.tsx @@ -0,0 +1,178 @@ +import Head from "next/head"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { useState } from "react"; +import styles from "@/styles/Layout.module.css"; + +export interface SiteLayoutProps { + title?: string; + description?: string; + keywords?: string; + canonical?: string; + children: React.ReactNode; +} + +const WORLD_LINKS = [ + { href: "/lore", label: "Lore" }, + { href: "/world", label: "World" }, + { href: "/characters", label: "Characters" }, + { href: "/music", label: "Music" }, + { href: "/gallery", label: "Gallery" }, +]; + +export default function SiteLayout({ + title = "Bone Lord Bob β€” American Anime", + description = "Bone Lord Bob is an original American Anime series β€” dark, brutal, beautiful.", + keywords = "Bone Lord Bob, American Anime, indie animation, dark fantasy", + canonical, + children, +}: SiteLayoutProps) { + const router = useRouter(); + const [worldOpen, setWorldOpen] = useState(false); + const [mobileOpen, setMobileOpen] = useState(false); + + const canonicalUrl = canonical + ? `https://www.bonelordbob.com${canonical}` + : `https://www.bonelordbob.com${router.asPath.split("?")[0]}`; + + const isActive = (href: string) => + href === "/" ? router.pathname === "/" : router.pathname.startsWith(href); + + const isWorldActive = WORLD_LINKS.some((l) => router.pathname.startsWith(l.href)); + + return ( + <> + + {title === "Bone Lord Bob β€” American Anime" ? title : `${title} | Bone Lord Bob`} + + + + + + + + + + + + + +
+ {/* ── Nav ── */} + + + {/* Mobile drawer */} + {mobileOpen && ( +
+ setMobileOpen(false)}>Home +
World
+ {WORLD_LINKS.map((l) => ( + setMobileOpen(false)}> + {l.label} + + ))} + setMobileOpen(false)}>Follow +
+ )} + + {/* ── Page content ── */} +
{children}
+ + {/* ── Footer ── */} + +
+ + ); +} diff --git a/pages/gallery.tsx b/pages/gallery.tsx new file mode 100644 index 0000000..92419fc --- /dev/null +++ b/pages/gallery.tsx @@ -0,0 +1,136 @@ +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("official"); + + return ( + + {/* Hero */} +
+ Art of the Bone Kingdom +

Gallery

+

+ Official art from the series β€” and the community that's building around it. +

+
+ +
+ {/* Tab switcher */} +
+ + +
+ + {/* Official art */} + {tab === "official" && ( +
+ {OFFICIAL_ART.length > 0 ? ( +
+ {OFFICIAL_ART.map((item, i) => ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {item.alt} + {item.caption &&

{item.caption}

} +
+ ))} +
+ ) : ( +
+ 🎨 +

Official art gallery coming soon

+

+ Character sheets, key art, and episode stills will live here. +

+
+ )} +
+ )} + + {/* Fan art */} + {tab === "fan" && ( +
+ {FAN_ART.length > 0 ? ( +
+ {FAN_ART.map((item, i) => ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {item.alt} + {item.artist && ( +

+ Art by{" "} + {item.artistUrl ? ( + + {item.artist} + + ) : ( + item.artist + )} +

+ )} +
+ ))} +
+ ) : ( +
+ πŸ’€ +

Fan art gallery β€” coming soon

+

+ Create something. Tag us on social with{" "} + #BoneLordBob and we'll feature + it here. +

+ +
+ )} +
+ )} +
+
+ ); +} diff --git a/pages/index.tsx b/pages/index.tsx index ac9d2a4..0608616 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,7 +1,6 @@ -import Head from "next/head"; import Image from "next/image"; -import Link from "next/link"; import styles from "@/styles/Home.module.css"; +import SiteLayout from "@/pages/components/SiteLayout"; const SOCIALS = [ { @@ -50,64 +49,13 @@ const SOCIALS = [ export default function Home() { return ( - <> - - Bone Lord Bob β€” American Anime - - - - - - - - {/* Open Graph */} - - - - - - - - - {/* Twitter Card */} - - - - - - - +
- {/* ── Nav ─────────────────────────────────────────────────────── */} - - {/* ── Hero ────────────────────────────────────────────────────── */}
@@ -133,21 +81,13 @@ export default function Home() { {/* ── Divider ─────────────────────────────────────────────────── */}
- {["πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€"].map( - (s, i) => ( - - {s} - - ) - )} + {Array.from({ length: 10 }).map((_, i) => ( + πŸ’€ + ))} Coming Soon - {["πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€", "πŸ’€"].map( - (s, i) => ( - - {s} - - ) - )} + {Array.from({ length: 10 }).map((_, i) => ( + πŸ’€ + ))}
{/* ── About ───────────────────────────────────────────────────── */} @@ -263,16 +203,12 @@ export default function Home() { transition: "border-color 0.2s, background 0.2s", }} onMouseEnter={(e) => { - (e.currentTarget as HTMLAnchorElement).style.borderColor = - s.color; - (e.currentTarget as HTMLAnchorElement).style.background = - "#231e18"; + (e.currentTarget as HTMLAnchorElement).style.borderColor = s.color; + (e.currentTarget as HTMLAnchorElement).style.background = "#231e18"; }} onMouseLeave={(e) => { - (e.currentTarget as HTMLAnchorElement).style.borderColor = - "rgba(232,220,200,0.12)"; - (e.currentTarget as HTMLAnchorElement).style.background = - "#1a1510"; + (e.currentTarget as HTMLAnchorElement).style.borderColor = "rgba(232,220,200,0.12)"; + (e.currentTarget as HTMLAnchorElement).style.background = "#1a1510"; }} >
- - {/* ── Footer ──────────────────────────────────────────────────── */} -
- - Bone Lord Bob - -
- - Β© {new Date().getFullYear()} Mathison Projects Inc. All rights - reserved. - - | - - Privacy Policy - - | - - Terms & Conditions - -
-
- +
); } diff --git a/pages/lore.tsx b/pages/lore.tsx new file mode 100644 index 0000000..dba85a0 --- /dev/null +++ b/pages/lore.tsx @@ -0,0 +1,63 @@ +import SiteLayout from "./components/SiteLayout"; +import layoutStyles from "@/styles/Layout.module.css"; +import styles from "@/styles/World.module.css"; + +export default function Lore() { + return ( + + {/* Hero */} +
+ The Deep Canon +

Lore

+

+ Every world has rules. Every myth has teeth. Here begins the canon of Bone Lord Bob. +

+
+ +
+ {/* Placeholder lore entries */} +
+
+ πŸ’€ +

The Bone Covenant

+

+ In the beginning there was only the great silence β€” and then the crack. From that first + fracture, the Bone Kingdom was born. Those who heard it gained dominion over death itself. +

+ More coming soon +
+ +
+ πŸ”₯ +

The Cursed Tongue

+

+ There is a language older than memory. Those who speak it fluently enough can unmake a + living thing β€” or bind the dead to their will. Very few have lived long enough to master it. +

+ More coming soon +
+ +
+ βš”οΈ +

The Three Kingdoms

+

+ The world is divided not by geography, but by allegiance to one of three ancient powers. + The war between them has lasted longer than any living creature can remember. +

+ More coming soon +
+
+ +
+ πŸ“œ +

Full lore archive unlocking as the series releases

+
+
+
+ ); +} diff --git a/pages/music.tsx b/pages/music.tsx new file mode 100644 index 0000000..ee5190a --- /dev/null +++ b/pages/music.tsx @@ -0,0 +1,82 @@ +import SiteLayout from "./components/SiteLayout"; +import layoutStyles from "@/styles/Layout.module.css"; +import styles from "@/styles/World.module.css"; + +// Placeholder β€” tracks will be added when official BLB soundtrack assets are available +const TRACKS: { title: string; vibe: string; file?: string }[] = [ + // { title: "Bone Kingdom Theme", vibe: "Dark orchestral", file: "/music/bone-kingdom-theme.mp3" }, +]; + +export default function Music() { + return ( + + {/* Hero */} +
+ The Soundtrack +

Music

+

+ The Bone Kingdom has a sound. Dark. Relentless. Yours. +

+
+ +
+ {TRACKS.length > 0 ? ( +
+ {TRACKS.map((t, i) => ( +
+ {String(i + 1).padStart(2, "0")} +
+ {t.title} + {t.vibe} +
+ {t.file && ( + + β–Ά + + )} +
+ ))} +
+ ) : null} + + {/* YouTube playlist embed placeholder */} +
+
+ 🎡 +

Official soundtrack coming with Episode 1

+ + Subscribe on YouTube for updates + +
+
+ + {/* Patreon CTA */} +
+

Support the Soundtrack

+

+ Patrons get early access to music, behind-the-scenes production content, and + the full score as it's composed. +

+ + Support on Patreon + +
+
+
+ ); +} diff --git a/pages/privacy.tsx b/pages/privacy.tsx index c77289b..1b8f66d 100644 --- a/pages/privacy.tsx +++ b/pages/privacy.tsx @@ -1,38 +1,7 @@ -import Head from "next/head"; +import SiteLayout from "@/pages/components/SiteLayout"; import Link from "next/link"; const s = { - page: { - minHeight: "100vh", - background: "#0a0806", - color: "#e8dcc8", - fontFamily: "'Segoe UI', system-ui, -apple-system, sans-serif", - lineHeight: 1.7 as const, - } as React.CSSProperties, - nav: { - display: "flex", - alignItems: "center", - justifyContent: "space-between", - padding: "20px 32px", - borderBottom: "1px solid rgba(232,220,200,0.1)", - } as React.CSSProperties, - logo: { - fontFamily: "'Georgia', 'Times New Roman', serif", - fontSize: "1.2rem", - fontWeight: 700, - letterSpacing: "0.04em", - textDecoration: "none", - color: "#e8dcc8", - } as React.CSSProperties, - logoSpan: { color: "#c0392b" } as React.CSSProperties, - backLink: { - fontSize: "0.88rem", - color: "#9e9080", - textDecoration: "none", - display: "inline-flex", - alignItems: "center", - gap: "4px", - } as React.CSSProperties, main: { maxWidth: "780px", margin: "0 auto", @@ -88,318 +57,217 @@ const s = { color: "#c0392b", textDecoration: "underline", } as React.CSSProperties, - footer: { - borderTop: "1px solid rgba(232,220,200,0.1)", - padding: "28px 32px", - textAlign: "center" as const, - fontSize: "0.82rem", - color: "#9e9080", - } as React.CSSProperties, }; -import React from "react"; - export default function Privacy() { return ( - <> - - Privacy Policy β€” Bone Lord Bob - - - - - - - - - - - - - + +
+ Legal +

Privacy Policy

+

Last updated: April 2026

-
- {/* Nav */} - +

+ Bone Lord Bob ("we", "us", "our") is + operated by Mathison Projects Inc. We respect your privacy and are + committed to protecting any personal data we collect. This policy + explains what we collect, how we use it, and your rights. +

- {/* Content */} -
- Legal -

Privacy Policy

-

Last updated: April 2026

- -

- Bone Lord Bob ("we", "us", "our") is - operated by Mathison Projects Inc. We respect your privacy and are - committed to protecting any personal data we collect. This policy - explains what we collect, how we use it, and your rights. -

- -

1. Information We Collect

-

- We collect limited information when you visit{" "} - www.bonelordbob.com: -

-
    -
  • - Usage data β€” pages visited, browser type, - device, IP address, and referral source, collected automatically - via analytics tools. -
  • -
  • - Cookie consent preference β€” stored locally in - your browser's localStorage. -
  • -
  • - Contact information β€” only if you email us - directly at{" "} - - hello@bonelordbob.com - - . -
  • -
- -

2. Cookies & Analytics

-

- We use Google Analytics to understand how visitors - interact with our site. Google Analytics places cookies on your - device to collect anonymized data about your visit (e.g., pages - viewed, session duration, geographic region). -

-

- You can opt out of Google Analytics tracking by installing the{" "} - - Google Analytics Opt-out Browser Add-on - - . -

-

- We also use a localStorage key (blb_cookie_consent) to - remember your cookie consent choice. This is not transmitted to any - server. -

- -

3. Third-Party Services

-

- Our site links to and embeds content from third-party platforms. - Each has its own privacy policy: -

- -

- We are not responsible for the privacy practices of these - third-party platforms. Visiting their links is subject to their - respective policies. -

- -

4. How We Use Your Information

-

- We use the data we collect to: -

-
    -
  • Analyze and improve site performance
  • -
  • Understand audience demographics and interests
  • -
  • - Respond to inquiries you send via email -
  • -
-

- We do not sell, rent, or trade your personal - information to third parties. -

- -

5. Your Rights

- -

- GDPR (European Union): If you are located in the - EU/EEA, you have the right to access, rectify, erase, restrict, or - object to processing of your personal data. You also have the right - to data portability. To exercise these rights, contact us at{" "} +

1. Information We Collect

+

+ We collect limited information when you visit{" "} + www.bonelordbob.com: +

+
    +
  • + Usage data β€” pages visited, browser type, device, + IP address, and referral source, collected automatically via + analytics tools. +
  • +
  • + Cookie consent preference β€” stored locally in + your browser's localStorage. +
  • +
  • + Contact information β€” only if you email us + directly at{" "} hello@bonelordbob.com . -

    +
  • +
-

- CCPA (California, USA): California residents have - the right to know what personal information we collect, to request - deletion of that information, and to opt out of the sale of personal - information. We do not sell personal information. To submit a - request, contact{" "} - - hello@bonelordbob.com +

2. Cookies & Analytics

+

+ We use Google Analytics to understand how visitors + interact with our site. Google Analytics places cookies on your device + to collect anonymized data about your visit (e.g., pages viewed, + session duration, geographic region). +

+

+ You can opt out of Google Analytics tracking by installing the{" "} + + Google Analytics Opt-out Browser Add-on + + . +

+

+ We also use a localStorage key (blb_cookie_consent) to + remember your cookie consent choice. This is not transmitted to any + server. +

+ +

3. Third-Party Services

+

+ Our site links to and embeds content from third-party platforms. Each has + its own privacy policy: +

+
    +
  • + YouTube β€”{" "} + + Google Privacy Policy - . -

    - -

    - CASL (Canada): We do not send commercial electronic - messages unless you have given express or implied consent. If you - wish to withdraw consent or unsubscribe from any communications, - contact us at{" "} - - hello@bonelordbob.com +

  • +
  • + Instagram β€”{" "} + + Meta Privacy Policy - . -

    - -

    6. Data Retention

    -

    - Analytics data is retained by Google Analytics per their default - retention settings (26 months). We do not store personal data on - our own servers beyond what is needed to respond to direct inquiries. -

    - -

    7. Children's Privacy

    -

    - Bone Lord Bob is intended for mature audiences. We do not knowingly - collect personal information from children under 13. If you believe - a child has provided us with personal data, please contact us - immediately. -

    - -

    8. Changes to This Policy

    -

    - We may update this Privacy Policy from time to time. We will post - the updated version on this page with a revised "Last - updated" date. Continued use of the site after changes - constitutes acceptance. -

    - -

    9. Contact

    -

    - For any privacy-related questions, requests, or concerns, contact - us at: -

    -

    - Mathison Projects Inc. -
    - Email:{" "} - - hello@bonelordbob.com +

  • +
  • + X (Twitter) β€”{" "} + + X Privacy Policy -
    - Website:{" "} - - www.bonelordbob.com +
  • +
  • + Facebook β€”{" "} + + Meta Privacy Policy -

    -
+ +
  • + Patreon β€”{" "} + + Patreon Privacy Policy + +
  • +
  • + TikTok β€”{" "} + + TikTok Privacy Policy + +
  • + +

    + We are not responsible for the privacy practices of these third-party + platforms. Visiting their links is subject to their respective + policies. +

    -
    -
    - Β© {new Date().getFullYear()} Mathison Projects Inc. All rights - reserved.  | {" "} - - Home - {" "} -  | {" "} - - Terms & Conditions - -
    -
    -
    - +

    4. How We Use Your Information

    +

    We use the data we collect to:

    +
      +
    • Analyze and improve site performance
    • +
    • Understand audience demographics and interests
    • +
    • Respond to inquiries you send via email
    • +
    +

    + We do not sell, rent, or trade your personal + information to third parties. +

    + +

    5. Your Rights

    +

    + GDPR (European Union): If you are located in the + EU/EEA, you have the right to access, rectify, erase, restrict, or + object to processing of your personal data. You also have the right to + data portability. To exercise these rights, contact us at{" "} + + hello@bonelordbob.com + + . +

    +

    + CCPA (California, USA): California residents have the + right to know what personal information we collect, to request deletion + of that information, and to opt out of the sale of personal + information. We do not sell personal information. To submit a request, + contact{" "} + + hello@bonelordbob.com + + . +

    +

    + CASL (Canada): We do not send commercial electronic + messages unless you have given express or implied consent. If you wish + to withdraw consent, contact us at{" "} + + hello@bonelordbob.com + + . +

    + +

    6. Data Retention

    +

    + Analytics data is retained by Google Analytics per their default + retention settings (26 months). We do not store personal data on our + own servers beyond what is needed to respond to direct inquiries. +

    + +

    7. Children's Privacy

    +

    + Bone Lord Bob is intended for mature audiences. We do not knowingly + collect personal information from children under 13. If you believe a + child has provided us with personal data, please contact us + immediately. +

    + +

    8. Changes to This Policy

    +

    + We may update this Privacy Policy from time to time. We will post the + updated version on this page with a revised "Last updated" + date. Continued use of the site after changes constitutes acceptance. +

    + +

    9. Contact

    +

    + For any privacy-related questions, requests, or concerns, contact us + at: +

    +

    + Mathison Projects Inc. +
    + Email:{" "} + + hello@bonelordbob.com + +
    + Website:{" "} + + www.bonelordbob.com + +

    + +

    + Terms & Conditions + {" "}Β·{" "} + Back to Home +

    +
    +
    ); } diff --git a/pages/terms.tsx b/pages/terms.tsx index 3056c90..7d1b9f6 100644 --- a/pages/terms.tsx +++ b/pages/terms.tsx @@ -1,39 +1,7 @@ -import Head from "next/head"; +import SiteLayout from "@/pages/components/SiteLayout"; import Link from "next/link"; -import React from "react"; const s = { - page: { - minHeight: "100vh", - background: "#0a0806", - color: "#e8dcc8", - fontFamily: "'Segoe UI', system-ui, -apple-system, sans-serif", - lineHeight: 1.7 as const, - } as React.CSSProperties, - nav: { - display: "flex", - alignItems: "center", - justifyContent: "space-between", - padding: "20px 32px", - borderBottom: "1px solid rgba(232,220,200,0.1)", - } as React.CSSProperties, - logo: { - fontFamily: "'Georgia', 'Times New Roman', serif", - fontSize: "1.2rem", - fontWeight: 700, - letterSpacing: "0.04em", - textDecoration: "none", - color: "#e8dcc8", - } as React.CSSProperties, - logoSpan: { color: "#c0392b" } as React.CSSProperties, - backLink: { - fontSize: "0.88rem", - color: "#9e9080", - textDecoration: "none", - display: "inline-flex", - alignItems: "center", - gap: "4px", - } as React.CSSProperties, main: { maxWidth: "780px", margin: "0 auto", @@ -89,243 +57,171 @@ const s = { color: "#c0392b", textDecoration: "underline", } as React.CSSProperties, - footer: { - borderTop: "1px solid rgba(232,220,200,0.1)", - padding: "28px 32px", - textAlign: "center" as const, - fontSize: "0.82rem", - color: "#9e9080", - } as React.CSSProperties, }; export default function Terms() { return ( - <> - - Terms & Conditions β€” Bone Lord Bob - - - - - - - - - - - - - + +
    + Legal +

    Terms & Conditions

    +

    Last updated: April 2026

    -
    - {/* Nav */} - +

    + Please read these Terms & Conditions ("Terms") carefully + before using www.bonelordbob.com (the "Site"), + operated by Mathison Projects Inc. ("we", "us", + "our"). By accessing or using the Site, you agree to be + bound by these Terms. +

    - {/* Content */} -
    - Legal -

    Terms & Conditions

    -

    Last updated: April 2026

    +

    1. Acceptance of Terms

    +

    + By accessing this Site, you confirm that you are at least 13 years of + age (or the minimum legal age in your jurisdiction) and agree to these + Terms. If you do not agree, please do not use the Site. +

    +

    + We reserve the right to update these Terms at any time. Changes will + be effective upon posting to this page with a revised "Last + updated" date. Continued use of the Site after changes + constitutes acceptance of the new Terms. +

    -

    - Please read these Terms & Conditions ("Terms") - carefully before using www.bonelordbob.com (the - "Site"), operated by Mathison Projects Inc. - ("we", "us", "our"). By accessing or - using the Site, you agree to be bound by these Terms. -

    +

    2. Intellectual Property

    +

    + All content on this Site β€” including but not limited to text, artwork, + logos, character designs, animations, names, slogans, and the "Bone + Lord Bob" brand β€” is the exclusive property of{" "} + Mathison Projects Inc. and is protected by United + States and international copyright, trademark, and other intellectual + property laws. +

    +

    + Β© {new Date().getFullYear()} Mathison Projects Inc. All rights + reserved. +

    +

    + You may not reproduce, distribute, modify, create derivative works + from, publicly display, or commercially exploit any content from this + Site without our prior written permission. +

    -

    1. Acceptance of Terms

    -

    - By accessing this Site, you confirm that you are at least 13 years - of age (or the minimum legal age in your jurisdiction) and agree to - these Terms. If you do not agree, please do not use the Site. -

    -

    - We reserve the right to update these Terms at any time. Changes - will be effective upon posting to this page with a revised - "Last updated" date. Continued use of the Site after - changes constitutes acceptance of the new Terms. -

    +

    3. Permitted Use

    +

    + You may access and view the Site for personal, non-commercial purposes. + You may share links to the Site on social media or other platforms, + provided you do not misrepresent the content or the Bone Lord Bob + brand. +

    +

    You may not:

    +
      +
    • + Use the Site for any unlawful purpose or in violation of any + applicable laws or regulations +
    • +
    • + Scrape, data-mine, or systematically extract content from the Site + without permission +
    • +
    • + Attempt to gain unauthorized access to any part of the Site or its + related systems +
    • +
    • + Impersonate Bone Lord Bob, Mathison Projects Inc., or any of their + representatives +
    • +
    • + Use our trademarks or brand assets without written authorization +
    • +
    -

    2. Intellectual Property

    -

    - All content on this Site β€” including but not limited to text, - artwork, logos, character designs, animations, names, slogans, and - the "Bone Lord Bob" brand β€” is the exclusive property of{" "} - Mathison Projects Inc. and is protected by United - States and international copyright, trademark, and other - intellectual property laws. -

    -

    - Β© {new Date().getFullYear()} Mathison Projects Inc. All rights - reserved. -

    -

    - You may not reproduce, distribute, modify, create derivative works - from, publicly display, or commercially exploit any content from - this Site without our prior written permission. -

    +

    4. User Conduct

    +

    + When interacting with us via email or social media, you agree not to + send harassing, abusive, defamatory, obscene, or threatening content. + We reserve the right to block users who violate this policy. +

    -

    3. Permitted Use

    -

    - You may access and view the Site for personal, non-commercial - purposes. You may share links to the Site on social media or other - platforms, provided you do not misrepresent the content or the - Bone Lord Bob brand. -

    -

    - You may not: -

    -
      -
    • - Use the Site for any unlawful purpose or in violation of any - applicable laws or regulations -
    • -
    • - Scrape, data-mine, or systematically extract content from the - Site without permission -
    • -
    • - Attempt to gain unauthorized access to any part of the Site or - its related systems -
    • -
    • - Impersonate Bone Lord Bob, Mathison Projects Inc., or any of - their representatives -
    • -
    • - Use our trademarks or brand assets without written authorization -
    • -
    +

    5. Third-Party Links

    +

    + The Site contains links to third-party platforms (YouTube, Instagram, X, + Facebook, Patreon, TikTok). These links are provided for convenience. + We have no control over the content or practices of these platforms + and are not responsible for their content, privacy policies, or terms + of service. +

    -

    4. User Conduct

    -

    - When interacting with us via email or social media, you agree not - to send harassing, abusive, defamatory, obscene, or threatening - content. We reserve the right to block users who violate this policy. -

    +

    6. Disclaimers

    +

    + THE SITE AND ALL CONTENT ARE PROVIDED "AS IS" AND "AS + AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. +

    +

    + We do not warrant that the Site will be uninterrupted, error-free, or + free of viruses or other harmful components. We may modify, suspend, + or discontinue the Site at any time without notice. +

    -

    5. Third-Party Links

    -

    - The Site contains links to third-party platforms (YouTube, - Instagram, X, Facebook, Patreon, TikTok). These links are provided - for convenience. We have no control over the content or practices - of these platforms and are not responsible for their content, - privacy policies, or terms of service. -

    +

    7. Limitation of Liability

    +

    + TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MATHISON PROJECTS + INC. AND ITS OFFICERS, DIRECTORS, EMPLOYEES, AND AGENTS SHALL NOT BE + LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR + PUNITIVE DAMAGES ARISING FROM YOUR USE OF (OR INABILITY TO USE) THE + SITE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +

    +

    + OUR TOTAL LIABILITY TO YOU FOR ANY CLAIM ARISING FROM THESE TERMS OR + YOUR USE OF THE SITE SHALL NOT EXCEED $100 USD. +

    -

    6. Disclaimers

    -

    - THE SITE AND ALL CONTENT ARE PROVIDED "AS IS" AND - "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR - NON-INFRINGEMENT. -

    -

    - We do not warrant that the Site will be uninterrupted, error-free, - or free of viruses or other harmful components. We may modify, - suspend, or discontinue the Site at any time without notice. -

    +

    8. Governing Law

    +

    + These Terms are governed by and construed in accordance with the laws + of the State of Nebraska, United States of America, + without regard to its conflict of law principles. Any disputes arising + from these Terms or your use of the Site shall be resolved exclusively + in the courts located in Douglas County, Nebraska. +

    -

    7. Limitation of Liability

    -

    - TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MATHISON - PROJECTS INC. AND ITS OFFICERS, DIRECTORS, EMPLOYEES, AND AGENTS - SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - CONSEQUENTIAL, OR PUNITIVE DAMAGES ARISING FROM YOUR USE OF (OR - INABILITY TO USE) THE SITE, EVEN IF WE HAVE BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. -

    -

    - OUR TOTAL LIABILITY TO YOU FOR ANY CLAIM ARISING FROM THESE TERMS - OR YOUR USE OF THE SITE SHALL NOT EXCEED $100 USD. -

    +

    9. Severability

    +

    + If any provision of these Terms is found to be unenforceable or + invalid, that provision will be limited or eliminated to the minimum + extent necessary, and the remaining provisions will continue in full + force and effect. +

    -

    8. Governing Law

    -

    - These Terms are governed by and construed in accordance with the - laws of the State of Nebraska, United States of America, - without regard to its conflict of law principles. Any disputes - arising from these Terms or your use of the Site shall be resolved - exclusively in the courts located in Douglas County, Nebraska. -

    +

    10. Contact

    +

    For questions about these Terms, contact:

    +

    + Mathison Projects Inc. +
    + Email:{" "} + + hello@bonelordbob.com + +
    + Website:{" "} + + www.bonelordbob.com + +

    -

    9. Severability

    -

    - If any provision of these Terms is found to be unenforceable or - invalid, that provision will be limited or eliminated to the - minimum extent necessary, and the remaining provisions will continue - in full force and effect. -

    - -

    10. Contact

    -

    - For questions about these Terms, contact: -

    -

    - Mathison Projects Inc. -
    - Email:{" "} - - hello@bonelordbob.com - -
    - Website:{" "} - - www.bonelordbob.com - -

    -
    - -
    -
    - Β© {new Date().getFullYear()} Mathison Projects Inc. All rights - reserved.  | {" "} - - Home - {" "} -  | {" "} - - Privacy Policy - -
    -
    -
    - +

    + Privacy Policy + {" "}Β·{" "} + Back to Home +

    +
    +
    ); } diff --git a/pages/world.tsx b/pages/world.tsx new file mode 100644 index 0000000..5cb5b6e --- /dev/null +++ b/pages/world.tsx @@ -0,0 +1,79 @@ +import SiteLayout from "./components/SiteLayout"; +import layoutStyles from "@/styles/Layout.module.css"; +import styles from "@/styles/World.module.css"; + +export default function WorldPage() { + return ( + + {/* Hero */} +
    + The Setting +

    + The World +

    +

    + Not a land you'd want to be born into. But one you won't be able to look away from. +

    +
    + +
    +
    +

    + The world of Bone Lord Bob exists somewhere between myth and memory β€” a place where + the rules of death are more like suggestions, and the landscape itself remembers every + war ever fought on it. +

    +

    + There are no safe cities. Only cities that haven't fallen yet. +

    +
    + + {/* Location cards */} +
    +
    +
    + 🦴 +

    The Bonefield

    +
    +

    + A vast plain where the remains of an ancient battle stretch beyond the horizon. + Travelers say you can still hear the war if you press your ear to the ground at midnight. +

    +
    + +
    +
    + 🏰 +

    The Throne of Ash

    +
    +

    + No one sits there now. No one has for a hundred years. But something still answers + when the right name is spoken in its hall. +

    +
    + +
    +
    + πŸŒ‘ +

    The Hollow Dark

    +
    +

    + Below every kingdom is the Hollow Dark β€” the underworld that isn't quite the afterlife. + Bob knows this place better than anyone alive. +

    +
    +
    + +
    + πŸ—ΊοΈ +

    World map and full region guide β€” coming with Episode 1

    +
    +
    +
    + ); +} diff --git a/pages/world/lore.tsx b/pages/world/lore.tsx new file mode 100644 index 0000000..58e521e --- /dev/null +++ b/pages/world/lore.tsx @@ -0,0 +1,182 @@ +import SiteLayout from "@/pages/components/SiteLayout"; + +const s = { + page: { + maxWidth: "860px", + margin: "0 auto", + padding: "64px 32px 96px", + } as React.CSSProperties, + hero: { + marginBottom: "64px", + 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: "560px", + margin: "0 auto", + lineHeight: 1.7, + } as React.CSSProperties, + divider: { + display: "flex", + alignItems: "center", + justifyContent: "center", + gap: "12px", + margin: "48px 0", + fontSize: "1.2rem", + opacity: 0.4, + } as React.CSSProperties, + section: { + marginBottom: "56px", + } as React.CSSProperties, + sectionLabel: { + display: "block", + fontSize: "0.72rem", + fontWeight: 700, + letterSpacing: "0.14em", + textTransform: "uppercase" as const, + color: "#c0392b", + marginBottom: "12px", + } as React.CSSProperties, + h2: { + fontFamily: "'Georgia', 'Times New Roman', serif", + fontSize: "clamp(1.6rem, 3vw, 2.2rem)", + fontWeight: 700, + color: "#e8dcc8", + marginBottom: "20px", + lineHeight: 1.2, + } as React.CSSProperties, + p: { + fontSize: "1rem", + color: "#c8bfae", + lineHeight: 1.8, + marginBottom: "16px", + maxWidth: "680px", + } as React.CSSProperties, + comingSoon: { + background: "#1a1510", + border: "1px solid rgba(232,220,200,0.1)", + borderRadius: "8px", + padding: "40px 32px", + textAlign: "center" as const, + marginTop: "16px", + } as React.CSSProperties, + comingSoonIcon: { + fontSize: "2rem", + marginBottom: "12px", + display: "block", + opacity: 0.4, + } as React.CSSProperties, + comingSoonText: { + fontSize: "0.88rem", + color: "#9e9080", + letterSpacing: "0.08em", + textTransform: "uppercase" as const, + fontWeight: 600, + } as React.CSSProperties, +}; + +export default function Lore() { + return ( + +
    + {/* Hero */} +
    + The Mythology +

    The Lore

    +

    + Death is not the end in this world. It is the beginning of debt. +

    +
    + + {/* Section: Bone Kingdom */} +
    + Foundation +

    The Bone Kingdom

    +

    + A land where death is currency and the living are guests. The Bone + Kingdom does not welcome the breathing β€” it merely tolerates them, + for now, until their ledger comes due. Every step taken on its soil + is a transaction. Every breath drawn is borrowed. +

    +

    + Its borders are not marked by walls or rivers, but by a feeling: the + moment the air turns cold and the light goes gray, you have arrived. + The dead know. The living learn too late. +

    +
    + +
    + πŸ’€πŸ’€πŸ’€ +
    + + {/* Section: The Ledger */} +
    + The Accounting +

    The Ledger

    +

    + Every soul has a price. The Bone Lord keeps the account. From the + moment of first breath, your name is inscribed β€” not in ink, but in + marrow. The record does not forget. It does not forgive. It only + waits. +

    +

    + Heroes have tried to destroy the Ledger. Warlords have tried to + steal it. Gods have tried to rewrite it. None have succeeded. The + book endures because it is not made of paper. It is made of + consequence. +

    +
    + +
    + πŸ’€πŸ’€πŸ’€ +
    + + {/* Section: Origins β€” coming soon */} +
    + History +

    Origins

    +
    + πŸ’€ +

    Coming Soon

    +
    +
    + +
    + πŸ’€πŸ’€πŸ’€ +
    + + {/* Section: Prophecy β€” coming soon */} +
    + The Foretelling +

    Prophecy

    +
    + πŸ’€ +

    Coming Soon

    +
    +
    +
    +
    + ); +} diff --git a/pages/world/world.tsx b/pages/world/world.tsx new file mode 100644 index 0000000..a0b58dd --- /dev/null +++ b/pages/world/world.tsx @@ -0,0 +1,146 @@ +import SiteLayout from "@/pages/components/SiteLayout"; + +const s = { + page: { + maxWidth: "1000px", + margin: "0 auto", + padding: "64px 32px 96px", + } as React.CSSProperties, + hero: { + marginBottom: "64px", + 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, + sectionLabel: { + display: "block", + fontSize: "0.72rem", + fontWeight: 700, + letterSpacing: "0.14em", + textTransform: "uppercase" as const, + color: "#c0392b", + marginBottom: "12px", + textAlign: "center" as const, + } as React.CSSProperties, + grid: { + display: "grid", + gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))", + gap: "20px", + marginTop: "32px", + marginBottom: "48px", + } as React.CSSProperties, + card: { + background: "#1a1510", + border: "1px solid rgba(232,220,200,0.12)", + borderRadius: "8px", + padding: "32px 28px", + transition: "border-color 0.2s", + } as React.CSSProperties, + cardIcon: { + fontSize: "2rem", + marginBottom: "16px", + display: "block", + } as React.CSSProperties, + cardName: { + fontFamily: "'Georgia', 'Times New Roman', serif", + fontSize: "1.25rem", + fontWeight: 700, + color: "#e8dcc8", + marginBottom: "12px", + } as React.CSSProperties, + cardDesc: { + fontSize: "0.92rem", + color: "#9e9080", + lineHeight: 1.65, + } as React.CSSProperties, + more: { + textAlign: "center" as const, + padding: "32px", + background: "#120f0a", + border: "1px solid rgba(232,220,200,0.08)", + borderRadius: "8px", + fontSize: "0.9rem", + color: "#9e9080", + fontStyle: "italic", + letterSpacing: "0.04em", + } as React.CSSProperties, +}; + +const REGIONS = [ + { + icon: "🏴", + name: "The Bone Kingdom", + desc: "Where the dead outnumber the living. The seat of the Bone Lord's power β€” a realm that does not distinguish between conqueror and conquered. All serve, eventually.", + }, + { + icon: "πŸŒ‘", + name: "The Bonefield", + desc: "An endless plain of ash and silence. Nothing grows. Nothing dies. Those who wander into the Bonefield are neither living nor dead β€” just lost.", + }, + { + icon: "πŸ”₯", + name: "The Pyre Gates", + desc: "The boundary between worlds. Cross it once. You won't cross back. The Gates do not open for the living β€” but they have been known to open for the desperate.", + }, +]; + +export default function WorldPage() { + return ( + +
    + {/* Hero */} +
    + Geography & Factions +

    The World

    +

    + Every territory has a cost. Every border is written in bone. Know + where you are before it's too late. +

    +
    + + {/* Region cards */} + Regions +
    + {REGIONS.map((r) => ( +
    + {r.icon} +
    {r.name}
    +

    {r.desc}

    +
    + ))} +
    + + {/* Placeholder */} +
    + More regions revealed as the story unfolds... +
    +
    +
    + ); +} diff --git a/styles/Gallery.module.css b/styles/Gallery.module.css new file mode 100644 index 0000000..a783851 --- /dev/null +++ b/styles/Gallery.module.css @@ -0,0 +1,138 @@ +/* ── Tabs ──────────────────────────────────────────────────────────────────── */ +.tabs { + display: flex; + gap: 0; + border-bottom: 1px solid var(--border); + margin-bottom: 3rem; +} + +.tab { + padding: 0.75rem 2rem; + background: none; + border: none; + border-bottom: 2px solid transparent; + font-size: 0.78rem; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--bone-dim); + cursor: pointer; + transition: color 0.2s, border-color 0.2s; + font-family: inherit; + margin-bottom: -1px; +} + +.tab:hover { color: var(--bone); } + +.tabActive { + color: var(--bone); + border-bottom-color: var(--red); +} + +/* ── Section ───────────────────────────────────────────────────────────────── */ +.section {} + +/* ── Grid ──────────────────────────────────────────────────────────────────── */ +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 1.5rem; + margin-bottom: 3rem; +} + +.card { + background: var(--dark-card); + border: 1px solid var(--border); + overflow: hidden; + transition: border-color 0.2s, transform 0.2s; +} + +.card:hover { + border-color: rgba(232,220,200,0.25); + transform: translateY(-2px); +} + +.cardImg { + width: 100%; + aspect-ratio: 4/3; + object-fit: cover; + display: block; +} + +.cardCaption { + padding: 0.65rem 1rem; + font-size: 0.78rem; + color: var(--bone-dim); + opacity: 0.7; + border-top: 1px solid var(--border); +} + +.cardCaption a { + color: var(--red); + text-decoration: underline; +} + +/* ── Empty state ───────────────────────────────────────────────────────────── */ +.empty { + text-align: center; + padding: 6rem 2rem; + border: 1px dashed var(--border); + background: var(--dark-card); +} + +.emptyIcon { + display: block; + font-size: 3.5rem; + margin-bottom: 1.25rem; + opacity: 0.25; +} + +.emptyTitle { + font-family: var(--font-display); + font-size: 1.1rem; + color: var(--bone); + margin-bottom: 0.65rem; +} + +.emptyText { + font-size: 0.88rem; + color: var(--bone-dim); + max-width: 440px; + margin: 0 auto 2rem; + line-height: 1.75; +} + +.emptyLinks { + display: flex; + gap: 0.75rem; + justify-content: center; + flex-wrap: wrap; +} + +.emptyBtn { + display: inline-flex; + padding: 0.6rem 1.4rem; + background: transparent; + color: var(--bone-dim); + border: 1px solid var(--border); + font-size: 0.75rem; + letter-spacing: 0.1em; + text-transform: uppercase; + transition: border-color 0.2s, color 0.2s; +} + +.emptyBtn:hover { + border-color: var(--red); + color: var(--bone); +} + +/* ── Responsive ────────────────────────────────────────────────────────────── */ +@media (max-width: 768px) { + .tabs { overflow-x: auto; } + .tab { padding: 0.65rem 1.25rem; white-space: nowrap; } + .grid { grid-template-columns: 1fr 1fr; } + .empty { padding: 3rem 1.25rem; } +} + +@media (max-width: 480px) { + .grid { grid-template-columns: 1fr; } +} diff --git a/styles/Layout.module.css b/styles/Layout.module.css new file mode 100644 index 0000000..d85e57b --- /dev/null +++ b/styles/Layout.module.css @@ -0,0 +1,295 @@ +/* ───────────────────────────────────────────────────────────────── + Layout.module.css β€” Bone Lord Bob shared site layout + ───────────────────────────────────────────────────────────────── */ + +/* Site wrapper */ +.site { + min-height: 100vh; + background: var(--dark, #0a0806); + color: var(--bone, #e8dcc8); + font-family: var(--font-body, 'Segoe UI', system-ui, -apple-system, sans-serif); + display: flex; + flex-direction: column; +} + +/* ── NAV ───────────────────────────────────────────────────────── */ +.nav { + position: sticky; + top: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 40px; + height: 64px; + background: rgba(10, 8, 6, 0.95); + border-bottom: 1px solid var(--border, rgba(232, 220, 200, 0.12)); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); +} + +.navLogo { + font-family: var(--font-display, Georgia, 'Times New Roman', serif); + font-size: 1.15rem; + font-weight: 700; + letter-spacing: 0.06em; + color: var(--bone, #e8dcc8); + text-decoration: none; + transition: opacity 0.2s; +} +.navLogo:hover { opacity: 0.85; } +.navLogo span { color: var(--red, #c0392b); } + +/* Desktop nav list */ +.navLinks { + display: flex; + align-items: center; + gap: 4px; + list-style: none; + margin: 0; + padding: 0; +} + +.navItem { + position: relative; +} + +.navLink { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 8px 14px; + font-size: 0.88rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--bone-dim, #9e9080); + text-decoration: none; + background: none; + border: none; + cursor: pointer; + border-radius: 4px; + transition: color 0.2s, background 0.2s; + font-family: inherit; +} +.navLink:hover { color: var(--bone, #e8dcc8); background: rgba(232,220,200,0.06); } + +.navLinkActive { + color: var(--red, #c0392b) !important; +} + +.navDropdownTrigger { + /* same as navLink, handled above */ +} + +.chevron { + font-size: 0.7rem; + opacity: 0.7; + transition: transform 0.2s; +} + +/* ── DROPDOWN ──────────────────────────────────────────────────── */ +.dropdown { + position: absolute; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + min-width: 160px; + background: var(--dark-card, #1a1510); + border: 1px solid var(--border, rgba(232,220,200,0.12)); + border-radius: 6px; + padding: 6px 0; + box-shadow: 0 8px 32px rgba(0,0,0,0.6); + animation: dropdownIn 0.15s ease; + z-index: 200; +} + +@keyframes dropdownIn { + from { opacity: 0; transform: translateX(-50%) translateY(-6px); } + to { opacity: 1; transform: translateX(-50%) translateY(0); } +} + +.dropdownItem { + display: block; + padding: 9px 18px; + font-size: 0.87rem; + font-weight: 500; + color: var(--bone-dim, #9e9080); + text-decoration: none; + transition: color 0.15s, background 0.15s; + white-space: nowrap; +} +.dropdownItem:hover { color: var(--bone, #e8dcc8); background: rgba(232,220,200,0.06); } + +.dropdownItemActive { color: var(--red, #c0392b) !important; } + +/* ── HAMBURGER ─────────────────────────────────────────────────── */ +.hamburger { + display: none; + flex-direction: column; + justify-content: center; + gap: 5px; + width: 36px; + height: 36px; + background: none; + border: none; + cursor: pointer; + padding: 4px; + border-radius: 4px; + transition: background 0.2s; +} +.hamburger:hover { background: rgba(232,220,200,0.08); } +.hamburger span { + display: block; + width: 22px; + height: 2px; + background: var(--bone, #e8dcc8); + border-radius: 2px; + transition: opacity 0.2s; +} + +/* ── MOBILE DRAWER ─────────────────────────────────────────────── */ +.mobileDrawer { + display: none; + flex-direction: column; + background: var(--dark-mid, #120f0a); + border-bottom: 1px solid var(--border, rgba(232,220,200,0.12)); + padding: 12px 0 20px; + z-index: 99; +} + +.mobileLink { + display: block; + padding: 12px 28px; + font-size: 0.9rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--bone, #e8dcc8); + text-decoration: none; + transition: color 0.2s, background 0.2s; +} +.mobileLink:hover { color: var(--red, #c0392b); background: rgba(232,220,200,0.04); } + +.mobileSectionLabel { + padding: 12px 28px 6px; + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--red, #c0392b); +} + +.mobileLinkIndent { + display: block; + padding: 9px 28px 9px 42px; + font-size: 0.87rem; + color: var(--bone-dim, #9e9080); + text-decoration: none; + transition: color 0.2s; +} +.mobileLinkIndent:hover { color: var(--bone, #e8dcc8); } + +/* ── MAIN ──────────────────────────────────────────────────────── */ +.main { + flex: 1; +} + +/* ── FOOTER ────────────────────────────────────────────────────── */ +.footer { + background: var(--dark-mid, #120f0a); + border-top: 1px solid var(--border, rgba(232,220,200,0.12)); +} + +.footerTop { + display: flex; + gap: 48px; + max-width: 1100px; + margin: 0 auto; + padding: 56px 40px 48px; + flex-wrap: wrap; +} + +.footerBrand { + flex: 1; + min-width: 200px; + max-width: 280px; +} + +.footerLogo { + font-family: var(--font-display, Georgia, serif); + font-size: 1.2rem; + font-weight: 700; + letter-spacing: 0.06em; + color: var(--bone, #e8dcc8); +} +.footerLogo span { color: var(--red, #c0392b); } + +.footerTagline { + margin-top: 10px; + font-size: 0.85rem; + color: var(--bone-dim, #9e9080); + line-height: 1.5; +} + +.footerColumns { + display: flex; + gap: 48px; + flex-wrap: wrap; +} + +.footerCol { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 120px; +} + +.footerColTitle { + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--red, #c0392b); + margin-bottom: 4px; +} + +.footerLink { + font-size: 0.875rem; + color: var(--bone-dim, #9e9080); + text-decoration: none; + transition: color 0.2s; +} +.footerLink:hover { color: var(--bone, #e8dcc8); } + +.footerBottom { + border-top: 1px solid var(--border, rgba(232,220,200,0.08)); + padding: 20px 40px; + text-align: center; + font-size: 0.8rem; + color: rgba(158, 144, 128, 0.6); + max-width: 100%; +} + +/* ── MOBILE RESPONSIVE ─────────────────────────────────────────── */ +@media (max-width: 768px) { + .nav { padding: 0 20px; } + + .navLinks { display: none; } + + .hamburger { display: flex; } + + .mobileDrawer { display: flex; } + + .footerTop { + flex-direction: column; + gap: 32px; + padding: 40px 20px 32px; + } + + .footerBrand { max-width: 100%; } + + .footerColumns { gap: 28px; } + + .footerBottom { padding: 16px 20px; } +} diff --git a/styles/World.module.css b/styles/World.module.css new file mode 100644 index 0000000..da0ad89 --- /dev/null +++ b/styles/World.module.css @@ -0,0 +1,328 @@ +/* ── Lore page ─────────────────────────────────────────────────────────────── */ +.loreGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 1.5rem; + margin-bottom: 4rem; +} + +.loreCard { + background: var(--dark-card); + border: 1px solid var(--border); + padding: 2rem 1.75rem; + position: relative; + overflow: hidden; + transition: border-color 0.2s; +} + +.loreCard:hover { border-color: rgba(232,220,200,0.25); } + +.loreCard::before { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 2px; + background: var(--red); + transform: scaleX(0); + transform-origin: left; + transition: transform 0.3s; +} + +.loreCard:hover::before { transform: scaleX(1); } + +.loreIcon { + display: block; + font-size: 2rem; + margin-bottom: 1rem; +} + +.loreTitle { + font-family: var(--font-display); + font-size: 1.1rem; + color: var(--bone); + margin-bottom: 0.75rem; +} + +.loreText { + font-size: 0.88rem; + color: var(--bone-dim); + line-height: 1.75; + margin-bottom: 1rem; +} + +.loreLocked { + font-size: 0.68rem; + letter-spacing: 0.15em; + text-transform: uppercase; + color: var(--red); + opacity: 0.7; +} + +/* ── World page ────────────────────────────────────────────────────────────── */ +.worldIntro { + max-width: 640px; + margin: 0 auto 4rem; + text-align: center; +} + +.worldText { + font-size: 1rem; + color: var(--bone-dim); + line-height: 1.8; + margin-bottom: 1rem; +} + +.locationGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1.5rem; + margin-bottom: 4rem; +} + +.locationCard { + background: var(--dark-card); + border: 1px solid var(--border); + padding: 2rem 1.75rem; + transition: border-color 0.2s, transform 0.2s; +} + +.locationCard:hover { + border-color: rgba(232,220,200,0.25); + transform: translateY(-2px); +} + +.locationHeader { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 0.85rem; +} + +.locationIcon { font-size: 1.5rem; } + +.locationName { + font-family: var(--font-display); + font-size: 1.1rem; + color: var(--bone); +} + +.locationDesc { + font-size: 0.88rem; + color: var(--bone-dim); + line-height: 1.75; +} + +/* ── Characters page ───────────────────────────────────────────────────────── */ +.characterGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 1.5rem; + margin-bottom: 4rem; +} + +.characterCard { + background: var(--dark-card); + border: 1px solid var(--border); + overflow: hidden; + transition: border-color 0.2s, transform 0.2s; +} + +.characterCard:hover { + border-color: rgba(232,220,200,0.25); + transform: translateY(-3px); +} + +.characterCardLocked { opacity: 0.6; } + +.characterArt { + position: relative; + aspect-ratio: 1; + background: var(--dark); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: center; +} + +.characterEmoji { + font-size: 5rem; + opacity: 0.15; +} + +.characterLockedOverlay { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + font-family: var(--font-display); + font-size: 6rem; + color: var(--bone-dim); + opacity: 0.08; +} + +.characterInfo { + padding: 1.5rem; +} + +.characterRole { + display: block; + font-size: 0.68rem; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--red); + margin-bottom: 0.4rem; +} + +.characterName { + font-family: var(--font-display); + font-size: 1.15rem; + color: var(--bone); + margin-bottom: 0.65rem; +} + +.characterDesc { + font-size: 0.85rem; + color: var(--bone-dim); + line-height: 1.7; +} + +/* ── Music page ────────────────────────────────────────────────────────────── */ +.tracklist { + margin-bottom: 3rem; + border: 1px solid var(--border); +} + +.track { + display: flex; + align-items: center; + gap: 1rem; + padding: 1rem 1.25rem; + border-bottom: 1px solid var(--border); + transition: background 0.15s; +} + +.track:last-child { border-bottom: none; } +.track:hover { background: rgba(232,220,200,0.04); } + +.trackNum { + font-size: 0.75rem; + color: var(--bone-dim); + opacity: 0.5; + min-width: 2rem; + font-variant-numeric: tabular-nums; +} + +.trackInfo { + flex: 1; + display: flex; + flex-direction: column; + gap: 0.2rem; +} + +.trackTitle { + font-size: 0.9rem; + color: var(--bone); +} + +.trackVibe { + font-size: 0.75rem; + color: var(--bone-dim); + opacity: 0.6; +} + +.trackPlay { + font-size: 0.8rem; + color: var(--red); + opacity: 0.7; + transition: opacity 0.2s; + cursor: pointer; +} + +.trackPlay:hover { opacity: 1; } + +.musicEmbed { + margin-bottom: 3rem; +} + +.musicEmbedPlaceholder { + border: 1px dashed var(--border); + padding: 4rem 2rem; + text-align: center; + background: var(--dark-card); +} + +.musicEmbedIcon { + display: block; + font-size: 3rem; + margin-bottom: 1rem; + opacity: 0.3; +} + +.musicEmbedText { + font-size: 0.85rem; + color: var(--bone-dim); + opacity: 0.6; + margin-bottom: 1.5rem; +} + +.musicEmbedBtn { + display: inline-flex; + padding: 0.65rem 1.5rem; + background: var(--red); + color: var(--bone); + font-size: 0.78rem; + letter-spacing: 0.1em; + text-transform: uppercase; + font-weight: 600; + transition: background 0.2s; +} + +.musicEmbedBtn:hover { background: #a93226; } + +.musicPatreon { + text-align: center; + padding: 3rem 2rem; + border: 1px solid var(--border); + background: var(--dark-card); +} + +.musicPatreonTitle { + font-family: var(--font-display); + font-size: 1.4rem; + color: var(--bone); + margin-bottom: 0.75rem; +} + +.musicPatreonText { + font-size: 0.88rem; + color: var(--bone-dim); + line-height: 1.7; + max-width: 480px; + margin: 0 auto 1.5rem; +} + +.musicPatreonBtn { + display: inline-flex; + padding: 0.7rem 1.75rem; + background: transparent; + color: var(--bone); + border: 1px solid var(--border); + font-size: 0.78rem; + letter-spacing: 0.1em; + text-transform: uppercase; + transition: border-color 0.2s, color 0.2s; +} + +.musicPatreonBtn:hover { + border-color: var(--bone-dim); + color: var(--bone); +} + +/* ── Responsive ────────────────────────────────────────────────────────────── */ +@media (max-width: 768px) { + .loreGrid, + .locationGrid, + .characterGrid { grid-template-columns: 1fr; } + .musicEmbedPlaceholder { padding: 2.5rem 1.25rem; } +}